Skip to content

gh-89554: Document standard type objects in types as classes#150676

Open
gaborbernat wants to merge 1 commit into
python:mainfrom
gaborbernat:gh-89554-types-class-roles
Open

gh-89554: Document standard type objects in types as classes#150676
gaborbernat wants to merge 1 commit into
python:mainfrom
gaborbernat:gh-89554-types-class-roles

Conversation

@gaborbernat
Copy link
Copy Markdown
Contributor

@gaborbernat gaborbernat commented May 31, 2026

The types module exposes built-in type objects (FunctionType, LambdaType, MethodType, the descriptor type family, FrameType, CoroutineType, AsyncGeneratorType, and the newer FrameLocalsProxyType / LazyImportType). These are classes, but the documentation marks them with the .. data:: directive, so existing :class: cross-references to them resolve against a missing py:class target and fail. Affected references appear in Doc/c-api/descriptor.rst, Doc/c-api/frame.rst, Doc/c-api/gen.rst, Doc/c-api/structures.rst, Doc/library/inspect.rst, and several Doc/whatsnew/ pages.

This switches those entries to .. class::, matching how UnionType, CapsuleType, CodeType, and ModuleType are already documented in the same file, and updates the few :data: references to :class: so nothing breaks in the other direction.

The singleton-value types NoneType, NotImplementedType, and EllipsisType are handled in a separate PR.

Refs: gh-89554 (reported in 2021; UnionType was fixed then in GH-28757, the remainder left open). Documentation-only change, so no Misc/NEWS entry (skip news).

cc @AA-Turner as the Lib/types.py maintainer.

The type objects exposed by the types module (FunctionType, MethodType,
the descriptor type family, FrameType and others) are classes, but were
documented with the ".. data::" directive. As a result existing
":class:`types.X`" cross-references, such as those in the C API docs for
descriptors, frames, generators and structures, and in inspect and the
What's New pages, fail to resolve against a py:class target.

Switch these entries to ".. class::", matching the existing treatment of
UnionType, CapsuleType, CodeType and ModuleType in the same file, and
update the handful of ":data:" references accordingly so nothing breaks
in the other direction.

The singleton-value types NoneType, NotImplementedType and EllipsisType
are left as ".. data::" for now, since they are referenced as the type of
a singleton value (:data:) and warrant a separate discussion.
@read-the-docs-community
Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #32924395 | 📁 Comparing 3df4894 against main (2f8f569)

  🔍 Preview build  

4 files changed
± howto/a-conceptual-overview-of-asyncio.html
± library/types.html
± whatsnew/3.10.html
± whatsnew/3.15.html

@picnixz
Copy link
Copy Markdown
Member

picnixz commented May 31, 2026

Those are actually real data, not classes. The objects are not defined in those modules, but in C and therefore there is a distinction between them.

@gaborbernat
Copy link
Copy Markdown
Contributor Author

gaborbernat commented Jun 1, 2026

Backward-compatibility check.

  • Across these symbols, downstream nitpick_ignore lists reference them as py:class 8–150× more than py:data (FunctionType 330:39, FrameType 251:8, MethodType 180:17, GeneratorType 152:1), and Sphinx autodoc already emits :py:class: for them via _INVALID_BUILTIN_CLASSES.
  • The only verified independent hand-written :data: reference that would break is SimPy (a :data: reference to types.MethodType in docs/about/defense_of_design.rst).
  • :obj: and autodoc references are unaffected; existing :class: references (for example throughout Doc/c-api/) get fixed.

This resolves more references than it breaks.

@gaborbernat
Copy link
Copy Markdown
Contributor Author

That distinction is real at the implementation level: types re-exports type objects defined in C rather than defining them itself.

The difficulty is that the same file already documents C-defined type objects with .. class::: CodeType, ModuleType, TracebackType, MappingProxyType, GenericAlias, UnionType, and CapsuleType. None of those are defined in types.py either; they are C type objects exposed as names, the same as FunctionType or FrameType. So "defined in C" does not separate the current .. data:: entries from the .. class:: ones. The split that does hold is whether a constructor signature is shown, and UnionType / CapsuleType are .. class:: without one.

The directive also drives cross-referencing rather than provenance. inspect.isclass() is true for all of these, and CPython's own C-API docs already reference them with :class: — for example Doc/c-api/descriptor.rst (GetSetDescriptorType, MemberDescriptorType, MethodDescriptorType, WrapperDescriptorType), Doc/c-api/frame.rst (FrameType), and Doc/c-api/gen.rst (AsyncGeneratorType) — which is why those links do not resolve today. Downstream, Sphinx itself maps these to their types.* name and renders them as classes in _INVALID_BUILTIN_CLASSES, so autodoc emits class references to them regardless of the directive used here. Other projects keep their own copy of that table, for example npdoc2md and quicktile.

What criterion would you want applied? If "type objects re-exported from C should be .. data::", then CodeType / ModuleType / TracebackType / UnionType / CapsuleType fall under it too and should move back for consistency. If "documented as a class when it is a class", the remaining .. data:: entries are the ones out of step. Either way works for me; I would just like the file to end up internally consistent.

@picnixz
Copy link
Copy Markdown
Member

picnixz commented Jun 1, 2026

Urgh ok, let'd use class everywhere. It will solve future issues. It may also solve issues with autodoc in general.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting review docs Documentation in the Doc dir skip news

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants