Wemake-python-styleguide: Forbid misrefactored assign op

Created on 23 Aug 2019  路  13Comments  路  Source: wemake-services/wemake-python-styleguide

Rule request

Thesis


We need to forbid code like:

x += x + 1

It is most likely an error. Refactor it to:

  1. x += 1
  2. x *= 2; x += 1

https://rust-lang.github.io/rust-clippy/master/index.html#misrefactored_assign_op
Related: #789

Reasoning

This is a refactoring rule.

Hacktoberfest help wanted starter rule request

All 13 comments

I would like to work on this issue

Awesome! @dinolinjob you are on!

I understood that I have to create a violation in https://github.com/wemake-services/wemake-python-styleguide/blob/master/wemake_python_styleguide/violations/refactoring.py.
Should I raise an error as soon as I come across some line consisting x += x + 1 exists?
Does it come under Tokenize violation?
What are the further steps to complete writing this rule?

@dinolinjob it is an ASTViolation. Then you should create a method inside visitors/ast to find these cases.

@sobolevn should I write a new visitor?

Try to write a _check_* method first on an existing visitor to check the logic. Then we can decide on a new visitor.

@sobolevn In which file under visitors/ast/ should I write my _check_* method?

visitors/ast/statements.py

@sobolevn I am trying to do a TDD, i have written a test in test_statements.py . But when i run it inside the docker image, it takes the installed wemake_python_styleguide. How do one configure the tests to run?

@viveksoundrapandi oh, I must document this. This Dockerfile is for GithubActions, not the local development.

Ahh! Thanks for the clarification

@sobolevn Can you suggest me some ideas on how to approach while writing this rule. Is there a way to compare variables before and after assignment operators?

Yes, you need to visit ast.AugAssign and fetch variables from the right part. If the left variable is contained in the right part - then we raise a violation.

That's how ast.AugAssign looks like for this simple case:

禄 echo 'x += x + 1' > ex.py

禄 python scripts/parse.py ex.py

AugAssign(target=Name(id='x', ctx=Store(), lineno=1, col_offset=0), op=Add(), value=BinOp(left=Name(id='x', ctx=Load(), lineno=1, col_offset=5), op=Add(), right=Num(n=1, lineno=1, col_offset=9), lineno=1, col_offset=5), lineno=1, col_offset=0)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

orsinium picture orsinium  路  5Comments

Dreamsorcerer picture Dreamsorcerer  路  3Comments

sobolevn picture sobolevn  路  3Comments

sobolevn picture sobolevn  路  4Comments

azdanov picture azdanov  路  3Comments