#!/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" )