Download Pytorch/Tools/scripts/pep384_macrocheck.py from RayTBRP/codellama-CodeLlama-7b-Python-hf: direct link, hf CLI and curl.
- Browser
- Download file 4.72 kB
-
https://huggingface.co/RayTBRP/codellama-CodeLlama-7b-Python-hf/resolve/c0c5506eba15c7ab03ff4f59bbe251ee2db72517/Pytorch/Tools/scripts/pep384_macrocheck.py
- Command line
-
hf download hf://RayTBRP/codellama-CodeLlama-7b-Python-hf@c0c5506eba15c7ab03ff4f59bbe251ee2db72517/Pytorch/Tools/scripts/pep384_macrocheck.py
-
curl -L -o pep384_macrocheck.py https://huggingface.co/RayTBRP/codellama-CodeLlama-7b-Python-hf/resolve/c0c5506eba15c7ab03ff4f59bbe251ee2db72517/Pytorch/Tools/scripts/pep384_macrocheck.py
4.72 kB
| """ | |
| pep384_macrocheck.py | |
| This program tries to locate errors in the relevant Python header | |
| files where macros access type fields when they are reachable from | |
| the limited API. | |
| The idea is to search macros with the string "->tp_" in it. | |
| When the macro name does not begin with an underscore, | |
| then we have found a dormant error. | |
| Christian Tismer | |
| 2018-06-02 | |
| """ | |
| import sys | |
| import os | |
| import re | |
| DEBUG = False | |
| def dprint(*args, **kw): | |
| if DEBUG: | |
| print(*args, **kw) | |
| def parse_headerfiles(startpath): | |
| """ | |
| Scan all header files which are reachable fronm Python.h | |
| """ | |
| search = "Python.h" | |
| name = os.path.join(startpath, search) | |
| if not os.path.exists(name): | |
| raise ValueError("file {} was not found in {}\n" | |
| "Please give the path to Python's include directory." | |
| .format(search, startpath)) | |
| errors = 0 | |
| with open(name) as python_h: | |
| while True: | |
| line = python_h.readline() | |
| if not line: | |
| break | |
| found = re.match(r'^\s*#\s*include\s*"(\w+\.h)"', line) | |
| if not found: | |
| continue | |
| include = found.group(1) | |
| dprint("Scanning", include) | |
| name = os.path.join(startpath, include) | |
| if not os.path.exists(name): | |
| name = os.path.join(startpath, "../PC", include) | |
| errors += parse_file(name) | |
| return errors | |
| def ifdef_level_gen(): | |
| """ | |
| Scan lines for #ifdef and track the level. | |
| """ | |
| level = 0 | |
| ifdef_pattern = r"^\s*#\s*if" # covers ifdef and ifndef as well | |
| endif_pattern = r"^\s*#\s*endif" | |
| while True: | |
| line = yield level | |
| if re.match(ifdef_pattern, line): | |
| level += 1 | |
| elif re.match(endif_pattern, line): | |
| level -= 1 | |
| def limited_gen(): | |
| """ | |
| Scan lines for Py_LIMITED_API yes(1) no(-1) or nothing (0) | |
| """ | |
| limited = [0] # nothing | |
| unlimited_pattern = r"^\s*#\s*ifndef\s+Py_LIMITED_API" | |
| limited_pattern = "|".join([ | |
| r"^\s*#\s*ifdef\s+Py_LIMITED_API", | |
| r"^\s*#\s*(el)?if\s+!\s*defined\s*\(\s*Py_LIMITED_API\s*\)\s*\|\|", | |
| r"^\s*#\s*(el)?if\s+defined\s*\(\s*Py_LIMITED_API" | |
| ]) | |
| else_pattern = r"^\s*#\s*else" | |
| ifdef_level = ifdef_level_gen() | |
| status = next(ifdef_level) | |
| wait_for = -1 | |
| while True: | |
| line = yield limited[-1] | |
| new_status = ifdef_level.send(line) | |
| dir = new_status - status | |
| status = new_status | |
| if dir == 1: | |
| if re.match(unlimited_pattern, line): | |
| limited.append(-1) | |
| wait_for = status - 1 | |
| elif re.match(limited_pattern, line): | |
| limited.append(1) | |
| wait_for = status - 1 | |
| elif dir == -1: | |
| # this must have been an endif | |
| if status == wait_for: | |
| limited.pop() | |
| wait_for = -1 | |
| else: | |
| # it could be that we have an elif | |
| if re.match(limited_pattern, line): | |
| limited.append(1) | |
| wait_for = status - 1 | |
| elif re.match(else_pattern, line): | |
| limited.append(-limited.pop()) # negate top | |
| def parse_file(fname): | |
| errors = 0 | |
| with open(fname) as f: | |
| lines = f.readlines() | |
| type_pattern = r"^.*?->\s*tp_" | |
| define_pattern = r"^\s*#\s*define\s+(\w+)" | |
| limited = limited_gen() | |
| status = next(limited) | |
| for nr, line in enumerate(lines): | |
| status = limited.send(line) | |
| line = line.rstrip() | |
| dprint(fname, nr, status, line) | |
| if status != -1: | |
| if re.match(define_pattern, line): | |
| name = re.match(define_pattern, line).group(1) | |
| if not name.startswith("_"): | |
| # found a candidate, check it! | |
| macro = line + "\n" | |
| idx = nr | |
| while line.endswith("\\"): | |
| idx += 1 | |
| line = lines[idx].rstrip() | |
| macro += line + "\n" | |
| if re.match(type_pattern, macro, re.DOTALL): | |
| # this type field can reach the limited API | |
| report(fname, nr + 1, macro) | |
| errors += 1 | |
| return errors | |
| def report(fname, nr, macro): | |
| f = sys.stderr | |
| print(fname + ":" + str(nr), file=f) | |
| print(macro, file=f) | |
| if __name__ == "__main__": | |
| p = sys.argv[1] if sys.argv[1:] else "../../Include" | |
| errors = parse_headerfiles(p) | |
| if errors: | |
| # somehow it makes sense to raise a TypeError :-) | |
| raise TypeError("These {} locations contradict the limited API." | |
| .format(errors)) | |