feat: render a property's description as an attribute docstring - #11
Merged
Conversation
A schema's `description` became a class docstring, but a property's went nowhere: the IR carried it and every serializer dropped it, so prose the spec author wrote for a field was invisible in the generated client. Emit it as a PEP 258 attribute docstring under the field. That is the device the method classes already use for parameters and body fields, and it is the only one that renders identically for all three serializers: pydantic would otherwise need `Field(description=...)` on every documented field, msgspec an `Annotated[..., Meta(description=...)]`, and adaptix has no equivalent at all. It is also inert -- the class body just evaluates a string -- so constructors, decoding, and the emitted JSON schema are untouched, while editors show the prose on hover. Wrapping, embedded quotes, and backslashes are handled by the existing `docstring` helper, so a raw string is used where the prose needs one. The committed example libraries are regenerated. Most of that diff predates this change: they were already stale by 31 lines' worth of method-parameter docstrings from an earlier release. The 5 lines under `models/` are this one.
The unit tests import the rendered module, which proves an attribute docstring is inert, but nothing ran ruff or mypy over one: neither compile-gate fixture had a property with prose. The wrapping width the docstring helper targets is ruff's, so the one gate that would catch a regression was the one not looking. Give the sample spec a described property, long enough to wrap and carrying embedded quotes, so every gate combination -- three serializers, both file layouts, and the stubs pass -- checks the rendered prose. Also drop the unused ``indent`` parameter from ``field_doc_lines``: every strategy renders at the class-body indent, and nothing passed anything else.
goduni
force-pushed
the
feat/field-docstrings
branch
from
August 17, 2026 00:19
7cffe06 to
8aeba77
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #11 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 31 31
Lines 2726 2735 +9
=========================================
+ Hits 2726 2735 +9 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
A schema's
descriptionbecame a class docstring, but a property's went nowhere: the IRcarried it and every serializer dropped it. Prose the spec author wrote for a field was
invisible in the generated client.
It is now emitted as a PEP 258 attribute docstring under the field:
Why this device and not the native ones:
halves of a generated package read the same way;
Field(description=...)on every documented field, msgspec anAnnotated[..., Meta(description=...)], and adaptix has no equivalent at all;decoding, and the emitted JSON schema are unchanged. Editors show it on hover.
Wrapping, embedded quotes, and backslashes are handled by the existing
docstringhelper, which already switches to a raw string when the prose contains a backslash.
Relation to #10
Independent, and they compose: #10 keeps a subtype's explicit re-declaration (and its
prose) in the IR, this one puts that prose in the output. Both touch the field loop in
the three
render_modelmethods, so whichever merges second has a one-line conflict perserializer.
Type of change
Verification
uv run pytest --cov src --cov-fail-under=80 --cov-report=term— 328 passed, 100% coverageuv run ruff checkuv run ruff format --checkuv run mypyregen.sh, each passing its ownruff check --isolated+mypy --strictgateNote on the examples diff
The committed example libraries are regenerated here, and most of that diff predates this
change: they were already stale by 31 lines' worth of method-parameter docstrings from an
earlier release. The 5 lines under
models/are this change.Checklist
uv run mypy