Fix cross-environment API-surface drift and lint findings from CI

extract_api.py's own extraction wasn't deterministic across machines, which
CI's drift check caught immediately: JSON_HAS_RANGES auto-detects via the
standard library's __cpp_lib_ranges feature-test macro, which isn't reliably
gated to C++20 mode by every stdlib -- undefined under -std=c++17 with macOS's
libc++, but defined under the identical flag with the Ubuntu stdlib CI uses,
so parse()/accept()/from_*() extracted different signatures purely depending
on which machine ran the extraction. Pinned to -DJSON_HAS_RANGES=0: the
deterministic and safe choice, since pinning to 1 was tried first and found to
fail to parse on a stdlib without full <ranges> support even when the macro
claims otherwise.

Also found and fixed a second, independent source of the same class of drift:
get_identity_name() used cursor.spelling verbatim for CONVERSION_FUNCTION
cursors, which libclang renders as its own internally-canonicalized form of
the return type rather than what's literally written. Confirmed for
json_pointer::operator string_t() spelling differently on two machines
pinned to the identical libclang==18.1.1 wheel, with the JSON_HAS_RANGES fix
above ruled out as the cause. Now derived from the cursor's own raw source
text instead, immune to libclang's dependent-type resolution differences and
incidentally more readable than the libclang-internal forms it replaces.

Bumped SURFACE_FORMAT_VERSION to 3 and regenerated all 27 history snapshots
and the committed api_surface.json; both fixes are documented in
tools/api_checker/history/README.md's format-history log.

Also fixes diff_api.py's format_version guard, which only compared the two
loaded surfaces against each other and never against SURFACE_FORMAT_VERSION
(what this build actually understands) -- two surfaces on the same,
newer-than-expected format_version would have silently passed the guard.

Remaining fixes are the concretely actionable findings from Codacy's review
of the new tools/api_checker/ files: unused imports/variables, a stray
f-string with no placeholders. Left the docstring-formatting nitpicks
(pydocstyle D2xx/D4xx) and generic subprocess-usage notices alone -- the
former has no established convention elsewhere in this codebase's Python
tooling to conform to, and the latter are inherent to a dev tool that shells
out to git/clang with developer-controlled arguments, not user input.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-07-11 18:59:19 +02:00
parent f23b3c63a2
commit 0663907b68
33 changed files with 227 additions and 160 deletions
+12 -5
View File
@@ -214,7 +214,7 @@ def print_diff(diff: dict, old_desc: str, new_desc: str) -> bool:
breaking = bool(diff['removed'] or diff['changed'])
if breaking:
print(f"\nWARNING: Potential BREAKING CHANGES detected:")
print("\nWARNING: Potential BREAKING CHANGES detected:")
print(f" - {len(diff['removed'])} removed entries")
print(f" - {len(diff['changed'])} changed overloads")
if diff['added']:
@@ -264,13 +264,20 @@ def main():
old_fmt = old_surface.get('format_version')
new_fmt = new_surface.get('format_version')
if old_fmt != new_fmt and not args.allow_format_mismatch:
print(f"Error: format_version mismatch ({old_desc}: {old_fmt!r} vs {new_desc}: {new_fmt!r}).")
# Check both surfaces against SURFACE_FORMAT_VERSION (what *this build* of diff_api.py
# understands), not just against each other: two surfaces on the same format_version could
# still both be on a version this build predates and doesn't correctly interpret.
mismatched = old_fmt != SURFACE_FORMAT_VERSION or new_fmt != SURFACE_FORMAT_VERSION
if mismatched and not args.allow_format_mismatch:
print(f"Error: format_version mismatch. This build of diff_api.py understands "
f"format_version {SURFACE_FORMAT_VERSION!r}, but {old_desc} is {old_fmt!r} and "
f"{new_desc} is {new_fmt!r}.")
print("The identity/signature algorithm may differ between these two surfaces, making a diff unsound.")
print("Re-run with --allow-format-mismatch to proceed anyway.")
sys.exit(1)
elif old_fmt != new_fmt:
print(f"WARNING: proceeding with mismatched format_version ({old_fmt!r} vs {new_fmt!r}) as requested.")
elif mismatched:
print(f"WARNING: proceeding with mismatched format_version (this build understands "
f"{SURFACE_FORMAT_VERSION!r}; {old_desc}={old_fmt!r}, {new_desc}={new_fmt!r}) as requested.")
old_api = build_identity_dict(old_surface['public_api'])
new_api = build_identity_dict(new_surface['public_api'])