Skip to content

Commit

Permalink
Closes #1898, closes #1883
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn committed Jun 21, 2021
1 parent 0f16b83 commit 6ba9cdc
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Semantic versioning in our case means:
- Fixes `ReassigningVariableToItselfViolation` to extract variables
from unary operators #1874
- Fixes that `f'{some:,}'` was considered too complex #1921
- Fixes that `range(len(x))` was not allowed even outside `for` loops #1883

### Misc

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@
WrongFunctionCallContextVisitor,
)

for_template = """
def function():
for list_item in {0}:
...
"""

wrong_samples = (
'range(len())',
'range(len(some))',
'range(len([]))',
'range(1, len(some))',
'range(-1, len(some))',
'range(0, len(some), -1)',
)


@pytest.mark.parametrize('code', [
'range(10)',
Expand All @@ -25,34 +40,45 @@ def test_correct_range_len(
parse_ast_tree,
code,
default_options,
mode,
):
"""Testing that ``range()`` can be used."""
tree = parse_ast_tree(code)
tree = parse_ast_tree(mode(for_template.format(code)))

visitor = WrongFunctionCallContextVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [])


@pytest.mark.parametrize('code', [
'range(len())',
'range(len(some))',
'range(len([]))',
'range(1, len(some))',
'range(-1, len(some))',
'range(0, len(some), -1)',
])
@pytest.mark.parametrize('code', wrong_samples)
def test_range_len(
assert_errors,
parse_ast_tree,
code,
default_options,
mode,
):
"""Testing that ``range(len(...))`` cannot be used."""
tree = parse_ast_tree(code)
tree = parse_ast_tree(mode(for_template.format(code)))

visitor = WrongFunctionCallContextVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [ImplicitEnumerateViolation])


@pytest.mark.parametrize('code', wrong_samples)
def test_range_len_outside_for_loop(
assert_errors,
parse_ast_tree,
code,
default_options,
):
"""Testing that ``range(len(...))`` can be used outside loops."""
tree = parse_ast_tree(code)

visitor = WrongFunctionCallContextVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [])
8 changes: 7 additions & 1 deletion wemake_python_styleguide/visitors/ast/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

from typing_extensions import final

from wemake_python_styleguide.compat.aliases import FunctionNodes, TextNodes
from wemake_python_styleguide.compat.aliases import (
ForNodes,
FunctionNodes,
TextNodes,
)
from wemake_python_styleguide.compat.functions import get_posonlyargs
from wemake_python_styleguide.constants import (
FUNCTIONS_BLACKLIST,
Expand Down Expand Up @@ -240,6 +244,8 @@ def _check_type_compare(self, node: ast.Call) -> None:
self.add_violation(TypeCompareViolation(node))

def _check_range_len(self, node: ast.Call) -> None:
if not isinstance(nodes.get_parent(node), ForNodes):
return
if not functions.given_function_called(node, {'range'}):
return

Expand Down

0 comments on commit 6ba9cdc

Please sign in to comment.