• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

domdfcoding / pre-commit-hooks / 23292013847

19 Mar 2026 11:08AM UTC coverage: 97.521% (+0.02%) from 97.5%
23292013847

push

github

domdfcoding
Bump mypy

118 of 121 relevant lines covered (97.52%)

0.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.44
/pre_commit_hooks/bind_requirements.py
1
#!/usr/bin/env python3
2
#
3
#  bind_requirements.py
4
"""
5
Bind requirements in ``requirements.txt`` files to the latest version on PyPI.
6
"""
7
#
8
#  Copyright © 2020-2021 Dominic Davis-Foster <dominic@davis-foster.co.uk>
9
#  Based on https://github.com/pre-commit/pre-commit-hooks
10
#
11
#  Permission is hereby granted, free of charge, to any person obtaining a copy
12
#  of this software and associated documentation files (the "Software"), to deal
13
#  in the Software without restriction, including without limitation the rights
14
#  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
#  copies of the Software, and to permit persons to whom the Software is
16
#  furnished to do so, subject to the following conditions:
17
#
18
#  The above copyright notice and this permission notice shall be included in all
19
#  copies or substantial portions of the Software.
20
#
21
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24
#  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
25
#  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
26
#  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
27
#  OR OTHER DEALINGS IN THE SOFTWARE.
28
#
29

30
# stdlib
31
import sys
1✔
32
from typing import Iterable, Optional
1✔
33

34
# 3rd party
35
import click
1✔
36
import requests
1✔
37
from consolekit import click_command
1✔
38
from consolekit.options import auto_default_option
1✔
39
from domdf_python_tools.paths import PathPlus
1✔
40
from domdf_python_tools.typing import PathLike
1✔
41
from packaging.requirements import InvalidRequirement
1✔
42
from shippinglabel import normalize_keep_dot
1✔
43
from shippinglabel_pypi import bind_requirements
1✔
44
from urllib3.exceptions import MaxRetryError, NewConnectionError
1✔
45

46
# this package
47
from pre_commit_hooks.util import PASS
1✔
48

49
__all__ = ("main", )
1✔
50

51

52
@auto_default_option(
1✔
53
                "--specifier",
54
                type=click.STRING,
55
                help="The version specifier symbol to use. (default: %(default)s)",
56
                )
57
@auto_default_option(
1✔
58
                "--python-min",
59
                type=click.STRING,
60
                help="The minimum Python version the requirement must support.",
61
                )
62
@click.argument("filenames", nargs=-1, type=click.STRING)
1✔
63
@click_command()
1✔
64
def main(
1✔
65
                filenames: Iterable[PathLike],
66
                specifier: str = ">=",
67
                python_min: Optional[str] = None,
68
                ) -> None:
69
        """
70
        Bind unbound requirements to the latest version on PyPI, and any later versions.
71
        """
72

73
        retv = PASS
1✔
74

75
        for filename in filenames:
1✔
76
                filename = PathPlus(filename)
1✔
77
                try:
1✔
78
                        ret_for_file = bind_requirements(
1✔
79
                                        filename,
80
                                        specifier,
81
                                        normalize_func=normalize_keep_dot,
82
                                        minimum_py_version=python_min,
83
                                        )
84

85
                        if ret_for_file:
1✔
86
                                print(f"Binding requirements for {filename.as_posix()}")
1✔
87

88
                except (NewConnectionError, MaxRetryError, requests.exceptions.ConnectionError) as e:
1✔
89
                        print(f"Error binding requirements for {filename.as_posix()}: {str(e)}")
×
90
                        ret_for_file = 1
×
91
                except InvalidRequirement as e:
1✔
92
                        print(f"Invalid Requirement: {str(e)}")
1✔
93
                        ret_for_file = 1
1✔
94

95
                retv |= ret_for_file
1✔
96

97
        if not retv:
1✔
98
                print("Up to date.")
1✔
99

100
        sys.exit(retv)
1✔
101

102

103
if __name__ == "__main__":
104
        sys.exit(main())
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc