Skip to content

Commit

Permalink
Merge branch 'master' into import-outside-toplevel
Browse files Browse the repository at this point in the history
  • Loading branch information
PCManticore authored Sep 17, 2019
2 parents 263b8b1 + a7f2365 commit 1ed5801
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 5 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Release date: TBA
This check warns when modules are imported from places other than a
module toplevel, e.g. inside a function or a class.

* 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
Expand Down
19 changes: 14 additions & 5 deletions pylint/checkers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand All @@ -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
)
Expand Down
5 changes: 5 additions & 0 deletions pylint/checkers/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,11 @@ def _is_variable_violation(
# Single statement function, with the statement on the
# same line as the function definition
maybee0601 = False
if isinstance(defstmt, (astroid.Import, astroid.ImportFrom)):
defstmt_parent = defstmt.parent
if isinstance(defstmt_parent, astroid.If):
if defstmt_parent.test.as_string() in TYPING_TYPE_CHECKS_GUARDS:
maybee0601 = True

return maybee0601, annotation_return, use_outer_definition

Expand Down
9 changes: 9 additions & 0 deletions tests/functional/f/function_redefined_2540.py
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions tests/functional/f/function_redefined_2540.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[testoptions]
min_pyver=3.7
11 changes: 11 additions & 0 deletions tests/functional/u/undefined_variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,14 @@ def onclick(event):
fig = plt.figure()
fig.canvas.mpl_connect('button_press_event', onclick)
plt.show(block=True)


# pylint: disable=wrong-import-position
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from datetime import datetime


def func_should_fail(_dt: datetime): # [used-before-assignment]
pass
1 change: 1 addition & 0 deletions tests/functional/u/undefined_variable.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ undefined-variable:161::Undefined variable 'unicode_2'
undefined-variable:171::Undefined variable 'unicode_4'
undefined-variable:226:LambdaClass4.<lambda>:Undefined variable 'LambdaClass4'
undefined-variable:234:LambdaClass5.<lambda>:Undefined variable 'LambdaClass5'
used-before-assignment:257:func_should_fail:Using variable 'datetime' before assignment

0 comments on commit 1ed5801

Please sign in to comment.