Skip to content

Commit db56fc9

Browse files
committed
Add tests
1 parent a067bdc commit db56fc9

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

pylint/checkers/variables.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2380,7 +2380,9 @@ def _is_builtin(self, name: str) -> bool:
23802380
def _has_nonlocal_in_enclosing_frame(
23812381
self, node: nodes.Name, uncertain_definitions: list[nodes.NodeNG]
23822382
) -> bool:
2383-
"""Check if there is a nonlocal declaration in the nearest frame that encloses both usage and definitions."""
2383+
"""Check if there is a nonlocal declaration in the nearest frame that encloses
2384+
both usage and definitions.
2385+
"""
23842386
defining_frames = {definition.frame() for definition in uncertain_definitions}
23852387
frame = node.frame()
23862388
is_enclosing_frame = False

tests/functional/u/used/used_before_assignment_nonlocal.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ def inner():
121121

122122

123123
def nonlocal_in_outer_frame_ok(callback, condition_a, condition_b):
124-
"""Nonlocal declared in outer frame, usage and definition in different frames."""
124+
"""Nonlocal declared in outer frame, usage and definition in different frames,
125+
both enclosed in outer frame.
126+
"""
125127
def outer():
126128
nonlocal callback
127129
if condition_a:
@@ -133,3 +135,31 @@ def inner():
133135
def callback():
134136
pass
135137
outer()
138+
139+
140+
def nonlocal_in_distant_outer_frame_fail(callback, condition_a, condition_b):
141+
"""Nonlocal declared in outer frame, both usage and definition immediately enclosed
142+
in intermediate frame.
143+
"""
144+
def outer():
145+
nonlocal callback
146+
def intermediate():
147+
if condition_a:
148+
def inner():
149+
callback() # [possibly-used-before-assignment]
150+
inner()
151+
else:
152+
if condition_b:
153+
def callback():
154+
pass
155+
intermediate()
156+
outer()
157+
158+
159+
def nonlocal_after_bad_usage_fail():
160+
"""Nonlocal declared after used-before-assignment."""
161+
num = 1
162+
def inner():
163+
num = num + 1 # [used-before-assignment]
164+
nonlocal num
165+
inner()

tests/functional/u/used/used_before_assignment_nonlocal.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ used-before-assignment:39:18:39:28:test_fail5:Using variable 'undefined1' before
77
used-before-assignment:90:10:90:18:type_annotation_never_gets_value_despite_nonlocal:Using variable 'some_num' before assignment:HIGH
88
used-before-assignment:96:14:96:18:inner_function_lacks_access_to_outer_args.inner:Using variable 'args' before assignment:HIGH
99
used-before-assignment:117:18:117:21:nonlocal_in_outer_frame_fail.outer.inner:Using variable 'num' before assignment:HIGH
10+
possibly-used-before-assignment:149:20:149:28:nonlocal_in_distant_outer_frame_fail.outer.intermediate.inner:Possibly using variable 'callback' before assignment:CONTROL_FLOW
11+
used-before-assignment:163:14:163:17:nonlocal_after_bad_usage_fail.inner:Using variable 'num' before assignment:HIGH

0 commit comments

Comments
 (0)