File: no_del.py

package info (click to toggle)
python-refurb 1.27.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,700 kB
  • sloc: python: 9,468; makefile: 40; sh: 6
file content (50 lines) | stat: -rw-r--r-- 1,207 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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 is commonly used for popping single elements from dicts
    and lists, though a slice can be used to remove a range of elements
    instead. When removing all elements via a slice, use the faster and more
    succinct `.clear()` method instead.

    Bad:

    ```
    names = {"key": "value"}
    nums = [1, 2, 3]

    del names[:]
    del nums[:]
    ```

    Good:

    ```
    names = {"key": "value"}
    nums = [1, 2, 3]

    names.clear()
    nums.clear()
    ```
    """

    name = "no-del"
    code = 131
    categories = ("builtin", "readability")
    msg: str = "Replace `del x[:]` with `x.clear()`"


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.from_node(node))