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

Commit e8539d2

Browse files
committed
add check for array_equal and np.testing
1 parent 862fbea commit e8539d2

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ a linter for pandas usage, please see [pandas-vet](https://github.com/deppen8/pa
4141
| PDF022 | found import from 'numpy.random' |
4242
| PDF023 | found assignment to single-letter variable |
4343
| PDF024 | found string join() with generator expressions |
44+
| PDF025 | found 'np.testing' or 'np.array_equal' (use 'pandas._testing' instead) |
45+
4446
## contributing
4547

4648
See `contributing.md` for how to get started.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import ast
2+
from typing import Iterator, Tuple
3+
4+
from pandas_dev_flaker._data_tree import State, register
5+
6+
MSG = (
7+
"PDF025 found 'np.testing' or 'np.array_equal' "
8+
"(use 'pandas._testing' instead)"
9+
)
10+
11+
12+
@register(ast.ImportFrom)
13+
def visit_ImportFrom(
14+
state: State,
15+
node: ast.ImportFrom,
16+
parent: ast.AST,
17+
) -> Iterator[Tuple[int, int, str]]:
18+
if (
19+
(
20+
"testing" in {name.name for name in node.names}
21+
or "array_equal" in {name.name for name in node.names}
22+
)
23+
and node.module is not None
24+
and node.module == "numpy"
25+
) or (node.module is not None and node.module == "numpy.testing"):
26+
yield node.lineno, node.col_offset, MSG
27+
28+
29+
@register(ast.Attribute)
30+
def visit_Attribute(
31+
state: State,
32+
node: ast.Attribute,
33+
parent: ast.AST,
34+
) -> Iterator[Tuple[int, int, str]]:
35+
if (
36+
node.attr in {"testing", "array_equal"}
37+
and isinstance(node.value, ast.Name)
38+
and node.value.id in {"numpy", "np"}
39+
):
40+
yield node.lineno, node.col_offset, MSG

tests/numpy_testing_test.py

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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+
"import numpy as np\nnp.tester",
25+
id="tester instead of testing",
26+
),
27+
),
28+
)
29+
def test_noop(source):
30+
assert not results(source)
31+
32+
33+
@pytest.mark.parametrize(
34+
"source, expected",
35+
(
36+
pytest.param(
37+
"import numpy\nnumpy.testing",
38+
"2:0: PDF025 found 'np.testing' or 'np.array_equal' "
39+
"(use 'pandas._testing' instead)",
40+
id="access from numpy",
41+
),
42+
pytest.param(
43+
"import numpy as np\nnp.testing",
44+
"2:0: PDF025 found 'np.testing' or 'np.array_equal' "
45+
"(use 'pandas._testing' instead)",
46+
id="access from np",
47+
),
48+
pytest.param(
49+
"import numpy as np\n"
50+
"np.testing.assert_array_equal(result, expected)",
51+
"2:0: PDF025 found 'np.testing' or 'np.array_equal' "
52+
"(use 'pandas._testing' instead)",
53+
id="np.testing.assert_array_equal",
54+
),
55+
pytest.param(
56+
"from numpy import testing",
57+
"1:0: PDF025 found 'np.testing' or 'np.array_equal' "
58+
"(use 'pandas._testing' instead)",
59+
id="import from numpy",
60+
),
61+
pytest.param(
62+
"from numpy.testing import assert_array_equal",
63+
"1:0: PDF025 found 'np.testing' or 'np.array_equal' "
64+
"(use 'pandas._testing' instead)",
65+
id="import from numpy",
66+
),
67+
pytest.param(
68+
"from numpy import array_equal",
69+
"1:0: PDF025 found 'np.testing' or 'np.array_equal' "
70+
"(use 'pandas._testing' instead)",
71+
id="array_equal",
72+
),
73+
),
74+
)
75+
def test_violation(source, expected):
76+
(result,) = results(source)
77+
assert result == expected

0 commit comments

Comments
 (0)