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

Commit 8be2d08

Browse files
authored
Merge pull request #25 from klssmith/no-single-letter-variables
No single letter variables
2 parents 92aff77 + 1c6f213 commit 8be2d08

File tree

4 files changed

+91
-3
lines changed

4 files changed

+91
-3
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/single_letter_variables_test.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import ast
2+
import tokenize
3+
from io import StringIO
4+
5+
import pytest
6+
7+
from pandas_dev_flaker.__main__ import run
8+
9+
10+
def results(s):
11+
return {
12+
"{}:{}: {}".format(*r)
13+
for r in run(
14+
ast.parse(s),
15+
list(tokenize.generate_tokens(StringIO(s).readline)),
16+
)
17+
}
18+
19+
20+
@pytest.mark.parametrize(
21+
"source",
22+
(
23+
pytest.param(
24+
"ab = 3",
25+
id="Multi-letter assignment",
26+
),
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+
),
35+
),
36+
)
37+
def test_noop(source):
38+
assert not results(source)
39+
40+
41+
@pytest.mark.parametrize(
42+
"source, expected",
43+
(
44+
pytest.param(
45+
"a = 3",
46+
"1:0: PDF023 found assignment to single-letter variable",
47+
id="Single letter variable",
48+
),
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+
),
59+
),
60+
)
61+
def test_violation(source, expected):
62+
(result,) = results(source)
63+
assert result == 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)