Generate the API reference from the wheel that ships - #22
Merged
Conversation
A reference written by hand beside the code is wrong by the second release, and wrong in the way that costs the most: it looks maintained. So this one is generated, by pdoc, from the installed package, and the release builds it from the wheel it is about to publish rather than from the checkout the wheel came out of. Half of this package is compiled and that is the one thing the inspection cannot see through. `zudb.connect` is a function object pyo3 built, so what pdoc reads off it is `(path, *, read_only=False, ...)` and the types are in `_zudb.pyi`, where the checkers read them. pdoc looks for a stub named after the module it is documenting, which is `zudb`, and the stub is named after the module the names were defined in, which is `zudb._zudb`. So `tools/reference.py` lays the stub where pdoc looks, under the `-stubs` name PEP 561 reserves for it, deriving it rather than writing it: there is no second declaration of the surface to keep in step, and the only edit is the one relative import, which a stub loaded outside the import machinery has no package to resolve. The check on that is the part worth having. Without the overlay ten public signatures lose every annotation, and the reference still builds, still looks finished, and is wrong about every one of them. Nobody reads their own generated docs closely enough to catch it, so the build fails instead, naming the signatures it would have published bare. `tags` now downloads the wheels by name instead of everything the run produced, because the rule it applies is that the directory holds the grid and nothing outside it, and the reference job puts a directory of HTML in the same run.
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.
The
referenceitem of the client scorecard, for this client: a generated API reference, published with the release rather than written by hand beside it.python tools/reference.py <directory>builds every name a reader can import, with its signature and what its docstring says, out of the installed package. The release builds the same pages from the wheel it is about to publish and uploads them, so the pages describe that wheel rather than the checkout it came out of.The one thing an inspection cannot see through
Half of this package is compiled.
zudb.connectis a function object pyo3 built, so what an inspection finds is(path, *, read_only=False, ...)with no type on anything, and the types are in_zudb.pyiwhere the checkers read them. Run the generator without help and it produces a complete reference in which not one signature says what it takes.pdoc looks for a stub named after the module it is documenting, which is
zudb. The stub is named after the module the names were defined in, which iszudb._zudb. So the build derives one from the other:_zudb.pyi, unchanged except that its single relative import is spelled absolutely, written under thezudb-stubsname PEP 561 reserves for a stub distributed apart from its package, and put on the path for as long as the build runs. Derived rather than written, which is the point. There is no second declaration of the public surface to keep in step, and nothing new goes in the wheel.The relative import has to be rewritten because pdoc loads a stub with a loader of its own rather than through
import, so the module has no package to be relative to andfrom .types import Valueraises before anything is read.What fails the build
bare()counts the public names whose signature carries no annotation, and any at all is a failure. That is the check that the overlay is still landing, and it is worth having because the failure it catches is silent: a reference that lost every type still builds, still looks finished, and is wrong about every signature on the page. Nobody reads their own generated docs closely enough to notice.Counting is over the members a namespace declares itself, not everything it answers to.
object.__eq__takes an untypedvalueon every class in the language, andBaseExceptionbrings two more.Release
A
referencejob, from one wheel rather than fourteen. What is being read is the public surface and every wheel in the grid has the same one, so a grid of references would be fourteen copies of one page and thirteen chances to read the wrong one.The
tagsjob now downloads the wheels and the sdist by name instead of taking everything the run produced. Its rule is that the directory holds the grid and nothing outside it, and the reference is a directory of HTML in the same run.