Skip to content

Commit

Permalink
Add "no del" check: (#50)
Browse files Browse the repository at this point in the history
This basically checks for instances of the `del` keyword which can be replaced
with the more descriptive `.pop()` or `.clear()` methods.
  • Loading branch information
dosisod authored Oct 6, 2022
1 parent 28480c3 commit 0cb9711
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
69 changes: 69 additions & 0 deletions refurb/checks/builtin/no_del.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from dataclasses import dataclass

from mypy.nodes import DelStmt, IndexExpr, NameExpr, SliceExpr, Var

from refurb.error import Error


@dataclass
class ErrorInfo(Error):
"""
The `del` statement has it's uses, but for the most part, it can be
replaced with a more flexible and expressive alternative.
With `dict` and `list` types you can remove a key/index by using the
`.pop()` method. If you want to remove all the elements in a `dict` or
`list`, use `.clear()` instead.
Bad:
```
names = {"key": "value"}
nums = [1, 2, 3]
del names["key"]
del nums[0]
del nums[:]
```
Good:
```
names = {"key": "value"}
nums = [1, 2, 3]
names.pop("key")
nums.pop(0)
nums.clear()
```
"""

code = 131


def check(node: DelStmt, errors: list[Error]) -> None:
match node:
case DelStmt(
expr=IndexExpr(base=NameExpr(node=Var(type=ty)), index=index)
) if str(ty).startswith(("builtins.dict[", "builtins.list[")):
match index:
case SliceExpr(begin_index=None, end_index=None):
errors.append(
ErrorInfo(
node.line,
node.column,
"Replace `del x[:]` with `x.clear()`",
)
)

case SliceExpr():
pass

case _:
errors.append(
ErrorInfo(
node.line,
node.column,
"Replace `del x[y]` with `x.pop(y)`",
)
)
16 changes: 16 additions & 0 deletions test/data/err_131.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
names = {"key": "value"}
nums = [1, 2, 3]

# these should match

del names["key"]
del nums[0]
del nums[:]


# these should not

x = 1
del x

del nums[1:2]
3 changes: 3 additions & 0 deletions test/data/err_131.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
test/data/err_131.py:6:1 [FURB131]: Replace `del x[y]` with `x.pop(y)`
test/data/err_131.py:7:1 [FURB131]: Replace `del x[y]` with `x.pop(y)`
test/data/err_131.py:8:1 [FURB131]: Replace `del x[:]` with `x.clear()`

0 comments on commit 0cb9711

Please sign in to comment.