From 0dbd3938af339858436fd2b44736a2d315f4665b Mon Sep 17 00:00:00 2001 From: Devesh Kumar Singh Date: Sat, 6 Jun 2020 02:18:50 +0530 Subject: [PATCH 1/7] Add B014 ignore --- setup.cfg | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 8c94472ab6d..b8ee43f5a46 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,8 +26,13 @@ exclude = per-file-ignores = # B011: Do not call assert False since python -O removes these calls tests/*: B011 - # TODO: Remove this when fixing flake8-bugbear warnings in source - src/pip/*: B007,B008,B009,B014,B305 + # TODO: Remove IOError from except (OSError, IOError) blocks in + # these files when Python 2 is removed. + # In Python 3, IOError have been merged into OSError + # https://github.com/PyCQA/flake8-bugbear/issues/110 + src/pip/_internal/utils/filesystem.py: B014 + src/pip/_internal/network/cache.py: B014 + src/pip/_internal/utils/misc.py: B014 [mypy] follow_imports = silent ignore_missing_imports = True From 76a130105cea16d16a80a5ec50006a8fc90cc3bd Mon Sep 17 00:00:00 2001 From: Devesh Kumar Singh Date: Sat, 6 Jun 2020 02:21:03 +0530 Subject: [PATCH 2/7] Fix src/pip with flake8-bugbear --- src/pip/_internal/cli/progress_bars.py | 4 +++- src/pip/_internal/commands/debug.py | 4 ++-- src/pip/_internal/utils/filesystem.py | 4 ++-- src/pip/_internal/utils/misc.py | 7 +++++-- src/pip/_internal/vcs/subversion.py | 2 +- src/pip/_internal/wheel_builder.py | 10 +++++----- 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/pip/_internal/cli/progress_bars.py b/src/pip/_internal/cli/progress_bars.py index 9a4ae592e7c..69338552f13 100644 --- a/src/pip/_internal/cli/progress_bars.py +++ b/src/pip/_internal/cli/progress_bars.py @@ -167,7 +167,9 @@ def pretty_eta(self): def iter(self, it): # type: ignore for x in it: yield x - self.next(len(x)) + # B305 is incorrectly raised here + # https://github.com/PyCQA/flake8-bugbear/issues/59 + self.next(len(x)) # noqa: B305 self.finish() diff --git a/src/pip/_internal/commands/debug.py b/src/pip/_internal/commands/debug.py index d8e2484c1b4..ffe341dde7f 100644 --- a/src/pip/_internal/commands/debug.py +++ b/src/pip/_internal/commands/debug.py @@ -87,7 +87,7 @@ def get_vendor_version_from_module(module_name): if not version: # Try to find version in debundled module info pkg_set = pkg_resources.WorkingSet( - [os.path.dirname(getattr(module, '__file__'))] + [os.path.dirname(getattr(module, '__file__', None))] ) package = pkg_set.find(pkg_resources.Requirement.parse(module_name)) version = getattr(package, 'version', None) @@ -166,7 +166,7 @@ def show_tags(options): def ca_bundle_info(config): # type: (Dict[str, str]) -> str levels = set() - for key, value in config.items(): + for key in config: levels.add(key.split('.')[0]) if not levels: diff --git a/src/pip/_internal/utils/filesystem.py b/src/pip/_internal/utils/filesystem.py index c706a038c2a..303243fd22f 100644 --- a/src/pip/_internal/utils/filesystem.py +++ b/src/pip/_internal/utils/filesystem.py @@ -155,7 +155,7 @@ def _test_writable_dir_win(path): # and we can't use tempfile: http://bugs.python.org/issue22107 basename = 'accesstest_deleteme_fishfingers_custard_' alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789' - for i in range(10): + for _ in range(10): name = basename + ''.join(random.choice(alphabet) for _ in range(6)) file = os.path.join(path, name) try: @@ -190,7 +190,7 @@ def find_files(path, pattern): """Returns a list of absolute paths of files beneath path, recursively, with filenames which match the UNIX-style shell glob pattern.""" result = [] # type: List[str] - for root, dirs, files in os.walk(path): + for root, _, files in os.walk(path): matches = fnmatch.filter(files, pattern) result.extend(os.path.join(root, f) for f in matches) return result diff --git a/src/pip/_internal/utils/misc.py b/src/pip/_internal/utils/misc.py index c7bb972ffb7..467ae5452e1 100644 --- a/src/pip/_internal/utils/misc.py +++ b/src/pip/_internal/utils/misc.py @@ -17,7 +17,7 @@ import sys from collections import deque -from pip._vendor import pkg_resources +from pip._vendor import pkg_resources, six # NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is # why we ignore the type on this import. from pip._vendor.retrying import retry # type: ignore @@ -548,7 +548,10 @@ def readline(self): try: return next(self._gen) except NameError: - return self._gen.next() + # flake8-bugbear B305 suggests using six.next for + # Python 2 compatibility. This along with the try/except + # block can be removed once we drop Python 2 support + return six.next(self._gen) except StopIteration: return '' diff --git a/src/pip/_internal/vcs/subversion.py b/src/pip/_internal/vcs/subversion.py index 4324a5d9f82..14825f791a4 100644 --- a/src/pip/_internal/vcs/subversion.py +++ b/src/pip/_internal/vcs/subversion.py @@ -56,7 +56,7 @@ def get_revision(cls, location): # Note: taken from setuptools.command.egg_info revision = 0 - for base, dirs, files in os.walk(location): + for base, dirs, _ in os.walk(location): if cls.dirname not in dirs: dirs[:] = [] continue # no sense walking uncontrolled subdirs diff --git a/src/pip/_internal/wheel_builder.py b/src/pip/_internal/wheel_builder.py index b5e8bf33924..8b6ddad4739 100644 --- a/src/pip/_internal/wheel_builder.py +++ b/src/pip/_internal/wheel_builder.py @@ -23,7 +23,7 @@ if MYPY_CHECK_RUNNING: from typing import ( - Any, Callable, Iterable, List, Optional, Pattern, Tuple, + Any, Callable, Iterable, List, Optional, Tuple, ) from pip._internal.cache import WheelCache @@ -34,11 +34,11 @@ logger = logging.getLogger(__name__) +_egg_info_re = re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', re.IGNORECASE) -def _contains_egg_info( - s, _egg_info_re=re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', - re.IGNORECASE)): - # type: (str, Pattern[str]) -> bool + +def _contains_egg_info(s): + # type: (str) -> bool """Determine whether the string looks like an egg_info. :param s: The string to parse. E.g. foo-2.1 From 931558277460f951cce52f9ec5b34c64e4b283bf Mon Sep 17 00:00:00 2001 From: Devesh Kumar Singh Date: Sat, 6 Jun 2020 02:21:43 +0530 Subject: [PATCH 3/7] Add news entry --- news/AFD0EAD4-42B3-4EC1-A2AE-70D7513C8555.trivial | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 news/AFD0EAD4-42B3-4EC1-A2AE-70D7513C8555.trivial diff --git a/news/AFD0EAD4-42B3-4EC1-A2AE-70D7513C8555.trivial b/news/AFD0EAD4-42B3-4EC1-A2AE-70D7513C8555.trivial new file mode 100644 index 00000000000..e69de29bb2d From d3f012cb3b5f3050cf12754fbd6f19eed30ca856 Mon Sep 17 00:00:00 2001 From: Devesh Kumar Singh Date: Sat, 6 Jun 2020 02:46:26 +0530 Subject: [PATCH 4/7] Fix argument type for ca_bundle_info --- src/pip/_internal/commands/debug.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pip/_internal/commands/debug.py b/src/pip/_internal/commands/debug.py index ffe341dde7f..acd273e625c 100644 --- a/src/pip/_internal/commands/debug.py +++ b/src/pip/_internal/commands/debug.py @@ -22,6 +22,7 @@ from types import ModuleType from typing import List, Optional, Dict from optparse import Values + from pip._internal.configuration import Configuration logger = logging.getLogger(__name__) @@ -164,9 +165,9 @@ def show_tags(options): def ca_bundle_info(config): - # type: (Dict[str, str]) -> str + # type: (Configuration) -> str levels = set() - for key in config: + for key, _ in config.items(): levels.add(key.split('.')[0]) if not levels: From 021eddcb7048df0693339ac2bfb14813f3c16622 Mon Sep 17 00:00:00 2001 From: Devesh Kumar Singh Date: Sat, 6 Jun 2020 12:21:06 +0530 Subject: [PATCH 5/7] Remove try/catch and use next --- src/pip/_internal/utils/misc.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/pip/_internal/utils/misc.py b/src/pip/_internal/utils/misc.py index 467ae5452e1..50a86982e4e 100644 --- a/src/pip/_internal/utils/misc.py +++ b/src/pip/_internal/utils/misc.py @@ -17,7 +17,7 @@ import sys from collections import deque -from pip._vendor import pkg_resources, six +from pip._vendor import pkg_resources # NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is # why we ignore the type on this import. from pip._vendor.retrying import retry # type: ignore @@ -545,13 +545,7 @@ def __init__(self, lines): def readline(self): try: - try: - return next(self._gen) - except NameError: - # flake8-bugbear B305 suggests using six.next for - # Python 2 compatibility. This along with the try/except - # block can be removed once we drop Python 2 support - return six.next(self._gen) + return next(self._gen) except StopIteration: return '' From 76257e4b6595e04c9f92cc284b8866d096d6725a Mon Sep 17 00:00:00 2001 From: Devesh Kumar Singh Date: Sat, 6 Jun 2020 13:46:06 +0530 Subject: [PATCH 6/7] Use module.__file__ --- src/pip/_internal/commands/debug.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pip/_internal/commands/debug.py b/src/pip/_internal/commands/debug.py index acd273e625c..119569b1886 100644 --- a/src/pip/_internal/commands/debug.py +++ b/src/pip/_internal/commands/debug.py @@ -87,8 +87,12 @@ def get_vendor_version_from_module(module_name): if not version: # Try to find version in debundled module info + # The type for module.__file__ is Optional[str] in + # Python 2, and str in Python 3. The type: ignore is + # added to account for Python 2, instead of a cast + # and should be removed once we drop Python 2 support pkg_set = pkg_resources.WorkingSet( - [os.path.dirname(getattr(module, '__file__', None))] + [os.path.dirname(module.__file__)] # type: ignore ) package = pkg_set.find(pkg_resources.Requirement.parse(module_name)) version = getattr(package, 'version', None) From 8f1d808deb6e6ce06942160c9eef36821da9d59c Mon Sep 17 00:00:00 2001 From: Devesh Kumar Singh Date: Wed, 10 Jun 2020 00:39:50 +0530 Subject: [PATCH 7/7] Add noqa B010 for setattr --- src/pip/_internal/cli/cmdoptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pip/_internal/cli/cmdoptions.py b/src/pip/_internal/cli/cmdoptions.py index adfc81767c4..120d51eeebe 100644 --- a/src/pip/_internal/cli/cmdoptions.py +++ b/src/pip/_internal/cli/cmdoptions.py @@ -835,7 +835,7 @@ def _handle_no_use_pep517(option, opt, value, parser): # TODO: Move into a class that inherits from partial, currently does not # work as mypy complains functools.partial is a generic class. # This way we know we can ignore this option in docs auto generation -setattr(always_unzip, 'deprecated', True) +setattr(always_unzip, 'deprecated', True) # noqa: B010 def _handle_merge_hash(option, opt_str, value, parser):