Skip to content

Commit

Permalink
pythongh-101100: Add a table of class attributes to the "Custom class…
Browse files Browse the repository at this point in the history
…es" section of the data model docs
  • Loading branch information
AlexWaygood committed Sep 25, 2024
1 parent e256a75 commit fd7121a
Show file tree
Hide file tree
Showing 37 changed files with 239 additions and 195 deletions.
2 changes: 1 addition & 1 deletion Doc/c-api/exceptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ Exception Classes
This creates a class object derived from :exc:`Exception` (accessible in C as
:c:data:`PyExc_Exception`).
The :attr:`!__module__` attribute of the new class is set to the first part (up
The :attr:`~class.__module__` attribute of the new class is set to the first part (up
to the last dot) of the *name* argument, and the class name is set to the last
part (after the last dot). The *base* argument can be used to specify alternate
base classes; it can either be only one class or a tuple of classes. The *dict*
Expand Down
2 changes: 1 addition & 1 deletion Doc/c-api/object.rst
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ Object Protocol
If *cls* has a :meth:`~class.__subclasscheck__` method, it will be called to
determine the subclass status as described in :pep:`3119`. Otherwise,
*derived* is a subclass of *cls* if it is a direct or indirect subclass,
i.e. contained in ``cls.__mro__``.
i.e. contained in :attr:`cls.__mro__ <class.__mro__>`.
Normally only class objects, i.e. instances of :class:`type` or a derived
class, are considered classes. However, objects can override this by having
Expand Down
18 changes: 11 additions & 7 deletions Doc/c-api/type.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ Type Objects
.. c:function:: PyObject* PyType_GetDict(PyTypeObject* type)
Return the type object's internal namespace, which is otherwise only
exposed via a read-only proxy (``cls.__dict__``). This is a
exposed via a read-only proxy (:attr:`cls.__dict__ <class.__dict__>`).
This is a
replacement for accessing :c:member:`~PyTypeObject.tp_dict` directly.
The returned dictionary must be treated as read-only.
Expand Down Expand Up @@ -174,29 +175,32 @@ Type Objects
.. c:function:: PyObject* PyType_GetName(PyTypeObject *type)
Return the type's name. Equivalent to getting the type's ``__name__`` attribute.
Return the type's name. Equivalent to getting the type's
:attr:`~class.__name__` attribute.
.. versionadded:: 3.11
.. c:function:: PyObject* PyType_GetQualName(PyTypeObject *type)
Return the type's qualified name. Equivalent to getting the
type's ``__qualname__`` attribute.
type's :attr:`~class.__qualname__` attribute.
.. versionadded:: 3.11
.. c:function:: PyObject* PyType_GetFullyQualifiedName(PyTypeObject *type)
Return the type's fully qualified name. Equivalent to
``f"{type.__module__}.{type.__qualname__}"``, or ``type.__qualname__`` if
``type.__module__`` is not a string or is equal to ``"builtins"``.
``f"{type.__module__}.{type.__qualname__}"``, or
:attr:`type.__qualname__ <class.__qualname__>` if
:attr:`type.__module__ <class.__module__>` is not a string or is equal to
``"builtins"``.
.. versionadded:: 3.13
.. c:function:: PyObject* PyType_GetModuleName(PyTypeObject *type)
Return the type's module name. Equivalent to getting the ``type.__module__``
attribute.
Return the type's module name. Equivalent to getting the
:attr:`type.__module__ <class.__module__>` attribute.
.. versionadded:: 3.13
Expand Down
12 changes: 6 additions & 6 deletions Doc/c-api/typeobj.rst
Original file line number Diff line number Diff line change
Expand Up @@ -567,12 +567,12 @@ and :c:data:`PyType_Type` effectively act as defaults.)

For :ref:`statically allocated type objects <static-types>`,
the *tp_name* field should contain a dot.
Everything before the last dot is made accessible as the :attr:`__module__`
Everything before the last dot is made accessible as the :attr:`~class.__module__`
attribute, and everything after the last dot is made accessible as the
:attr:`~definition.__name__` attribute.
:attr:`~class.__name__` attribute.

If no dot is present, the entire :c:member:`~PyTypeObject.tp_name` field is made accessible as the
:attr:`~definition.__name__` attribute, and the :attr:`__module__` attribute is undefined
:attr:`~class.__name__` attribute, and the :attr:`~class.__module__` attribute is undefined
(unless explicitly set in the dictionary, as explained above). This means your
type will be impossible to pickle. Additionally, it will not be listed in
module documentations created with pydoc.
Expand Down Expand Up @@ -1131,7 +1131,7 @@ and :c:data:`PyType_Type` effectively act as defaults.)

.. c:macro:: Py_TPFLAGS_MANAGED_DICT
This bit indicates that instances of the class have a ``__dict__``
This bit indicates that instances of the class have a `~object.__dict__`
attribute, and that the space for the dictionary is managed by the VM.

If this flag is set, :c:macro:`Py_TPFLAGS_HAVE_GC` should also be set.
Expand Down Expand Up @@ -1335,8 +1335,8 @@ and :c:data:`PyType_Type` effectively act as defaults.)
.. c:member:: const char* PyTypeObject.tp_doc
An optional pointer to a NUL-terminated C string giving the docstring for this
type object. This is exposed as the :attr:`__doc__` attribute on the type and
instances of the type.
type object. This is exposed as the :attr:`~class.__doc__` attribute on the
type and instances of the type.

**Inheritance:**

Expand Down
2 changes: 1 addition & 1 deletion Doc/extending/newtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ An interesting advantage of using the :c:member:`~PyTypeObject.tp_members` table
descriptors that are used at runtime is that any attribute defined this way can
have an associated doc string simply by providing the text in the table. An
application can use the introspection API to retrieve the descriptor from the
class object, and get the doc string using its :attr:`!__doc__` attribute.
class object, and get the doc string using its :attr:`~class.__doc__` attribute.

As with the :c:member:`~PyTypeObject.tp_methods` table, a sentinel entry with a :c:member:`~PyMethodDef.ml_name` value
of ``NULL`` is required.
Expand Down
2 changes: 1 addition & 1 deletion Doc/faq/programming.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1614,7 +1614,7 @@ method too, and it must do so carefully. The basic implementation of
...

Most :meth:`!__setattr__` implementations must modify
:meth:`self.__dict__ <object.__dict__>` to store
:attr:`self.__dict__ <object.__dict__>` to store
local state for self without causing an infinite recursion.


Expand Down
2 changes: 1 addition & 1 deletion Doc/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ Glossary
docstring
A string literal which appears as the first expression in a class,
function or module. While ignored when the suite is executed, it is
recognized by the compiler and put into the :attr:`!__doc__` attribute
recognized by the compiler and put into the :attr:`~definition.__doc__` attribute
of the enclosing class, function or module. Since it is available via
introspection, it is the canonical place for documentation of the
object.
Expand Down
11 changes: 6 additions & 5 deletions Doc/howto/annotations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ Your code will have to have a separate code path if the object
you're examining is a class (``isinstance(o, type)``).
In that case, best practice relies on an implementation detail
of Python 3.9 and before: if a class has annotations defined,
they are stored in the class's ``__dict__`` dictionary. Since
they are stored in the class's :attr:`~class.__dict__` dictionary. Since
the class may or may not have annotations defined, best practice
is to call the ``get`` method on the class dict.
is to call the :meth:`~dict.get` method on the class dict.

To put it all together, here is some sample code that safely
accesses the ``__annotations__`` attribute on an arbitrary
Expand All @@ -126,8 +126,8 @@ the type of ``ann`` using :func:`isinstance` before further
examination.

