Skip to content
This repository was archived by the owner on Feb 19, 2023. It is now read-only.

Commit 1c6f213

Browse files
committed
No single letter variables
This allows `_` to be used as a variable name, since it is conventionally used for throwaway variables, but does not allow any other single letter variables. The `target` method of `ast.Assigns` will normally contain a list of nodes, however for an unpacking assignment (such as `'a,b = c'`) it will contain an `ast.Tuple` or an `ast.List` so we need to cover for all cases.
1 parent 10b166b commit 1c6f213

File tree

4 files changed

+47
-4
lines changed

4 files changed

+47
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ a linter for pandas usage, please see [pandas-vet](https://github.com/deppen8/pa
3939
| PDF020 | found private import across modules |
4040
| PDF021 | found 'np.bool' or 'np.object' (use 'np.bool_' or 'np.object_' instead) |
4141
| PDF022 | found import from 'numpy.random' |
42+
| PDF023 | found assignment to single-letter variable |
4243
## contributing
4344

4445
See `contributing.md` for how to get started.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import ast
2+
from typing import Iterator, Tuple
3+
4+
from pandas_dev_flaker._data_tree import State, register
5+
6+
MSG = "PDF023 found assignment to single-letter variable"
7+
8+
9+
@register(ast.Assign)
10+
def visit_Assign(
11+
state: State,
12+
node: ast.Assign,
13+
parent: ast.AST,
14+
) -> Iterator[Tuple[int, int, str]]:
15+
16+
# Unpacking is represented by putting a Tuple or List within targets
17+
if isinstance(node.targets[0], (ast.Tuple, ast.List)):
18+
assignment_names = node.targets[0].elts
19+
else:
20+
assignment_names = node.targets
21+
22+
for item in assignment_names:
23+
if isinstance(item, ast.Name) and item.id != "_" and len(item.id) == 1:
24+
yield item.lineno, item.col_offset, MSG

tests/no_single_letter_variables_test.py renamed to tests/single_letter_variables_test.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ def results(s):
2424
"ab = 3",
2525
id="Multi-letter assignment",
2626
),
27+
pytest.param(
28+
"_ = 3",
29+
id="Underscore assignment",
30+
),
31+
pytest.param(
32+
"ab, cd, _ = (1, 2, 3)",
33+
id="Unpacking including an underscore",
34+
),
2735
),
2836
)
2937
def test_noop(source):
@@ -35,9 +43,19 @@ def test_noop(source):
3543
(
3644
pytest.param(
3745
"a = 3",
38-
"1:0: PDF023 don't assign to single-letter variables",
46+
"1:0: PDF023 found assignment to single-letter variable",
3947
id="Single letter variable",
4048
),
49+
pytest.param(
50+
"bar = a = 1",
51+
"1:6: PDF023 found assignment to single-letter variable",
52+
id="Multiple assignment",
53+
),
54+
pytest.param(
55+
"a, bar = (3, 5)",
56+
"1:0: PDF023 found assignment to single-letter variable",
57+
id="Unpacking",
58+
),
4159
),
4260
)
4361
def test_violation(source, expected):

tests/string_to_concatenate_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def results(s):
2121
"source",
2222
(
2323
pytest.param(
24-
"a = (\n" " 'foo'\n" " 'bar'\n" ")",
24+
"var = (\n" " 'foo'\n" " 'bar'\n" ")",
2525
id="separate lines",
2626
),
2727
),
@@ -34,8 +34,8 @@ def test_noop(source):
3434
"source, expected",
3535
(
3636
pytest.param(
37-
"a = 'foo''bar'",
38-
"1:4: PDF007 line split in two unnecessarily by 'black' formatter",
37+
"var = 'foo''bar'",
38+
"1:6: PDF007 line split in two unnecessarily by 'black' formatter",
3939
id="consecutive strings",
4040
),
4141
),

0 commit comments

Comments
 (0)