#!/usr/bin/env python3 """Guard slice_richcompare C89 locals and allocation/refcount order.""" import re import sys from pathlib import Path source = Path(sys.argv[1] if len(sys.argv) > 1 else "cpython/Objects/sliceobject.c") match = re.search( r"\nslice_richcompare\(PyObject \*v, PyObject \*w, int op\)\s*\{(.*?)\n\}", source.read_text(), re.S, ) assert match, "slice_richcompare definition not found" body = re.sub(r"/\*.*?\*/", "", match.group(1), flags=re.S) declarations = re.match( r"\s*PyObject \*t1;\s*PyObject \*t2;\s*PyObject \*res;", body ) assert declarations, "slice_richcompare must declare t1, t2, res without initializers at function entry" expected_statements = """ if (!PySlice_Check(v) || !PySlice_Check(w)) Py_RETURN_NOTIMPLEMENTED; if (v == w) { switch (op) { case Py_EQ: case Py_LE: case Py_GE: res = Py_True; break; default: res = Py_False; break; } Py_INCREF(res); return res; } t1 = PyTuple_Pack(3, ((PySliceObject *)v)->start, ((PySliceObject *)v)->stop, ((PySliceObject *)v)->step); if (t1 == NULL) { return NULL; } t2 = PyTuple_Pack(3, ((PySliceObject *)w)->start, ((PySliceObject *)w)->stop, ((PySliceObject *)w)->step); if (t2 == NULL) { Py_DECREF(t1); return NULL; } res = PyObject_RichCompare(t1, t2, op); Py_DECREF(t1); Py_DECREF(t2); return res; """ assert body[declarations.end():].split() == expected_statements.split(), ( "slice_richcompare must preserve shortcut/allocation/failure/comparison/refcount order without late declarations" ) print("slice_richcompare C89 declarations and allocation/refcount order: PASS")