Use one-line module docstrings in the API checker scripts

Codacy runs two docstring checkers with opposite rules for module
docstrings: with the summary on the first line it reported D213, with
the summary on the second line it reports D212. A one-line docstring
satisfies both. Keep the summary as the docstring and move the details
into a comment below it; nothing reads the module docstrings.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-09-28 18:42:34 +02:00
parent da5097abcd
commit 4c73319d3b
5 changed files with 57 additions and 67 deletions
+5 -7
View File
@@ -1,12 +1,10 @@
#!/usr/bin/env python3
"""
Verify that public API entries have documentation links.
"""Verify that public API entries have documentation links."""
Consumes an API snapshot from extract_api.py and checks:
1. Every public callable/type-tier entry has an @sa comment (with exceptions)
2. Every @sa URL resolves to an existing documentation file
3. No @sa comments appear on non-public entities
"""
# Consumes an API snapshot from extract_api.py and checks:
# 1. Every public callable/type-tier entry has an @sa comment (with exceptions)
# 2. Every @sa URL resolves to an existing documentation file
# 3. No @sa comments appear on non-public entities
import argparse
import json
+9 -11
View File
@@ -1,16 +1,14 @@
#!/usr/bin/env python3
"""
Advisory-only cross-check between documented macros and their #define sites.
"""Advisory-only cross-check between documented macros and their #define sites."""
Macros have no C++ access-specifier concept, so the AST-based public/private test that
extract_api.py uses for classes doesn't transfer -- see tools/api_checker/POLICY.md's "Known
limitations" section. This script only checks one direction: that every macro documented under
docs/mkdocs/docs/api/macros/ still has a matching #define somewhere under include/nlohmann/,
catching stale or renamed doc pages. It does NOT check the converse (undocumented macros) --
no reliable signal exists for that direction given this codebase's conventions.
Never blocks CI -- always exits 0, even when it reports findings.
"""
# Macros have no C++ access-specifier concept, so the AST-based public/private test that
# extract_api.py uses for classes doesn't transfer -- see tools/api_checker/POLICY.md's "Known
# limitations" section. This script only checks one direction: that every macro documented under
# docs/mkdocs/docs/api/macros/ still has a matching #define somewhere under include/nlohmann/,
# catching stale or renamed doc pages. It does NOT check the converse (undocumented macros) --
# no reliable signal exists for that direction given this codebase's conventions.
#
# Never blocks CI -- always exits 0, even when it reports findings.
import argparse
import glob
+19 -21
View File
@@ -1,26 +1,24 @@
#!/usr/bin/env python3
"""
Diff the public API surface between two refs to flag breaking vs. feature changes.
"""Diff the public API surface between two refs to flag breaking vs. feature changes."""
A "ref" for --old/--new is resolved in this order:
1. A stored, committed historical record at tools/api_checker/history/<ref>.json, if one exists
and --no-history wasn't passed (fast path -- no libclang/git-archive needed).
2. Live extraction: check the ref out via `git archive` into a temp dir and run extract_api.py
against it (needed for HEAD, branches, or any tag not yet backfilled into history/).
--old-file/--new-file bypass both and load an arbitrary surface JSON file directly.
Uses extract_api.py's --surface-output (identity-only: scope, kind, name, identity_name, tier,
signature, pretty_signature -- no location, no doc_url) for both sides, so the diff reflects only
genuine API changes, never unrelated code motion or documentation-site restructuring. Identity is
(scope, identity_name, kind, signature) -- see extract_api.py's identity_key()/get_signature_text()
docstrings for the full history of why this is what it is: a naive {scope,name,kind,params} key
silently collided on overloads differing only by constness/SFINAE; switching to libclang's USR
fixed that but encoded the *enclosing class template's own arity* into every member's identity, so
a single backward-compatible template-parameter addition (confirmed via real release tags
v3.11.2->v3.11.3) made ~228 of 330 entries look "changed" for a release with no real breaking
changes. The current raw-source-text-signature approach was arrived at, and each of several further
refinements verified, by testing against real historical releases -- not by inspecting code alone.
"""
# A "ref" for --old/--new is resolved in this order:
# 1. A stored, committed historical record at tools/api_checker/history/<ref>.json, if one exists
# and --no-history wasn't passed (fast path -- no libclang/git-archive needed).
# 2. Live extraction: check the ref out via `git archive` into a temp dir and run extract_api.py
# against it (needed for HEAD, branches, or any tag not yet backfilled into history/).
# --old-file/--new-file bypass both and load an arbitrary surface JSON file directly.
#
# Uses extract_api.py's --surface-output (identity-only: scope, kind, name, identity_name, tier,
# signature, pretty_signature -- no location, no doc_url) for both sides, so the diff reflects only
# genuine API changes, never unrelated code motion or documentation-site restructuring. Identity is
# (scope, identity_name, kind, signature) -- see extract_api.py's identity_key()/get_signature_text()
# docstrings for the full history of why this is what it is: a naive {scope,name,kind,params} key
# silently collided on overloads differing only by constness/SFINAE; switching to libclang's USR
# fixed that but encoded the *enclosing class template's own arity* into every member's identity, so
# a single backward-compatible template-parameter addition (confirmed via real release tags
# v3.11.2->v3.11.3) made ~228 of 330 entries look "changed" for a release with no real breaking
# changes. The current raw-source-text-signature approach was arrived at, and each of several further
# refinements verified, by testing against real historical releases -- not by inspecting code alone.
import argparse
import json
+17 -19
View File
@@ -1,24 +1,22 @@
#!/usr/bin/env python3
"""
Extract the public API surface of nlohmann/json using libclang AST.
"""Extract the public API surface of nlohmann/json using libclang AST."""
This tool derives the public API from C++ semantics (class templates, access specifiers,
namespace scoping) independently of documentation status. The extracted surface is the
source of truth for what is considered "public API" — doc-checking and API diffing are
downstream consumers of this snapshot.
Strategy:
1. Parse include/nlohmann/json.hpp with libclang (with proper system includes)
2. Walk the primary class-template definitions of the 6 known public classes
3. Extract callable members (methods, constructors, destructors, conversion ops) and type aliases
4. Extract free functions/operators in nlohmann:: (excluding detail::)
5. Handle alias-exposed exception types by following the alias to the detail:: definition
6. Normalize away the ABI inline-namespace (json_abi_v3_12_0, json_abi_diag_v3_12_0, etc.)
7. Emit a snapshot with an overload-disambiguating identity key and documentation status
Output includes both public_api (all tracked public entities) and documented_non_public
(entities with @sa comments that are NOT in the public surface — used for validation).
"""
# This tool derives the public API from C++ semantics (class templates, access specifiers,
# namespace scoping) independently of documentation status. The extracted surface is the
# source of truth for what is considered "public API" — doc-checking and API diffing are
# downstream consumers of this snapshot.
#
# Strategy:
# 1. Parse include/nlohmann/json.hpp with libclang (with proper system includes)
# 2. Walk the primary class-template definitions of the 6 known public classes
# 3. Extract callable members (methods, constructors, destructors, conversion ops) and type aliases
# 4. Extract free functions/operators in nlohmann:: (excluding detail::)
# 5. Handle alias-exposed exception types by following the alias to the detail:: definition
# 6. Normalize away the ABI inline-namespace (json_abi_v3_12_0, json_abi_diag_v3_12_0, etc.)
# 7. Emit a snapshot with an overload-disambiguating identity key and documentation status
#
# Output includes both public_api (all tracked public entities) and documented_non_public
# (entities with @sa comments that are NOT in the public surface — used for validation).
import argparse
import json
+7 -9
View File
@@ -1,14 +1,12 @@
#!/usr/bin/env python3
"""
Capture immutable, per-release API surface records into tools/api_checker/history/.
"""Capture immutable, per-release API surface records into tools/api_checker/history/."""
These are the durable, committed counterpart to diff_api.py's live git-archive-and-extract path:
once a release is tagged, run this once to capture tools/api_checker/history/<tag>.json, commit
it, and future diffs against that tag hit the fast, no-libclang-needed stored-file path in
diff_api.py automatically. See tools/api_checker/README.md's "Workflow: Release Checklist" and
POLICY.md for the full policy (manual step, not CI-automated; files are immutable once committed
-- regenerate only via --force, and only as a deliberate, reviewed choice).
"""
# These are the durable, committed counterpart to diff_api.py's live git-archive-and-extract path:
# once a release is tagged, run this once to capture tools/api_checker/history/<tag>.json, commit
# it, and future diffs against that tag hit the fast, no-libclang-needed stored-file path in
# diff_api.py automatically. See tools/api_checker/README.md's "Workflow: Release Checklist" and
# POLICY.md for the full policy (manual step, not CI-automated; files are immutable once committed
# -- regenerate only via --force, and only as a deliberate, reviewed choice).
import argparse
import datetime