25 lines
1.1 KiB
Python
25 lines
1.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Keep type_getattro's local descriptor getter declaration C89-safe."""
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
source = Path(sys.argv[1] if len(sys.argv) > 1 else "cpython/Objects/typeobject.c").read_text()
|
|
match = re.search(r"\ntype_getattro\(PyTypeObject \*type, PyObject \*name\)\n\{(.*?)\n\}", source, re.S)
|
|
assert match, "type_getattro definition missing"
|
|
body = match.group(1)
|
|
block = re.search(r"if \(attribute != NULL\) \{(.*?)\n \}", body, re.S)
|
|
assert block, "type_getattro local attribute block missing"
|
|
assert "descrgetfunc local_get;" in block.group(1), (
|
|
"type_getattro: local_get must be declared in the local attribute block"
|
|
)
|
|
assert block.group(1).index("descrgetfunc local_get;") < block.group(1).index("Py_INCREF(attribute);"), (
|
|
"type_getattro: local_get must be declared before statements in the C89 block"
|
|
)
|
|
assert "local_get = Py_TYPE(attribute)->tp_descr_get;" in block.group(1), (
|
|
"type_getattro: descriptor getter assignment must remain in place"
|
|
)
|
|
assert len(re.findall(r"\bdescrgetfunc\s+local_get\b", body)) == 1, (
|
|
"type_getattro: declare local_get exactly once"
|
|
)
|