diff --git a/ChangeLog b/ChangeLog index 432dd90be5..0d4d4dc9b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,10 @@ What's New in Pylint 2.4.0? Release date: TBA +* Support forward references for ``function-redefined`` check. + + Close #2540 + * Added a new check, ``consider-using-sys-exit`` This check is emitted when we detect that a quit() or exit() is invoked diff --git a/pylint/checkers/base.py b/pylint/checkers/base.py index df564e0fcc..2a1e904976 100644 --- a/pylint/checkers/base.py +++ b/pylint/checkers/base.py @@ -171,6 +171,7 @@ def get_regex(cls, name_type): COMPARISON_OPERATORS = frozenset(("==", "!=", "<", ">", "<=", ">=")) # List of methods which can be redefined REDEFINABLE_METHODS = frozenset(("__module__",)) +TYPING_FORWARD_REF_QNAME = "typing.ForwardRef" def _redefines_import(node): @@ -820,13 +821,11 @@ def _check_in_loop(self, node, node_name): def _check_redefinition(self, redeftype, node): """check for redefinition of a function / method / class name""" parent_frame = node.parent.frame() + # Ignore function stubs created for type information + redefinitions = parent_frame.locals[node.name] defined_self = next( - ( - local - for local in parent_frame.locals[node.name] - if not utils.is_overload_stub(local) - ), + (local for local in redefinitions if not utils.is_overload_stub(local)), node, ) if defined_self is not node and not astroid.are_exclusive(node, defined_self): @@ -842,6 +841,16 @@ def _check_redefinition(self, redeftype, node): if utils.is_overload_stub(node): return + # Check if we have forward references for this node. + for redefinition in redefinitions[: redefinitions.index(node)]: + inferred = utils.safe_infer(redefinition) + if ( + inferred + and isinstance(inferred, astroid.Instance) + and inferred.qname() == TYPING_FORWARD_REF_QNAME + ): + return + dummy_variables_rgx = lint_utils.get_global_option( self, "dummy-variables-rgx", default=None ) diff --git a/tests/functional/f/function_redefined_2540.py b/tests/functional/f/function_redefined_2540.py new file mode 100644 index 0000000000..25792295e2 --- /dev/null +++ b/tests/functional/f/function_redefined_2540.py @@ -0,0 +1,9 @@ +# pylint: disable=missing-module-docstring,missing-class-docstring,too-few-public-methods,invalid-name + +from typing import ForwardRef + +Cls = ForwardRef("Cls") + + +class Cls: + pass diff --git a/tests/functional/f/function_redefined_2540.rc b/tests/functional/f/function_redefined_2540.rc new file mode 100644 index 0000000000..a17bb22daf --- /dev/null +++ b/tests/functional/f/function_redefined_2540.rc @@ -0,0 +1,2 @@ +[testoptions] +min_pyver=3.7