Note that some exotic or malformed type objects may not have
a ``__dict__`` attribute, so for extra safety you may also wish
to use :func:`getattr` to access ``__dict__``.
a :attr:`~class.__dict__` attribute, so for extra safety you may also wish
to use :func:`getattr` to access :attr:`!__dict__`.


Manually Un-Stringizing Stringized Annotations
Expand Down Expand Up @@ -247,4 +247,5 @@ on the class, you may observe unexpected behavior; see
quirks by using :func:`annotationlib.get_annotations` on Python 3.14+ or
:func:`inspect.get_annotations` on Python 3.10+. On earlier versions of
Python, you can avoid these bugs by accessing the annotations from the
class's ``__dict__`` (e.g., ``cls.__dict__.get('__annotations__', None)``).
class's :attr:`~class.__dict__`
(e.g., ``cls.__dict__.get('__annotations__', None)``).
4 changes: 2 additions & 2 deletions Doc/howto/descriptor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,8 @@ attribute access.

The expression ``obj.x`` looks up the attribute ``x`` in the chain of
namespaces for ``obj``. If the search finds a descriptor outside of the
instance ``__dict__``, its :meth:`__get__` method is invoked according to the
precedence rules listed below.
instance :attr:`~object.__dict__`, its :meth:`~object.__get__` method is
invoked according to the precedence rules listed below.

The details of invocation depend on whether ``obj`` is an object, class, or
instance of super.
Expand Down
2 changes: 1 addition & 1 deletion Doc/howto/enum.rst
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ The solution is to specify the module name explicitly as follows::
the source, pickling will be disabled.

The new pickle protocol 4 also, in some circumstances, relies on
:attr:`~definition.__qualname__` being set to the location where pickle will be able
:attr:`~class.__qualname__` being set to the location where pickle will be able
to find the class. For example, if the class was made available in class
SomeData in the global scope::

Expand Down
2 changes: 1 addition & 1 deletion Doc/howto/mro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ E is more specialized than C, even if it is in a higher level.

A lazy programmer can obtain the MRO directly from Python 2.2, since in
this case it coincides with the Python 2.3 linearization. It is enough
to invoke the .mro() method of class A:
to invoke the :meth:`~class.mro` method of class A:

>>> A.mro() # doctest: +NORMALIZE_WHITESPACE
[<class 'A'>, <class 'B'>, <class 'E'>,
Expand Down
4 changes: 2 additions & 2 deletions Doc/library/collections.rst
Original file line number Diff line number Diff line change
Expand Up @@ -874,8 +874,8 @@ they add the ability to access fields by name instead of position index.
``(1, 2)``, then ``x`` will be a required argument, ``y`` will default to
``1``, and ``z`` will default to ``2``.

If *module* is defined, the ``__module__`` attribute of the named tuple is
set to that value.
If *module* is defined, the :attr:`~class.__module__` attribute of the
named tuple is set to that value.

Named tuple instances do not have per-instance dictionaries, so they are
lightweight and require no more memory than regular tuples.
Expand Down
7 changes: 4 additions & 3 deletions Doc/library/email.contentmanager.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,12 @@
* the type itself (``typ``)
* the type's fully qualified name (``typ.__module__ + '.' +
typ.__qualname__``).
* the type's qualname (``typ.__qualname__``)
* the type's name (``typ.__name__``).
* the type's :attr:`qualname <class.__qualname__>` (``typ.__qualname__``)
* the type's :attr:`name <class.__name__>` (``typ.__name__``).

If none of the above match, repeat all of the checks above for each of
the types in the :term:`MRO` (``typ.__mro__``). Finally, if no other key
the types in the :term:`MRO` (:attr:`typ.__mro__ <class.__mro__>`).
Finally, if no other key
yields a handler, check for a handler for the key ``None``. If there is
no handler for ``None``, raise a :exc:`KeyError` for the fully
qualified name of the type.
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/email.headerregistry.rst
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ variant, :attr:`~.BaseHeader.max_count` is set to 1.
class. When *use_default_map* is ``True`` (the default), the standard
mapping of header names to classes is copied in to the registry during
initialization. *base_class* is always the last class in the generated
class's ``__bases__`` list.
class's :class:`~class.__bases__` list.

