Skip to content

Commit 6068996

Browse files
committed
ENH: Try to detect if we're checking numpy so npy_ is normal
This got a lot of false positives in the NumPy repository. Perhaps it should be a switch from a higher level.
1 parent a6163c1 commit 6068996

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

src/check_python_h_first/single_file.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,24 @@
4242
]
4343

4444

45-
def check_python_h_included_first(name_to_check: str) -> int:
45+
def has_python_construct(line: str, checking_numpy: bool = False) -> bool:
46+
"""Test whether the line uses Python.
47+
48+
This is an attempt to detect files that expect ``Python.h`` to be
49+
included, but do not do so themselves.
50+
51+
"""
52+
result = (
53+
"py::" in line or "PYBIND11_" in line or " Py" in line or line.startswith("Py")
54+
)
55+
if not checking_numpy:
56+
result = result or " npy_" in line
57+
return result
58+
59+
60+
def check_python_h_included_first(
61+
name_to_check: str, checking_numpy: bool = False
62+
) -> int:
4663
"""Check that the passed file includes Python.h first if it does at all.
4764
4865
Perhaps overzealous, but that should work around concerns with
@@ -98,7 +115,9 @@ def check_python_h_included_first(name_to_check: str) -> int:
98115
included_python = True
99116
PYTHON_INCLUDING_HEADERS.append(basename_to_check)
100117
if os.path.dirname(name_to_check).endswith("include/numpy"):
101-
PYTHON_INCLUDING_HEADERS.append(f"numpy/{basename_to_check:s}")
118+
PYTHON_INCLUDING_HEADERS.append(
119+
f"numpy/{basename_to_check:s}"
120+
) # pragma: no cover
102121
# We just found out where Python.h comes in this file
103122
break
104123
elif this_header in LEAF_HEADERS:
@@ -125,8 +144,7 @@ def check_python_h_included_first(name_to_check: str) -> int:
125144
not included_python
126145
and not warned_python_construct
127146
and ".h" not in basename_to_check
128-
) and ("py::" in line or "PYBIND11_" in line
129-
or " npy_" in line or " Py" in line or line.startswith("Py")):
147+
) and has_python_construct(line, checking_numpy):
130148
print(
131149
"Python-including header not used before python constructs "
132150
f"in file {name_to_check:s}\nConstruct on line {i:d}",
@@ -135,4 +153,6 @@ def check_python_h_included_first(name_to_check: str) -> int:
135153
warned_python_construct = True
136154
if not includes_headers:
137155
LEAF_HEADERS.append(basename_to_check)
138-
return (included_python and len(included_non_python_header)) or warned_python_construct
156+
return (
157+
included_python and len(included_non_python_header)
158+
) or warned_python_construct

src/check_python_h_first/wrapper.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,18 @@ def process_files(file_list: list[str]) -> int:
7575
"""
7676
n_out_of_order = 0
7777
submodule_paths = get_submodule_paths()
78-
root_directory = os.path.dirname(os.path.dirname(__file__))
78+
root_directory = os.getcwd()
79+
checking_numpy = "numpy" in os.path.commonpath(file_list)
7980
for name_to_check in sorted(file_list, key=sort_order):
8081
name_to_check = os.path.join(root_directory, name_to_check)
8182
if any(submodule_path in name_to_check for submodule_path in submodule_paths):
8283
continue
8384
if ".dispatch." in name_to_check:
8485
continue
8586
try:
86-
n_out_of_order += check_python_h_included_first(name_to_check)
87+
n_out_of_order += check_python_h_included_first(
88+
name_to_check, checking_numpy
89+
)
8790
except UnicodeDecodeError:
8891
print(f"File {name_to_check:s} not utf-8", sys.stdout)
8992
return n_out_of_order

0 commit comments

Comments
 (0)