Skip to content

Commit 1bbbe92

Browse files
after review
1 parent 064c930 commit 1bbbe92

3 files changed

Lines changed: 52 additions & 23 deletions

File tree

tests/fixtures/noqa/noqa.py

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -122,20 +122,13 @@ class Nested: # noqa: WPS431
122122

123123
def nested(): # noqa: WPS430
124124
...
125-
126-
def factory(): # ok
127-
if some_condition():
128-
def deep_nested(): # noqa: WPS430
129-
...
130-
else:
131-
def wrapper(): # ok
132-
...
133-
if some_other_condition():
134-
def deep_nested(): # noqa: WPS430
135-
...
136-
else:
137-
def decorator(): # ok
138-
...
125+
126+
if some_condition():
127+
def deep_nested(): # noqa: WPS430
128+
...
129+
else:
130+
async def deep_nested(): # noqa: WPS430
131+
...
139132

140133

141134
del {'a': 1}['a'] # noqa: WPS420

tests/test_visitors/test_ast/test_complexity/test_nested/test_nested_functions.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,34 @@ def test_whitelist_nested_functions(
234234
[
235235
nested_function_in_if,
236236
nested_function_in_if_else,
237+
],
238+
)
239+
def test_deep_whitelist_nested_functions_allowed(
240+
assert_errors,
241+
assert_error_text,
242+
parse_ast_tree,
243+
whitelist_name,
244+
code,
245+
default_options,
246+
mode,
247+
):
248+
"""
249+
Test for allowed whitelisted functions inside single if(/else) block.
250+
251+
See: https://github.com/wemake-services/wemake-python-styleguide/issues/3589
252+
"""
253+
tree = parse_ast_tree(mode(code.format(whitelist_name)))
254+
255+
visitor = NestedComplexityVisitor(default_options, tree=tree)
256+
visitor.run()
257+
258+
assert_errors(visitor, [])
259+
260+
261+
@pytest.mark.parametrize('whitelist_name', NESTED_FUNCTIONS_WHITELIST)
262+
@pytest.mark.parametrize(
263+
'code',
264+
[
237265
nested_function_while_loop,
238266
nested_function_in_for_loop,
239267
nested_function_in_try,
@@ -251,13 +279,14 @@ def test_deep_whitelist_nested_functions(
251279
default_options,
252280
mode,
253281
):
254-
"""Testing that it is possible to nest whitelisted functions."""
282+
"""Testing that it is restricted to nest even whitelisted functions."""
255283
tree = parse_ast_tree(mode(code.format(whitelist_name)))
256284

257285
visitor = NestedComplexityVisitor(default_options, tree=tree)
258286
visitor.run()
259287

260-
assert_errors(visitor, [])
288+
assert_errors(visitor, [NestedFunctionViolation])
289+
assert_error_text(visitor, whitelist_name)
261290

262291

263292
@pytest.mark.parametrize(

wemake_python_styleguide/visitors/ast/complexity/nested.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,23 @@ def visit_Lambda(self, node: ast.Lambda) -> None:
5656
self.generic_visit(node)
5757

5858
def _check_nested_function(self, node: AnyFunctionDef) -> None:
59-
is_inside_function = isinstance(get_context(node), FunctionNodes)
59+
if not isinstance(get_context(node), FunctionNodes):
60+
return
6061

61-
is_not_whitelisted = node.name not in NESTED_FUNCTIONS_WHITELIST
62-
is_direct = isinstance(get_parent(node), FunctionNodes)
63-
is_bad = is_direct and is_not_whitelisted
62+
parent = get_parent(node)
6463

65-
if is_bad or (
66-
is_inside_function and not is_direct and is_not_whitelisted
64+
is_direct = isinstance(parent, FunctionNodes)
65+
66+
is_single_if = isinstance(parent, ast.If) and isinstance(
67+
get_parent(parent), FunctionNodes
68+
)
69+
70+
if node.name not in NESTED_FUNCTIONS_WHITELIST or not (
71+
is_direct or is_single_if
6772
):
68-
self.add_violation(NestedFunctionViolation(node, text=node.name))
73+
self.add_violation(
74+
NestedFunctionViolation(node, text=node.name),
75+
)
6976

7077
def _check_nested_classes(self, node: ast.ClassDef) -> None:
7178
parent_context = get_context(node)

0 commit comments

Comments
 (0)