-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Prevent redefined-outer-name
for if t.TYPE_CHECKING
#7525
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
16cafcc
to
c4410ea
Compare
Pull Request Test Coverage Report for Build 3118393877
π - Coveralls |
π€ Effect of this PR on checked open source code: π€ Effect on flask:
This comment was generated for commit c4410ea |
isinstance(definition.parent, nodes.If) | ||
and definition.parent.test.as_string() in TYPING_TYPE_CHECKS_GUARDS | ||
for definition in globs[name] | ||
in_type_checking_block(definition) for definition in globs[name] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is in scope, but there is only one reference to TYPING_TYPE_CHECKS_GUARDS
remaining. Should we remove it as well and use this function everywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that should be a follow-up PR. At first glance I'm not sure there's a drop-in replacement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index 65a9e8c8b..59e9f7fba 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -2011,10 +2011,7 @@ class VariablesChecker(BaseChecker):
if isinstance(defstmt, (nodes.Import, nodes.ImportFrom)):
defstmt_parent = defstmt.parent
- if (
- isinstance(defstmt_parent, nodes.If)
- and defstmt_parent.test.as_string() in TYPING_TYPE_CHECKS_GUARDS
- ):
+ if in_type_checking_block(defstmt):
# Exempt those definitions that are used inside the type checking
# guard or that are defined in both type checking guard branches.
used_in_branch = defstmt_parent.parent_of(node)
Passed all functional tests for me locally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned there aren't enough tests. This example depends on defstmt_parent
being nodes.If
. in_type_checking_block
is more robust, and doesn't assume direct parentage by a nodes.If
. There's more control flow in this example; it needs more thought.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah, my bad. What about:
if isinstance(defstmt_parent, nodes.If) and in_type_checking_block(defstmt):
The in_type_checking_block
doesn't do any control flow analysis and only makes sure we infer instead of relying on the string representation. As far as I see it is a drop-in replacement for defstmt_parent.test.as_string() in TYPING_TYPE_CHECKS_GUARDS
. (But not for isinstance(defstmt_parent, nodes.If)
as you correctly spotted!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't think it's a drop-in replacement because in_type_checking_block()
is recursive. We don't know which if
ancestor met the condition, but the way this block is written, the assumption is that defstmt_parent
is the one that met the condition, and doing a drop-in replacement will violate that condition. Leading me to think it needs more refactoring and a follow-up issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. Shall we open an issue/todo for this? I'm also fine with leaving as is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem, I'll do it. ππ»
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I'll let you merge when the remaining discussion is resolved.
Type of Changes
Description
Closes #7524
Similar solution to #6787