Skip to content

Commit

Permalink
Closes #1874, closes #1807
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn committed Jun 21, 2021
1 parent b52a00e commit 362e826
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 64 deletions.
13 changes: 9 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,22 @@ Semantic versioning in our case means:
There are no major releases right now: we are still at `0.x.y` version.
But, in the future we might change the configuration names / logic,
change the client facing API, change code conventions signigicantly, etc.
## 0.15.3 WIP


## 0.15.3

### Bugfixes

- Fixes crash on `python3.10`
- Fixes `UselessReturningElseViolation` to not report `else` with `break` #1958
- Fixes `ReassigningVariableToItselfViolation` to not report on `x = (x,)` #1807
- Fixes `ReassigningVariableToItselfViolation` to extract variables
from unary operators #1874

### Misc

- Adds documentation (and test) for how to run project on Jupyter Notebooks
- Adds documentation (and tests) for how to run project on Jupyter Notebooks
- Updates `mypy` to `0.902` and fixes type issues


## 0.15.2
Expand Down
110 changes: 56 additions & 54 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ snapshottest = "^0.6"
hypothesis = "^6.14"
hypothesmith = "^0.1"

mypy = "^0.812"
mypy = "^0.902"

docutils = "^0.17"
sphinx = "^4.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,22 @@ class MyClass(object):
MyValue = MyValue
"""

# regression 1807
right_tuplelize1 = 'my_var = (my_var,)'
right_tuplelize2 = 'my_var = (other,)'
right_tuplelize3 = 'my_var = (my_var, my_var)'
right_tuplelize4 = 'my_var = (my_var, other)'
right_tuplelize5 = 'my_var = (other, my_var)'

# regression 1874
right_swap1 = 'dx, dy = -dy, dx'
right_swap2 = 'dy, dx = dx, -dy'
right_swap3 = 'dx, dy = --dy, dx'
right_swap4 = 'dx, dy = +dy, -dx'
right_swap5 = 'dx, dy = dy, dx'
right_swap6 = 'dy, dx = dx, dy'


# Wrong:

wrong_fragment = """
Expand Down Expand Up @@ -240,6 +256,17 @@ def test_self_variable_reassignment_triple(
right_parts_unused3,
right_parts_unused4,
right_class_reassignment,
right_tuplelize1,
right_tuplelize2,
right_tuplelize3,
right_tuplelize4,
right_tuplelize5,
right_swap1,
right_swap2,
right_swap3,
right_swap4,
right_swap5,
right_swap6,
])
def test_correct_variable_reassignment(
assert_errors,
Expand Down
12 changes: 7 additions & 5 deletions wemake_python_styleguide/logic/naming/name_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ def get_variables_from_node(node: ast.AST) -> List[str]:

if naive_attempt:
names.append(naive_attempt)
elif isinstance(node, ast.Tuple):
elif isinstance(node, ast.Tuple) and len(node.elts) > 1:
# If tuple has just a single variable, we want to ignore it:
# like `x = (x,)`
for subnode in node.elts:
extracted_name = get_variables_from_node(subnode)
if extracted_name:
names.extend(extracted_name)
names.extend(get_variables_from_node(subnode))
return names


Expand All @@ -100,7 +100,9 @@ def extract_name(node: ast.AST) -> Optional[str]:
"""
if isinstance(node, ast.Starred):
node = node.value
return extract_name(node.value)
if isinstance(node, ast.UnaryOp):
return extract_name(node.operand)
if isinstance(node, ast.Name):
return node.id
return None
3 changes: 3 additions & 0 deletions wemake_python_styleguide/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ class or structure.
"""

def __hash__(self) -> int:
"""We need these options to be hashable."""

# General:
@property
def min_name_length(self) -> int:
Expand Down
5 changes: 5 additions & 0 deletions wemake_python_styleguide/visitors/ast/naming/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ def _check_reassignment(
return # This is not a variable, but a class property

var_values = name_nodes.get_variables_from_node(node.value)
if len(names) <= 1 and len(var_values) > 1:
# It means that we have something like `x = (y, z)`
# or even `x = (x, y)`, which is also fine. See #1807
return

for var_name, var_value in itertools.zip_longest(names, var_values):
if var_name == var_value:
self.add_violation(
Expand Down

0 comments on commit 362e826

Please sign in to comment.