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 committed 2026-09-28 18:42:34 +02:00
1 parent da5097abcd
commit 4c73319d3b
5 files changed
+57 -67

No files matched your search

+5 -7
View File
@@ -1,12 +1,10 @@
#!/usr/bin/env python3 #!/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: # Consumes an API snapshot from extract_api.py and checks:
1. Every public callable/type-tier entry has an @sa comment (with exceptions) # 1. Every public callable/type-tier entry has an @sa comment (with exceptions)
2. Every @sa URL resolves to an existing documentation file # 2. Every @sa URL resolves to an existing documentation file
3. No @sa comments appear on non-public entities # 3. No @sa comments appear on non-public entities
"""
import argparse import argparse
import json import json
+9 -11
View File
@@ -1,16 +1,14 @@
#!/usr/bin/env python3 #!/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 # 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 # 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 # 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/, # 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) -- # 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. # no reliable signal exists for that direction given this codebase's conventions.
#
Never blocks CI -- always exits 0, even when it reports findings. # Never blocks CI -- always exits 0, even when it reports findings.
"""
import argparse import argparse
import glob import glob
+19 -21
View File
@@ -1,26 +1,24 @@
#!/usr/bin/env python3 #!/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: # 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 # 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). # 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 # 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/). # 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. # --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, # 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 # 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 # 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() # (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 # 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 # 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 # 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 # 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 # 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 # 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. # refinements verified, by testing against real historical releases -- not by inspecting code alone.
"""
import argparse import argparse
import json import json
+17 -19
View File
@@ -1,24 +1,22 @@
#!/usr/bin/env python3 #!/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, # This tool derives the public API from C++ semantics (class templates, access specifiers,
namespace scoping) independently of documentation status. The extracted surface is the # 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 # source of truth for what is considered "public API" — doc-checking and API diffing are
downstream consumers of this snapshot. # downstream consumers of this snapshot.
#
Strategy: # Strategy:
1. Parse include/nlohmann/json.hpp with libclang (with proper system includes) # 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 # 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 # 3. Extract callable members (methods, constructors, destructors, conversion ops) and type aliases
4. Extract free functions/operators in nlohmann:: (excluding detail::) # 4. Extract free functions/operators in nlohmann:: (excluding detail::)
5. Handle alias-exposed exception types by following the alias to the detail:: definition # 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.) # 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 # 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 # 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). # (entities with @sa comments that are NOT in the public surface — used for validation).
"""
import argparse import argparse
import json import json
+7 -9
View File
@@ -1,14 +1,12 @@
#!/usr/bin/env python3 #!/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: # 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 # 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 # 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 # 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 # 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). # -- regenerate only via --force, and only as a deliberate, reviewed choice).
"""
import argparse import argparse
import datetime import datetime