The default mappings are:

Expand Down
31 changes: 17 additions & 14 deletions Doc/library/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,11 @@ are always available. They are listed here in alphabetical order.
:func:`property`.

.. versionchanged:: 3.10
Class methods now inherit the method attributes (``__module__``,
``__name__``, ``__qualname__``, ``__doc__`` and ``__annotations__``) and
have a new ``__wrapped__`` attribute.
Class methods now inherit the method attributes
(:attr:`~function.__module__`, :attr:`~function.__name__`,
:attr:`~function.__qualname__`, :attr:`~function.__doc__` and
:attr:`~function.__annotations__`) and have a new ``__wrapped__``
attribute.

.. deprecated-removed:: 3.11 3.13
Class methods can no longer wrap other :term:`descriptors <descriptor>` such as
Expand Down Expand Up @@ -1286,8 +1288,9 @@ are always available. They are listed here in alphabetical order.

.. note::

:class:`object` does *not* have a :attr:`~object.__dict__`, so you can't
assign arbitrary attributes to an instance of the :class:`object` class.
:class:`object` instances do *not* have :attr:`~object.__dict__`
attributes, so you can't assign arbitrary attributes to an instance of
:class:`object`.


.. function:: oct(x)
Expand Down Expand Up @@ -1907,10 +1910,11 @@ are always available. They are listed here in alphabetical order.
For more information on static methods, see :ref:`types`.

.. versionchanged:: 3.10
Static methods now inherit the method attributes (``__module__``,
``__name__``, ``__qualname__``, ``__doc__`` and ``__annotations__``),
have a new ``__wrapped__`` attribute, and are now callable as regular
functions.
Static methods now inherit the method attributes
(:attr:`~function.__module__`, :attr:`~function.__name__`,
:attr:`~function.__qualname__`, :attr:`~function.__doc__` and
:attr:`~function.__annotations__`), have a new ``__wrapped__`` attribute,
and are now callable as regular functions.


.. index::
Expand Down Expand Up @@ -2049,15 +2053,14 @@ are always available. They are listed here in alphabetical order.
The :func:`isinstance` built-in function is recommended for testing the type
of an object, because it takes subclasses into account.


With three arguments, return a new type object. This is essentially a
dynamic form of the :keyword:`class` statement. The *name* string is
the class name and becomes the :attr:`~definition.__name__` attribute.
the class name and becomes the :attr:`~class.__name__` attribute.
The *bases* tuple contains the base classes and becomes the
:attr:`~class.__bases__` attribute; if empty, :class:`object`, the
ultimate base of all classes, is added. The *dict* dictionary contains
attribute and method definitions for the class body; it may be copied
or wrapped before becoming the :attr:`~object.__dict__` attribute.
or wrapped before becoming the :attr:`~class.__dict__` attribute.
The following two statements create identical :class:`type` objects:

>>> class X:
Expand All @@ -2082,11 +2085,11 @@ are always available. They are listed here in alphabetical order.
vars(object)

Return the :attr:`~object.__dict__` attribute for a module, class, instance,
or any other object with a :attr:`~object.__dict__` attribute.
or any other object with a :attr:`!__dict__` attribute.

