|
2 | 2 | from pathlib import Path |
3 | 3 | import sys |
4 | 4 | import _colorize |
| 5 | +import textwrap |
5 | 6 |
|
6 | 7 | SIMPLE_FUNCTION_REGEX = re.compile(r"PyAPI_FUNC(.+) (\w+)\(") |
7 | 8 | SIMPLE_MACRO_REGEX = re.compile(r"# *define *(\w+)(\(.+\))? ") |
8 | 9 | SIMPLE_INLINE_REGEX = re.compile(r"static inline .+( |\n)(\w+)") |
9 | 10 | SIMPLE_DATA_REGEX = re.compile(r"PyAPI_DATA\(.+\) (\w+)") |
10 | 11 |
|
| 12 | +CPYTHON = Path(__file__).parent.parent.parent |
| 13 | +INCLUDE = CPYTHON / "Include" |
| 14 | +C_API_DOCS = CPYTHON / "Doc" / "c-api" |
| 15 | +IGNORED = ( |
| 16 | + (CPYTHON / "Tools" / "check-c-api-docs" / "ignored_c_api.txt") |
| 17 | + .read_text() |
| 18 | + .split("\n") |
| 19 | +) |
| 20 | + |
| 21 | +for index, line in enumerate(IGNORED): |
| 22 | + if line.startswith("#"): |
| 23 | + IGNORED.pop(index) |
| 24 | + |
11 | 25 | MISTAKE = """\ |
12 | 26 | If this is a mistake and this script should not be failing, create an |
13 | 27 | issue and tag Peter (@ZeroIntensity) on it.\ |
14 | 28 | """ |
15 | 29 |
|
16 | | -FOUND_UNDOCUMENTED = f"""\ |
17 | | -Found some undocumented C API(s)! |
18 | 30 |
|
19 | | -Python requires documentation on all public C API symbols, macros, and types. |
20 | | -If these API(s) were not meant to be public, prefix them with a |
21 | | -leading underscore (_PySomething_API) or move them to the internal C API |
22 | | -(pycore_*.h files). |
| 31 | +def found_undocumented(singular: bool): |
| 32 | + some = "an" if singular else "some" |
| 33 | + s = "" if singular else "s" |
| 34 | + these = "this" if singular else "these" |
| 35 | + them = "it" if singular else "them" |
| 36 | + were = "was" if singular else "were" |
23 | 37 |
|
24 | | -In exceptional cases, certain functions can be ignored by adding them to |
25 | | -Tools/c-api-docs-check/ignored_c_api.txt |
| 38 | + return textwrap.dedent( |
| 39 | + f"""\ |
| 40 | + Found {some} undocumented C API{s}! |
26 | 41 |
|
27 | | -{MISTAKE}\ |
28 | | -""" |
| 42 | + Python requires documentation on all public C API symbols, macros, and types. |
| 43 | + If {these} API{s} {were} not meant to be public, prefix {them} with a |
| 44 | + leading underscore (_PySomething_API) or move {them} to the internal C API |
| 45 | + (pycore_*.h files). |
29 | 46 |
|
30 | | -FOUND_IGNORED_DOCUMENTED = f"""\ |
31 | | -Some C API(s) were listed in Tools/c-api-docs-check/ignored_c_api.txt, but |
32 | | -they were found in the documentation. To fix this, remove them from |
33 | | -ignored_c_api.txt. |
| 47 | + In exceptional cases, certain APIs can be ignored by adding them to |
| 48 | + Tools/c-api-docs-check/ignored_c_api.txt |
34 | 49 |
|
35 | | -{MISTAKE}\ |
36 | | -""" |
| 50 | + {MISTAKE}\ |
| 51 | + """ |
| 52 | + ) |
37 | 53 |
|
38 | | -_CPYTHON = Path(__file__).parent.parent.parent |
39 | | -INCLUDE = _CPYTHON / "Include" |
40 | | -C_API_DOCS = _CPYTHON / "Doc" / "c-api" |
41 | | -IGNORED = ( |
42 | | - (_CPYTHON / "Tools" / "check-c-api-docs" / "ignored_c_api.txt") |
43 | | - .read_text() |
44 | | - .split("\n") |
45 | | -) |
46 | 54 |
|
47 | | -for index, line in enumerate(IGNORED): |
48 | | - if line.startswith("#"): |
49 | | - IGNORED.pop(index) |
| 55 | +def found_ignored_documented(singular: bool) -> str: |
| 56 | + some = "a" if singular else "some" |
| 57 | + s = "" if singular else "s" |
| 58 | + them = "it" if singular else "them" |
| 59 | + were = "was" if singular else "were" |
| 60 | + they = "it" if singular else "they" |
| 61 | + |
| 62 | + return textwrap.dedent( |
| 63 | + f"""\ |
| 64 | + Found {some} C API{s} listed in Tools/c-api-docs-check/ignored_c_api.txt, but |
| 65 | + {they} {were} found in the documentation. To fix this, remove {them} from |
| 66 | + ignored_c_api.txt. |
| 67 | +
|
| 68 | + {MISTAKE}\ |
| 69 | + """ |
| 70 | + ) |
50 | 71 |
|
51 | 72 |
|
52 | 73 | def is_documented(name: str) -> bool: |
@@ -145,17 +166,22 @@ def main() -> None: |
145 | 166 |
|
146 | 167 | fail = False |
147 | 168 | to_check = [ |
148 | | - (all_missing, "missing", FOUND_UNDOCUMENTED), |
149 | | - (all_found_ignored, "documented but ignored", FOUND_IGNORED_DOCUMENTED), |
| 169 | + (all_missing, "missing", found_undocumented(len(all_missing) == 1)), |
| 170 | + ( |
| 171 | + all_found_ignored, |
| 172 | + "documented but ignored", |
| 173 | + found_ignored_documented(len(all_found_ignored) == 1), |
| 174 | + ), |
150 | 175 | ] |
151 | 176 | for name_list, what, message in to_check: |
152 | 177 | if not name_list: |
153 | 178 | continue |
154 | 179 |
|
155 | 180 | s = "s" if len(name_list) != 1 else "" |
156 | 181 | print(f"-- {len(name_list)} {what} C API{s} --") |
157 | | - for name in all_missing: |
| 182 | + for name in name_list: |
158 | 183 | print(f" - {name}") |
| 184 | + print() |
159 | 185 | print(message) |
160 | 186 | fail = True |
161 | 187 |
|
|
0 commit comments