From c0521fe49fd75e794a38a216813658ab40185834 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 5 Dec 2021 20:49:36 +0000 Subject: [PATCH] bpo-45840: Improve cross-references in the data model documentation (GH-29633) --- Doc/reference/datamodel.rst | 130 ++++++++++-------- .../2021-11-19-02-02-32.bpo-45840.A51B2S.rst | 1 + 2 files changed, 77 insertions(+), 54 deletions(-) create mode 100644 Misc/NEWS.d/next/Documentation/2021-11-19-02-02-32.bpo-45840.A51B2S.rst diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 41092458102..597c8ec9f17 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -188,7 +188,7 @@ Ellipsis representation in computers. The string representations of the numeric classes, computed by - :meth:`__repr__` and :meth:`__str__`, have the following + :meth:`~object.__repr__` and :meth:`~object.__str__`, have the following properties: * They are valid numeric literals which, when passed to their @@ -677,7 +677,8 @@ Callable types returns an :term:`asynchronous iterator` object which can be used in an :keyword:`async for` statement to execute the body of the function. - Calling the asynchronous iterator's :meth:`aiterator.__anext__` method + Calling the asynchronous iterator's + :meth:`aiterator.__anext__ ` method will return an :term:`awaitable` which when awaited will execute until it provides a value using the :keyword:`yield` expression. When the function executes an empty :keyword:`return` @@ -715,13 +716,13 @@ Callable types Classes Classes are callable. These objects normally act as factories for new instances of themselves, but variations are possible for class types that - override :meth:`__new__`. The arguments of the call are passed to - :meth:`__new__` and, in the typical case, to :meth:`__init__` to + override :meth:`~object.__new__`. The arguments of the call are passed to + :meth:`__new__` and, in the typical case, to :meth:`~object.__init__` to initialize the new instance. Class Instances Instances of arbitrary classes can be made callable by defining a - :meth:`__call__` method in their class. + :meth:`~object.__call__` method in their class. Modules @@ -880,14 +881,14 @@ Class instances section :ref:`descriptors` for another way in which attributes of a class retrieved via its instances may differ from the objects actually stored in the class's :attr:`~object.__dict__`. If no class attribute is found, and the - object's class has a :meth:`__getattr__` method, that is called to satisfy + object's class has a :meth:`~object.__getattr__` method, that is called to satisfy the lookup. .. index:: triple: class instance; attribute; assignment Attribute assignments and deletions update the instance's dictionary, never a - class's dictionary. If the class has a :meth:`__setattr__` or - :meth:`__delattr__` method, this is called instead of updating the instance + class's dictionary. If the class has a :meth:`~object.__setattr__` or + :meth:`~object.__delattr__` method, this is called instead of updating the instance dictionary directly. .. index:: @@ -1176,7 +1177,8 @@ Internal types Slice objects .. index:: builtin: slice - Slice objects are used to represent slices for :meth:`__getitem__` + Slice objects are used to represent slices for + :meth:`~object.__getitem__` methods. They are also created by the built-in :func:`slice` function. .. index:: @@ -1229,7 +1231,8 @@ A class can implement certain operations that are invoked by special syntax (such as arithmetic operations or subscripting and slicing) by defining methods with special names. This is Python's approach to :dfn:`operator overloading`, allowing classes to define their own behavior with respect to language -operators. For instance, if a class defines a method named :meth:`__getitem__`, +operators. For instance, if a class defines a method named +:meth:`~object.__getitem__`, and ``x`` is an instance of this class, then ``x[i]`` is roughly equivalent to ``type(x).__getitem__(x, i)``. Except where mentioned, attempts to execute an operation raise an exception when no appropriate method is defined (typically @@ -1237,9 +1240,9 @@ operation raise an exception when no appropriate method is defined (typically Setting a special method to ``None`` indicates that the corresponding operation is not available. For example, if a class sets -:meth:`__iter__` to ``None``, the class is not iterable, so calling +:meth:`~object.__iter__` to ``None``, the class is not iterable, so calling :func:`iter` on its instances will raise a :exc:`TypeError` (without -falling back to :meth:`__getitem__`). [#]_ +falling back to :meth:`~object.__getitem__`). [#]_ When implementing a class that emulates any built-in type, it is important that the emulation only be implemented to the degree that it makes sense for the @@ -1789,7 +1792,8 @@ Invoking Descriptors In general, a descriptor is an object attribute with "binding behavior", one whose attribute access has been overridden by methods in the descriptor -protocol: :meth:`__get__`, :meth:`__set__`, and :meth:`__delete__`. If any of +protocol: :meth:`~object.__get__`, :meth:`~object.__set__`, and +:meth:`~object.__delete__`. If any of those methods are defined for an object, it is said to be a descriptor. The default behavior for attribute access is to get, set, or delete the @@ -1853,7 +1857,8 @@ Super Binding For instance bindings, the precedence of descriptor invocation depends on which descriptor methods are defined. A descriptor can define any combination -of :meth:`__get__`, :meth:`__set__` and :meth:`__delete__`. If it does not +of :meth:`~object.__get__`, :meth:`~object.__set__` and +:meth:`~object.__delete__`. If it does not define :meth:`__get__`, then accessing the attribute will return the descriptor object itself unless there is a value in the object's instance dictionary. If the descriptor defines :meth:`__set__` and/or :meth:`__delete__`, it is a data @@ -1864,7 +1869,8 @@ descriptors have just the :meth:`__get__` method. Data descriptors with instance dictionary. In contrast, non-data descriptors can be overridden by instances. -Python methods (including :func:`staticmethod` and :func:`classmethod`) are +Python methods (including those decorated with +:func:`@staticmethod ` and :func:`@classmethod `) are implemented as non-data descriptors. Accordingly, instances can redefine and override methods. This allows individual instances to acquire behaviors that differ from other instances of the same class. @@ -1879,46 +1885,50 @@ __slots__ ^^^^^^^^^ *__slots__* allow us to explicitly declare data members (like -properties) and deny the creation of *__dict__* and *__weakref__* +properties) and deny the creation of :attr:`~object.__dict__` and *__weakref__* (unless explicitly declared in *__slots__* or available in a parent.) -The space saved over using *__dict__* can be significant. +The space saved over using :attr:`~object.__dict__` can be significant. Attribute lookup speed can be significantly improved as well. .. data:: object.__slots__ This class variable can be assigned a string, iterable, or sequence of strings with variable names used by instances. *__slots__* reserves space - for the declared variables and prevents the automatic creation of *__dict__* + for the declared variables and prevents the automatic creation of + :attr:`~object.__dict__` and *__weakref__* for each instance. Notes on using *__slots__* """""""""""""""""""""""""" -* When inheriting from a class without *__slots__*, the *__dict__* and +* When inheriting from a class without *__slots__*, the + :attr:`~object.__dict__` and *__weakref__* attribute of the instances will always be accessible. -* Without a *__dict__* variable, instances cannot be assigned new variables not +* Without a :attr:`~object.__dict__` variable, instances cannot be assigned new + variables not listed in the *__slots__* definition. Attempts to assign to an unlisted variable name raises :exc:`AttributeError`. If dynamic assignment of new variables is desired, then add ``'__dict__'`` to the sequence of strings in the *__slots__* declaration. * Without a *__weakref__* variable for each instance, classes defining - *__slots__* do not support weak references to its instances. If weak reference + *__slots__* do not support :mod:`weak references ` to its instances. + If weak reference support is needed, then add ``'__weakref__'`` to the sequence of strings in the *__slots__* declaration. -* *__slots__* are implemented at the class level by creating descriptors - (:ref:`descriptors`) for each variable name. As a result, class attributes +* *__slots__* are implemented at the class level by creating :ref:`descriptors ` + for each variable name. As a result, class attributes cannot be used to set default values for instance variables defined by *__slots__*; otherwise, the class attribute would overwrite the descriptor assignment. * The action of a *__slots__* declaration is not limited to the class where it is defined. *__slots__* declared in parents are available in - child classes. However, child subclasses will get a *__dict__* and + child classes. However, child subclasses will get a :attr:`~object.__dict__` and *__weakref__* unless they also define *__slots__* (which should only contain names of any *additional* slots). @@ -1934,14 +1944,17 @@ Notes on using *__slots__* used; however, in the future, special meaning may be assigned to the values corresponding to each key. -* *__class__* assignment works only if both classes have the same *__slots__*. +* :attr:`~instance.__class__` assignment works only if both classes have the + same *__slots__*. -* Multiple inheritance with multiple slotted parent classes can be used, +* :ref:`Multiple inheritance ` with multiple slotted parent + classes can be used, but only one parent is allowed to have attributes created by slots (the other bases must have empty slot layouts) - violations raise :exc:`TypeError`. -* If an iterator is used for *__slots__* then a descriptor is created for each +* If an :term:`iterator` is used for *__slots__* then a :term:`descriptor` is + created for each of the iterator's values. However, the *__slots__* attribute will be an empty iterator. @@ -1950,7 +1963,7 @@ Notes on using *__slots__* Customizing class creation -------------------------- -Whenever a class inherits from another class, *__init_subclass__* is +Whenever a class inherits from another class, :meth:`~object.__init_subclass__` is called on that class. This way, it is possible to write classes which change the behavior of subclasses. This is closely related to class decorators, but where class decorators only affect the specific class they're @@ -1991,7 +2004,7 @@ class defining the method. When a class is created, :meth:`type.__new__` scans the class variables -and makes callbacks to those with a :meth:`__set_name__` hook. +and makes callbacks to those with a :meth:`~object.__set_name__` hook. .. method:: object.__set_name__(self, owner, name) @@ -2103,7 +2116,8 @@ Once the appropriate metaclass has been identified, then the class namespace is prepared. If the metaclass has a ``__prepare__`` attribute, it is called as ``namespace = metaclass.__prepare__(name, bases, **kwds)`` (where the additional keyword arguments, if any, come from the class definition). The -``__prepare__`` method should be implemented as a :func:`classmethod`. The +``__prepare__`` method should be implemented as a +:func:`classmethod `. The namespace returned by ``__prepare__`` is passed in to ``__new__``, but when the final class object is created the namespace is copied into a new ``dict``. @@ -2401,31 +2415,36 @@ Emulating container types ------------------------- The following methods can be defined to implement container objects. Containers -usually are sequences (such as lists or tuples) or mappings (like dictionaries), +usually are :term:`sequences ` (such as :class:`lists ` or +:class:`tuples `) or :term:`mappings ` (like +:class:`dictionaries `), but can represent other containers as well. The first set of methods is used either to emulate a sequence or to emulate a mapping; the difference is that for a sequence, the allowable keys should be the integers *k* for which ``0 <= k < -N`` where *N* is the length of the sequence, or slice objects, which define a +N`` where *N* is the length of the sequence, or :class:`slice` objects, which define a range of items. It is also recommended that mappings provide the methods :meth:`keys`, :meth:`values`, :meth:`items`, :meth:`get`, :meth:`clear`, :meth:`setdefault`, :meth:`pop`, :meth:`popitem`, :meth:`!copy`, and -:meth:`update` behaving similar to those for Python's standard dictionary +:meth:`update` behaving similar to those for Python's standard :class:`dictionary ` objects. The :mod:`collections.abc` module provides a :class:`~collections.abc.MutableMapping` -abstract base class to help create those methods from a base set of -:meth:`__getitem__`, :meth:`__setitem__`, :meth:`__delitem__`, and :meth:`keys`. +:term:`abstract base class` to help create those methods from a base set of +:meth:`~object.__getitem__`, :meth:`~object.__setitem__`, :meth:`~object.__delitem__`, and :meth:`keys`. Mutable sequences should provide methods :meth:`append`, :meth:`count`, :meth:`index`, :meth:`extend`, :meth:`insert`, :meth:`pop`, :meth:`remove`, -:meth:`reverse` and :meth:`sort`, like Python standard list objects. Finally, +:meth:`reverse` and :meth:`sort`, like Python standard :class:`list` +objects. Finally, sequence types should implement addition (meaning concatenation) and -multiplication (meaning repetition) by defining the methods :meth:`__add__`, -:meth:`__radd__`, :meth:`__iadd__`, :meth:`__mul__`, :meth:`__rmul__` and -:meth:`__imul__` described below; they should not define other numerical +multiplication (meaning repetition) by defining the methods +:meth:`~object.__add__`, :meth:`~object.__radd__`, :meth:`~object.__iadd__`, +:meth:`~object.__mul__`, :meth:`~object.__rmul__` and :meth:`~object.__imul__` +described below; they should not define other numerical operators. It is recommended that both mappings and sequences implement the -:meth:`__contains__` method to allow efficient use of the ``in`` operator; for +:meth:`~object.__contains__` method to allow efficient use of the ``in`` +operator; for mappings, ``in`` should search the mapping's keys; for sequences, it should search through the values. It is further recommended that both mappings and -sequences implement the :meth:`__iter__` method to allow efficient iteration +sequences implement the :meth:`~object.__iter__` method to allow efficient iteration through the container; for mappings, :meth:`__iter__` should iterate through the object's keys; for sequences, it should iterate through the values. @@ -2838,7 +2857,8 @@ exception:: TypeError: object of type 'C' has no len() The rationale behind this behaviour lies with a number of special methods such -as :meth:`__hash__` and :meth:`__repr__` that are implemented by all objects, +as :meth:`~object.__hash__` and :meth:`~object.__repr__` that are implemented +by all objects, including type objects. If the implicit lookup of these methods used the conventional lookup process, they would fail when invoked on the type object itself:: @@ -2861,7 +2881,7 @@ the instance when looking up special methods:: In addition to bypassing any instance attributes in the interest of correctness, implicit special method lookup generally also bypasses the -:meth:`__getattribute__` method even of the object's metaclass:: +:meth:`~object.__getattribute__` method even of the object's metaclass:: >>> class Meta(type): ... def __getattribute__(*args): @@ -2885,7 +2905,7 @@ correctness, implicit special method lookup generally also bypasses the >>> len(c) # Implicit lookup 10 -Bypassing the :meth:`__getattribute__` machinery in this fashion +Bypassing the :meth:`~object.__getattribute__` machinery in this fashion provides significant scope for speed optimisations within the interpreter, at the cost of some flexibility in the handling of special methods (the special method *must* be set on the class @@ -2902,7 +2922,7 @@ Coroutines Awaitable Objects ----------------- -An :term:`awaitable` object generally implements an :meth:`__await__` method. +An :term:`awaitable` object generally implements an :meth:`~object.__await__` method. :term:`Coroutine objects ` returned from :keyword:`async def` functions are awaitable. @@ -2910,7 +2930,7 @@ are awaitable. The :term:`generator iterator` objects returned from generators decorated with :func:`types.coroutine` - are also awaitable, but they do not implement :meth:`__await__`. + are also awaitable, but they do not implement :meth:`~object.__await__`. .. method:: object.__await__(self) @@ -2929,7 +2949,7 @@ Coroutine Objects ----------------- :term:`Coroutine objects ` are :term:`awaitable` objects. -A coroutine's execution can be controlled by calling :meth:`__await__` and +A coroutine's execution can be controlled by calling :meth:`~object.__await__` and iterating over the result. When the coroutine has finished executing and returns, the iterator raises :exc:`StopIteration`, and the exception's :attr:`~StopIteration.value` attribute holds the return value. If the @@ -2948,7 +2968,7 @@ generators, coroutines do not directly support iteration. Starts or resumes execution of the coroutine. If *value* is ``None``, this is equivalent to advancing the iterator returned by - :meth:`__await__`. If *value* is not ``None``, this method delegates + :meth:`~object.__await__`. If *value* is not ``None``, this method delegates to the :meth:`~generator.send` method of the iterator that caused the coroutine to suspend. The result (return value, :exc:`StopIteration`, or other exception) is the same as when @@ -2961,7 +2981,7 @@ generators, coroutines do not directly support iteration. the coroutine to suspend, if it has such a method. Otherwise, the exception is raised at the suspension point. The result (return value, :exc:`StopIteration`, or other exception) is the same as - when iterating over the :meth:`__await__` return value, described + when iterating over the :meth:`~object.__await__` return value, described above. If the exception is not caught in the coroutine, it propagates back to the caller. @@ -3015,11 +3035,11 @@ An example of an asynchronous iterable object:: .. versionadded:: 3.5 .. versionchanged:: 3.7 - Prior to Python 3.7, ``__aiter__`` could return an *awaitable* + Prior to Python 3.7, :meth:`~object.__aiter__` could return an *awaitable* that would resolve to an :term:`asynchronous iterator `. - Starting with Python 3.7, ``__aiter__`` must return an + Starting with Python 3.7, :meth:`~object.__aiter__` must return an asynchronous iterator object. Returning anything else will result in a :exc:`TypeError` error. @@ -3062,8 +3082,9 @@ An example of an asynchronous context manager class:: controlled conditions. It generally isn't a good idea though, since it can lead to some very strange behaviour if it is handled incorrectly. -.. [#] The :meth:`__hash__`, :meth:`__iter__`, :meth:`__reversed__`, and - :meth:`__contains__` methods have special handling for this; others +.. [#] The :meth:`~object.__hash__`, :meth:`~object.__iter__`, + :meth:`~object.__reversed__`, and :meth:`~object.__contains__` methods have + special handling for this; others will still raise a :exc:`TypeError`, but may do so by relying on the behavior that ``None`` is not callable. @@ -3074,5 +3095,6 @@ An example of an asynchronous context manager class:: *blocking* such fallback. .. [#] For operands of the same type, it is assumed that if the non-reflected - method -- such as :meth:`__add__` -- fails then the overall operation is not + method -- such as :meth:`~object.__add__` -- fails then the overall + operation is not supported, which is why the reflected method is not called. diff --git a/Misc/NEWS.d/next/Documentation/2021-11-19-02-02-32.bpo-45840.A51B2S.rst b/Misc/NEWS.d/next/Documentation/2021-11-19-02-02-32.bpo-45840.A51B2S.rst new file mode 100644 index 00000000000..87371e5b76b --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2021-11-19-02-02-32.bpo-45840.A51B2S.rst @@ -0,0 +1 @@ +Improve cross-references in the documentation for the data model.