#!/usr/bin/env python3 """Guard _PyMem_GetCurrentAllocatorName C89 local placement and comparisons.""" import re import sys from pathlib import Path source = Path(sys.argv[1]).read_text() match = re.search( r"_PyMem_GetCurrentAllocatorName\s*\([^)]*\)\s*\{(?P.*?)\n\}", source, re.S, ) assert match, "_PyMem_GetCurrentAllocatorName definition not found" body = match.group("body") expected_declarations = [ "PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC;", "PyMemAllocatorEx pymalloc = PYMALLOC_ALLOC;", "PyMemAllocatorEx dbg_raw = PYDBGRAW_ALLOC;", "PyMemAllocatorEx dbg_mem = PYDBGMEM_ALLOC;", "PyMemAllocatorEx dbg_obj = PYDBGOBJ_ALLOC;", ] positions = [body.find(declaration) for declaration in expected_declarations] assert all(position >= 0 for position in positions), "allocator snapshot declarations must remain present" first_check = body.find("if (pymemallocator_eq") assert first_check >= 0 and positions == sorted(positions) and positions[-1] < first_check, ( "all allocator snapshots must be initialized before the first statement for C89" ) assert body.count("if (pymemallocator_eq(&_PyMem_Raw, &malloc_alloc)") == 2, ( "preserve the malloc and pymalloc base-allocator comparisons" ) assert body.count("if (pymemallocator_eq(&_PyMem_Debug.raw.alloc, &malloc_alloc) &&") == 2, ( "preserve malloc_debug and pymalloc_debug allocator comparisons" ) assert "pymemallocator_eq(&_PyMem_Raw, &dbg_raw)" in body assert "pymemallocator_eq(&_PyMem, &dbg_mem)" in body assert "pymemallocator_eq(&_PyObject, &dbg_obj)" in body assert body.index("/* Debug hooks installed */") < body.index('return "malloc_debug";') assert body.index('return "malloc_debug";') < body.index('return "pymalloc_debug";') assert body.index('return "pymalloc_debug";') < body.index("return NULL;") print("obmalloc allocator-name C89 declarations and allocator classification order: PASS")