PEP 727: Documentation Metadata in Typing

I will cover core features this proposal enables that are currently not covered well by docstrings and make standardizing docstring format not enough unless extensions are made.

  • Parameter/attribute level documentation instead of function level documentation. This one does partly exist for docstrings as attribute docstrings are mentioned in an old PEP although at runtime manipulation/extraction of them is not thing.
  • Sharing documentation for same parameter/attribute used in many (dozens/hundreds) of functions/classes.
NameT = Annotated[Optional[str], "The name scope used for any operations made in this layer/context."]

def foo(name: NameT):
  ...

def bar(name: NameT):
  ...

This second point is key benefit I see with this feature. For docstrings to support this they would need some reference/templating mechanism to be defined and standardized.

The first two points do not require that solution be connected to typing/Annotated. Annotated handles them well, but an alternative proposal that allows easy parameter/field sharing I would be happy to see.

Also this PEP being rejected does not mean the feature will not/can not be used. Only that it would become pypi package and libraries could still choose to use it. I’ve already been using Annotated for documentation this way for a couple years in internal codebases. There is no IDE support for it, but even without IDE support, sphinx/documentation generation integration is still doable. And for users of codebase they can click on parameter to jump function definition → click on type annotation to reach Annotated definition with docstring. I think PEP main value is trying to reach agreement on what Annotated documentation should look like for tools to support it. Are there rule clarifications/changes needed to make static analysis more convenient.

Questions of what does Optional[NameT] mean and how should documentation be shown can all be answered. My current implementation looks for Annotated any level nested in type (necessary for ClassVar/Required compatibility as they must be above Annotated) and expects only one documentation string to be found. So Optional[NameT] would just use documentation of NameT while Union[Annotated[int, “doc1”], Annotated[str, “doc2”]] is unsupported/rejected. Rules I use are partly helped by it not being standard/adjust annotations as needed so alternative rule of Annotated can not be nested in Union/must be top level would be fair choices.

edit: I’m neutral on runtime introspection benefits of Annotated vs docstring. I think Annotated is easier for runtime manipulation, but for docstrings if format was defined a linter could validate and enforce it.

edit 2: Regardless PEP being accepted/rejected I think agreement on rules for how Annotated aliases/Union/other types interact is still useful today. If feature goes on to be used as separate pypi package and rules are chosen independently couple years later if static analysis later wants to support it, there will be less ability to change rules. Right now what Union[Annotated[int, …], Annotated[str, …]] is still open thing and there’s little constraint to pick rules that are convenient for both static/runtime usage.

2 Likes