Objects such as modules and instances have an updateable :attr:`~object.__dict__`
attribute; however, other objects may have write restrictions on their
:attr:`~object.__dict__` attributes (for example, classes use a
:attr:`!__dict__` attributes (for example, classes use a
:class:`types.MappingProxyType` to prevent direct dictionary updates).

Without an argument, :func:`vars` acts like :func:`locals`.
Expand Down
16 changes: 9 additions & 7 deletions Doc/library/functools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -646,10 +646,11 @@ The :mod:`functools` module defines the following functions:
attributes of the wrapper function are updated with the corresponding attributes
from the original function. The default values for these arguments are the
module level constants ``WRAPPER_ASSIGNMENTS`` (which assigns to the wrapper
function's ``__module__``, ``__name__``, ``__qualname__``, ``__annotations__``,
``__type_params__``, and ``__doc__``, the documentation string)
and ``WRAPPER_UPDATES`` (which
updates the wrapper function's ``__dict__``, i.e. the instance dictionary).
function's :attr:`~function.__module__`, :attr:`~function.__name__`,
:attr:`~function.__qualname__`, :attr:`~function.__annotations__`,
:attr:`~function.__type_params__`, and :attr:`~function.__doc__`, the
documentation string) and ``WRAPPER_UPDATES`` (which updates the wrapper
function's :attr:`~function.__dict__`, i.e. the instance dictionary).

To allow access to the original function for introspection and other purposes
(e.g. bypassing a caching decorator such as :func:`lru_cache`), this function
Expand All @@ -670,7 +671,7 @@ The :mod:`functools` module defines the following functions:

.. versionchanged:: 3.2
The ``__wrapped__`` attribute is now automatically added.
The ``__annotations__`` attribute is now copied by default.
The :attr:`~function.__annotations__` attribute is now copied by default.
Missing attributes no longer trigger an :exc:`AttributeError`.

.. versionchanged:: 3.4
Expand All @@ -679,7 +680,7 @@ The :mod:`functools` module defines the following functions:
(see :issue:`17482`)

.. versionchanged:: 3.12
The ``__type_params__`` attribute is now copied by default.
The :attr:`~function.__type_params__` attribute is now copied by default.


.. decorator:: wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
Expand Down Expand Up @@ -743,7 +744,8 @@ have three read-only attributes:

:class:`partial` objects are like :class:`function` objects in that they are
callable, weak referenceable, and can have attributes. There are some important
differences. For instance, the :attr:`~definition.__name__` and :attr:`__doc__` attributes
differences. For instance, the :attr:`~function.__name__` and
:attr:`function.__doc__` attributes
are not created automatically. Also, :class:`partial` objects defined in
classes behave like static methods and do not transform into bound methods
during instance attribute look-up.
2 changes: 1 addition & 1 deletion Doc/library/inspect.rst
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
has a :meth:`~object.__get__` method, but not a :meth:`~object.__set__`
method or a :meth:`~object.__delete__` method. Beyond that, the set of
attributes varies. A :attr:`~definition.__name__` attribute is usually
sensible, and :attr:`!__doc__` often is.
sensible, and :attr:`~definition.__doc__` often is.

Methods implemented via descriptors that also pass one of the other tests
return ``False`` from the :func:`ismethoddescriptor` test, simply because the
Expand Down
3 changes: 2 additions & 1 deletion Doc/library/logging.rst
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,8 @@ in a module, ``__name__`` is the module's name in the Python package namespace.
parameter mirrors the equivalent one in the :mod:`warnings` module.

The fourth keyword argument is *extra* which can be used to pass a
dictionary which is used to populate the __dict__ of the :class:`LogRecord`
dictionary which is used to populate the :attr:`~object.__dict__` of the
:class:`LogRecord`
created for the logging event with user-defined attributes. These custom
attributes can then be used as you like. For example, they could be
incorporated into logged messages. For example::
Expand Down
2 changes: 1 addition & 1 deletion Doc/library/pydoc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ modules. The documentation can be presented as pages of text on the console,
served to a web browser, or saved to HTML files.

For modules, classes, functions and methods, the displayed documentation is
derived from the docstring (i.e. the :attr:`!__doc__` attribute) of the object,
derived from the docstring (i.e. the :attr:`~definition.__doc__` attribute) of the object,
and recursively of its documentable members. If there is no docstring,
:mod:`!pydoc` tries to obtain a description from the block of comment lines just
above the definition of the class, function or method in the source file, or at
Expand Down
Loading

0 comments on commit fd7121a

Please sign in to comment.