33 lines
1.4 KiB
Python
33 lines
1.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Check only _PyType_Lookup's cache-update entry declaration and timing."""
|
|
import re
|
|
from pathlib import Path
|
|
|
|
source = (Path(__file__).resolve().parents[1] / "cpython/Objects/typeobject.c").read_text()
|
|
match = re.search(
|
|
r"\n_PyType_Lookup\(PyTypeObject \*type, PyObject \*name\)\n\{(.*?)\n\}",
|
|
source, re.S,
|
|
)
|
|
assert match, "_PyType_Lookup definition missing"
|
|
body = re.sub(r"/\*.*?\*/|//[^\n]*", "", match.group(1), flags=re.S)
|
|
guard = "if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(cache, type)) {"
|
|
assert body.count(guard) == 1, "cache-update block must be unique"
|
|
update = body.split(guard, 1)[1]
|
|
assert re.match(r"\s*struct type_cache_entry \*entry;\s*h =", update), (
|
|
"_PyType_Lookup cache update: entry must precede statements (C89)"
|
|
)
|
|
assert len(re.findall(r"\bstruct type_cache_entry\s*\*entry\b", update)) == 1, (
|
|
"cache update: declare entry exactly once"
|
|
)
|
|
assert len(re.findall(r"\bentry\s*=", update)) == 1, (
|
|
"cache update: initialize entry exactly once"
|
|
)
|
|
assert re.match(
|
|
r"\s*struct type_cache_entry \*entry;"
|
|
r"\s*h = MCACHE_HASH_METHOD\(type, name\);"
|
|
r"\s*entry = &cache->hashtable\[h\];"
|
|
r"\s*entry->version = type->tp_version_tag;"
|
|
r"\s*entry->value = res;", update,
|
|
), "cache update: preserve entry assignment between hash recalculation and writes"
|
|
print("_PyType_Lookup cache-update entry C89 declaration and same-point assignment: PASS")
|