diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d749de5d07..f8b43cee14 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -57,7 +57,8 @@ repos: rev: 5.0.4 hooks: - id: flake8 - additional_dependencies: [flake8-typing-imports==1.14.0] + additional_dependencies: + [flake8-bugbear==22.10.27, flake8-typing-imports==1.14.0] exclude: *fixtures - repo: local hooks: diff --git a/pylint/checkers/format.py b/pylint/checkers/format.py index d33def5b5d..247385f2a8 100644 --- a/pylint/checkers/format.py +++ b/pylint/checkers/format.py @@ -529,7 +529,7 @@ def visit_default(self, node: nodes.NodeNG) -> None: tolineno = node.tolineno assert tolineno, node lines: list[str] = [] - for line in range(line, tolineno + 1): + for line in range(line, tolineno + 1): # noqa: B020 self._visited_lines[line] = 1 try: lines.append(self._lines[line].rstrip()) @@ -676,15 +676,11 @@ def check_lines( if tokens.type(line_start) != tokenize.STRING: self.check_trailing_whitespace_ending(line, lineno + offset) - # hold onto the initial lineno for later - potential_line_length_warning = False - for offset, line in enumerate(split_lines): - # this check is purposefully simple and doesn't rstrip - # since this is running on every line you're checking it's - # advantageous to avoid doing a lot of work - if len(line) > max_chars: - potential_line_length_warning = True - break + # This check is purposefully simple and doesn't rstrip since this is running + # on every line you're checking it's advantageous to avoid doing a lot of work + potential_line_length_warning = any( + len(line) > max_chars for line in split_lines + ) # if there were no lines passing the max_chars config, we don't bother # running the full line check (as we've met an even more strict condition) diff --git a/pylint/checkers/strings.py b/pylint/checkers/strings.py index dc332d9ecc..74cad2e22c 100644 --- a/pylint/checkers/strings.py +++ b/pylint/checkers/strings.py @@ -834,16 +834,16 @@ def check_for_concatenated_strings( def process_string_token(self, token: str, start_row: int, start_col: int) -> None: quote_char = None - index = None - for index, char in enumerate(token): + for _index, char in enumerate(token): if char in "'\"": quote_char = char break if quote_char is None: return - - prefix = token[:index].lower() # markers like u, b, r. - after_prefix = token[index:] + # pylint: disable=undefined-loop-variable + prefix = token[:_index].lower() # markers like u, b, r. + after_prefix = token[_index:] + # pylint: enable=undefined-loop-variable # Chop off quotes quote_length = ( 3 if after_prefix[:3] == after_prefix[-3:] == 3 * quote_char else 1 diff --git a/pylint/checkers/typecheck.py b/pylint/checkers/typecheck.py index 7ec8bab5fb..a5c6d07ac3 100644 --- a/pylint/checkers/typecheck.py +++ b/pylint/checkers/typecheck.py @@ -1584,7 +1584,10 @@ def visit_call(self, node: nodes.Call) -> None: # 3. Match the **kwargs, if any. if node.kwargs: - for i, [(name, defval), assigned] in enumerate(parameters): + # TODO: It's possible to remove this disable by using dummy-variables-rgx + # see https://github.com/PyCQA/pylint/pull/7697#discussion_r1010832518 + # pylint: disable-next=unused-variable + for i, [(name, _defval), _assigned] in enumerate(parameters): # Assume that *kwargs provides values for all remaining # unassigned named parameters. if name is not None: diff --git a/pylint/checkers/utils.py b/pylint/checkers/utils.py index b3e376ffe4..af4745538d 100644 --- a/pylint/checkers/utils.py +++ b/pylint/checkers/utils.py @@ -491,7 +491,7 @@ def only_required_for_messages( def store_messages( func: AstCallbackMethod[_CheckerT, _NodeT] ) -> AstCallbackMethod[_CheckerT, _NodeT]: - setattr(func, "checks_msgs", messages) + func.checks_msgs = messages # type: ignore[attr-defined] return func return store_messages diff --git a/pylint/lint/caching.py b/pylint/lint/caching.py index 573b976288..8ea8a22368 100644 --- a/pylint/lint/caching.py +++ b/pylint/lint/caching.py @@ -12,12 +12,14 @@ from pylint.constants import PYLINT_HOME from pylint.utils import LinterStats +PYLINT_HOME_AS_PATH = Path(PYLINT_HOME) + def _get_pdata_path( - base_name: Path, recurs: int, pylint_home: Path = Path(PYLINT_HOME) + base_name: Path, recurs: int, pylint_home: Path = PYLINT_HOME_AS_PATH ) -> Path: - # We strip all characters that can't be used in a filename - # Also strip '/' and '\\' because we want to create a single file, not sub-directories + # We strip all characters that can't be used in a filename. Also strip '/' and + # '\\' because we want to create a single file, not sub-directories. underscored_name = "_".join( str(p.replace(":", "_").replace("/", "_").replace("\\", "_")) for p in base_name.parts diff --git a/pylint/message/message_definition_store.py b/pylint/message/message_definition_store.py index ef26d648df..810140b7cc 100644 --- a/pylint/message/message_definition_store.py +++ b/pylint/message/message_definition_store.py @@ -52,10 +52,12 @@ def register_message(self, message: MessageDefinition) -> None: self._msgs_by_category[message.msgid[0]].append(message.msgid) # Since MessageDefinitionStore is only initialized once - # and the arguments are relatively small in size we do not run the + # and the arguments are relatively small we do not run the # risk of creating a large memory leak. # See discussion in: https://github.com/PyCQA/pylint/pull/5673 - @functools.lru_cache(maxsize=None) # pylint: disable=method-cache-max-size-none + @functools.lru_cache( # pylint: disable=method-cache-max-size-none # noqa: B019 + maxsize=None + ) def get_message_definitions(self, msgid_or_symbol: str) -> list[MessageDefinition]: """Returns the Message definition for either a numeric or symbolic id. diff --git a/requirements_test_pre_commit.txt b/requirements_test_pre_commit.txt index 2b2a1e329c..730c96bd1a 100644 --- a/requirements_test_pre_commit.txt +++ b/requirements_test_pre_commit.txt @@ -2,6 +2,7 @@ # in .pre-commit-config.yaml black==22.10.0 flake8==5.0.4 +flake8-bugbear==22.10.27 flake8-typing-imports==1.14.0 isort==5.10.1 mypy==0.982 diff --git a/tests/test_check_parallel.py b/tests/test_check_parallel.py index 420ed3d935..d5cdf0715d 100644 --- a/tests/test_check_parallel.py +++ b/tests/test_check_parallel.py @@ -239,7 +239,9 @@ def test_linter_with_unpickleable_plugins_is_pickleable(self) -> None: linter.load_plugin_modules(["pylint.extensions.overlapping_exceptions"]) try: dill.dumps(linter) - assert False, "Plugins loaded were pickle-safe! This test needs altering" + raise AssertionError( + "Plugins loaded were pickle-safe! This test needs altering" + ) except (KeyError, TypeError, PickleError, NotImplementedError): pass @@ -247,8 +249,10 @@ def test_linter_with_unpickleable_plugins_is_pickleable(self) -> None: linter.load_plugin_configuration() try: dill.dumps(linter) - except KeyError: - assert False, "Cannot pickle linter when using non-pickleable plugin" + except KeyError as exc: + raise AssertionError( + "Cannot pickle linter when using non-pickleable plugin" + ) from exc def test_worker_check_sequential_checker(self) -> None: """Same as test_worker_check_single_file_no_checkers with SequentialTestChecker."""