40 lines
1.7 KiB
Python
40 lines
1.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Check tracemalloc's positional initializer against its header definition."""
|
|
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
source = Path(sys.argv[1]).read_text()
|
|
header = Path(sys.argv[2]).read_text()
|
|
header = re.sub(r"/\*.*?\*/", "", header, flags=re.S)
|
|
layout = re.search(r"struct _PyTraceMalloc_Config \{(.*?)\n\};", header, re.S)
|
|
assert layout, "_PyTraceMalloc_Config definition not found"
|
|
fields = re.findall(r"\b(\w+)\s*;", layout.group(1))
|
|
assert fields == ["initialized", "tracing", "max_nframe"], (
|
|
"expected initialized, tracing, max_nframe field order"
|
|
)
|
|
macro = re.search(
|
|
r"#define _PyTraceMalloc_Config_INIT\s*\\\s*\{(.*?)\}", header, re.S
|
|
)
|
|
assert macro, "_PyTraceMalloc_Config_INIT definition not found"
|
|
defaults = re.findall(r"\.(\w+)\s*=\s*(\w+)", macro.group(1))
|
|
assert defaults == list(zip(fields, ["TRACEMALLOC_NOT_INITIALIZED", "0", "1"])), (
|
|
"expected uninitialized, tracing disabled, and one traceback frame defaults"
|
|
)
|
|
initializer = re.search(
|
|
r"struct _PyTraceMalloc_Config _Py_tracemalloc_config\s*=\s*(.*?);",
|
|
source,
|
|
re.S,
|
|
)
|
|
assert initializer, "_Py_tracemalloc_config initializer not found"
|
|
body = re.sub(r"/\*.*?\*/", "", initializer.group(1), flags=re.S).strip()
|
|
assert body.startswith("{") and body.endswith("}") and not re.search(
|
|
r"\.\s*\w+\s*=", body
|
|
), "_Py_tracemalloc_config must use a VC6-compatible positional initializer"
|
|
values = [value.strip() for value in body[1:-1].strip().rstrip(",").split(",")]
|
|
assert values == [value for field, value in defaults], (
|
|
"positional initializer must preserve every header default in field order"
|
|
)
|
|
print("obmalloc tracemalloc C89 positional initializer: PASS (initialized=TRACEMALLOC_NOT_INITIALIZED, tracing=0, max_nframe=1)")
|