Files
Python3-Win9x/scripts/vc6-bytes-clinic-c89.test.py

36 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""Check C89 declaration placement in generated bytes Clinic wrappers."""
import re
import sys
from pathlib import Path
if len(sys.argv) != 2:
raise SystemExit("usage: vc6-bytes-clinic-c89.test.py bytesobject.c.h")
source = Path(sys.argv[1]).read_text()
checks = {
"bytes_decode(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)": (
"encoding_length", "errors_length"),
"bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)": (
"encoding_length", "errors_length"),
}
for signature, names in checks.items():
start = source.index(signature)
body_start = source.index("\n{\n", start) + 2
body_end = source.index("\n}", body_start)
body = source[body_start:body_end]
unpack = re.search(r"^\s*(?:args|fastargs) = _PyArg_UnpackKeywords", body, re.MULTILINE)
if unpack is None:
raise SystemExit(signature.split("(", 1)[0] + ": argument unpack statement missing")
opening = body[:unpack.start()]
execution = body[unpack.end():]
for name in names:
declaration = "Py_ssize_t " + name + ";"
if opening.count(declaration) != 1 or body.count(declaration) != 1:
raise SystemExit(signature.split("(", 1)[0] + ": " + name + " must be declared once before argument unpacking")
if re.search(r"\bPy_ssize_t\s+" + re.escape(name) + r"\b", execution):
raise SystemExit(signature.split("(", 1)[0] + ": late declaration remains for " + name)
for name in names:
if "&" + name not in execution:
raise SystemExit(signature.split("(", 1)[0] + ": original UTF-8 length use missing for " + name)
print("bytes Clinic C89 declaration placement: PASS")