summaryrefslogtreecommitdiffstats
path: root/Doc/library
diff options
context:
space:
mode:
authorOlga Matoula <olgamatoula@gmail.com>2023-04-24 23:26:18 (GMT)
committerGitHub <noreply@github.com>2023-04-24 23:26:18 (GMT)
commit0f23eda4b996dacd19dbe91bd47a30433bf236d2 (patch)
tree3d81c14868a08dc0ded2b1106b2216f783258aa5 /Doc/library
parent8291ae31ddc2f935b8ec60f3d5f3825f78ccf244 (diff)
downloadcpython-0f23eda4b996dacd19dbe91bd47a30433bf236d2.zip
cpython-0f23eda4b996dacd19dbe91bd47a30433bf236d2.tar.gz
cpython-0f23eda4b996dacd19dbe91bd47a30433bf236d2.tar.bz2
gh-103810: Fix broken references in dataclasses (#103811)
Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
Diffstat (limited to 'Doc/library')
-rw-r--r--Doc/library/dataclasses.rst146
1 files changed, 74 insertions, 72 deletions
diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst
index a04e5f7..85a7d90 100644
--- a/Doc/library/dataclasses.rst
+++ b/Doc/library/dataclasses.rst
@@ -12,8 +12,8 @@
--------------
This module provides a decorator and functions for automatically
-adding generated :term:`special method`\s such as :meth:`__init__` and
-:meth:`__repr__` to user-defined classes. It was originally described
+adding generated :term:`special method`\s such as :meth:`~object.__init__` and
+:meth:`~object.__repr__` to user-defined classes. It was originally described
in :pep:`557`.
The member variables to use in these generated methods are defined
@@ -31,7 +31,7 @@ using :pep:`526` type annotations. For example, this code::
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand
-will add, among other things, a :meth:`__init__` that looks like::
+will add, among other things, a :meth:`~object.__init__` that looks like::
def __init__(self, name: str, unit_price: float, quantity_on_hand: int = 0):
self.name = name
@@ -86,86 +86,86 @@ Module contents
The parameters to :func:`dataclass` are:
- - ``init``: If true (the default), a :meth:`__init__` method will be
+ - ``init``: If true (the default), a :meth:`~object.__init__` method will be
generated.
- If the class already defines :meth:`__init__`, this parameter is
+ If the class already defines :meth:`~object.__init__`, this parameter is
ignored.
- - ``repr``: If true (the default), a :meth:`__repr__` method will be
+ - ``repr``: If true (the default), a :meth:`~object.__repr__` method will be
generated. The generated repr string will have the class name and
the name and repr of each field, in the order they are defined in
the class. Fields that are marked as being excluded from the repr
are not included. For example:
``InventoryItem(name='widget', unit_price=3.0, quantity_on_hand=10)``.
- If the class already defines :meth:`__repr__`, this parameter is
+ If the class already defines :meth:`~object.__repr__`, this parameter is
ignored.
- - ``eq``: If true (the default), an :meth:`__eq__` method will be
+ - ``eq``: If true (the default), an :meth:`~object.__eq__` method will be
generated. This method compares the class as if it were a tuple
of its fields, in order. Both instances in the comparison must
be of the identical type.
- If the class already defines :meth:`__eq__`, this parameter is
+ If the class already defines :meth:`~object.__eq__`, this parameter is
ignored.
- - ``order``: If true (the default is ``False``), :meth:`__lt__`,
- :meth:`__le__`, :meth:`__gt__`, and :meth:`__ge__` methods will be
+ - ``order``: If true (the default is ``False``), :meth:`~object.__lt__`,
+ :meth:`~object.__le__`, :meth:`~object.__gt__`, and :meth:`~object.__ge__` methods will be
generated. These compare the class as if it were a tuple of its
fields, in order. Both instances in the comparison must be of the
identical type. If ``order`` is true and ``eq`` is false, a
:exc:`ValueError` is raised.
- If the class already defines any of :meth:`__lt__`,
- :meth:`__le__`, :meth:`__gt__`, or :meth:`__ge__`, then
+ If the class already defines any of :meth:`~object.__lt__`,
+ :meth:`~object.__le__`, :meth:`~object.__gt__`, or :meth:`~object.__ge__`, then
:exc:`TypeError` is raised.
- - ``unsafe_hash``: If ``False`` (the default), a :meth:`__hash__` method
+ - ``unsafe_hash``: If ``False`` (the default), a :meth:`~object.__hash__` method
is generated according to how ``eq`` and ``frozen`` are set.
- :meth:`__hash__` is used by built-in :meth:`hash()`, and when objects are
+ :meth:`~object.__hash__` is used by built-in :meth:`hash()`, and when objects are
added to hashed collections such as dictionaries and sets. Having a
- :meth:`__hash__` implies that instances of the class are immutable.
+ :meth:`~object.__hash__` implies that instances of the class are immutable.
Mutability is a complicated property that depends on the programmer's
- intent, the existence and behavior of :meth:`__eq__`, and the values of
+ intent, the existence and behavior of :meth:`~object.__eq__`, and the values of
the ``eq`` and ``frozen`` flags in the :func:`dataclass` decorator.
- By default, :func:`dataclass` will not implicitly add a :meth:`__hash__`
+ By default, :func:`dataclass` will not implicitly add a :meth:`~object.__hash__`
method unless it is safe to do so. Neither will it add or change an
- existing explicitly defined :meth:`__hash__` method. Setting the class
+ existing explicitly defined :meth:`~object.__hash__` method. Setting the class
attribute ``__hash__ = None`` has a specific meaning to Python, as
- described in the :meth:`__hash__` documentation.
+ described in the :meth:`~object.__hash__` documentation.
- If :meth:`__hash__` is not explicitly defined, or if it is set to ``None``,
- then :func:`dataclass` *may* add an implicit :meth:`__hash__` method.
+ If :meth:`~object.__hash__` is not explicitly defined, or if it is set to ``None``,
+ then :func:`dataclass` *may* add an implicit :meth:`~object.__hash__` method.
Although not recommended, you can force :func:`dataclass` to create a
- :meth:`__hash__` method with ``unsafe_hash=True``. This might be the case
+ :meth:`~object.__hash__` method with ``unsafe_hash=True``. This might be the case
if your class is logically immutable but can nonetheless be mutated.
This is a specialized use case and should be considered carefully.
- Here are the rules governing implicit creation of a :meth:`__hash__`
- method. Note that you cannot both have an explicit :meth:`__hash__`
+ Here are the rules governing implicit creation of a :meth:`~object.__hash__`
+ method. Note that you cannot both have an explicit :meth:`~object.__hash__`
method in your dataclass and set ``unsafe_hash=True``; this will result
in a :exc:`TypeError`.
If ``eq`` and ``frozen`` are both true, by default :func:`dataclass` will
- generate a :meth:`__hash__` method for you. If ``eq`` is true and
- ``frozen`` is false, :meth:`__hash__` will be set to ``None``, marking it
+ generate a :meth:`~object.__hash__` method for you. If ``eq`` is true and
+ ``frozen`` is false, :meth:`~object.__hash__` will be set to ``None``, marking it
unhashable (which it is, since it is mutable). If ``eq`` is false,
- :meth:`__hash__` will be left untouched meaning the :meth:`__hash__`
+ :meth:`~object.__hash__` will be left untouched meaning the :meth:`~object.__hash__`
method of the superclass will be used (if the superclass is
:class:`object`, this means it will fall back to id-based hashing).
- ``frozen``: If true (the default is ``False``), assigning to fields will
generate an exception. This emulates read-only frozen instances. If
- :meth:`__setattr__` or :meth:`__delattr__` is defined in the class, then
+ :meth:`~object.__setattr__` or :meth:`~object.__delattr__` is defined in the class, then
:exc:`TypeError` is raised. See the discussion below.
- ``match_args``: If true (the default is ``True``), the
``__match_args__`` tuple will be created from the list of
- parameters to the generated :meth:`__init__` method (even if
- :meth:`__init__` is not generated, see above). If false, or if
+ parameters to the generated :meth:`~object.__init__` method (even if
+ :meth:`~object.__init__` is not generated, see above). If false, or if
``__match_args__`` is already defined in the class, then
``__match_args__`` will not be generated.
@@ -173,18 +173,18 @@ Module contents
- ``kw_only``: If true (the default value is ``False``), then all
fields will be marked as keyword-only. If a field is marked as
- keyword-only, then the only effect is that the :meth:`__init__`
+ keyword-only, then the only effect is that the :meth:`~object.__init__`
parameter generated from a keyword-only field must be specified
- with a keyword when :meth:`__init__` is called. There is no
+ with a keyword when :meth:`~object.__init__` is called. There is no
effect on any other aspect of dataclasses. See the
:term:`parameter` glossary entry for details. Also see the
:const:`KW_ONLY` section.
.. versionadded:: 3.10
- - ``slots``: If true (the default is ``False``), :attr:`__slots__` attribute
+ - ``slots``: If true (the default is ``False``), :attr:`~object.__slots__` attribute
will be generated and new class will be returned instead of the original one.
- If :attr:`__slots__` is already defined in the class, then :exc:`TypeError`
+ If :attr:`~object.__slots__` is already defined in the class, then :exc:`TypeError`
is raised.
.. versionadded:: 3.10
@@ -215,7 +215,7 @@ Module contents
b: int = 0 # assign a default value for 'b'
In this example, both ``a`` and ``b`` will be included in the added
- :meth:`__init__` method, which will be defined as::
+ :meth:`~object.__init__` method, which will be defined as::
def __init__(self, a: int, b: int = 0):
@@ -256,13 +256,13 @@ Module contents
error to specify both ``default`` and ``default_factory``.
- ``init``: If true (the default), this field is included as a
- parameter to the generated :meth:`__init__` method.
+ parameter to the generated :meth:`~object.__init__` method.
- ``repr``: If true (the default), this field is included in the
- string returned by the generated :meth:`__repr__` method.
+ string returned by the generated :meth:`~object.__repr__` method.
- ``hash``: This can be a bool or ``None``. If true, this field is
- included in the generated :meth:`__hash__` method. If ``None`` (the
+ included in the generated :meth:`~object.__hash__` method. If ``None`` (the
default), use the value of ``compare``: this would normally be
the expected behavior. A field should be considered in the hash
if it's used for comparisons. Setting this value to anything
@@ -275,8 +275,8 @@ Module contents
is excluded from the hash, it will still be used for comparisons.
- ``compare``: If true (the default), this field is included in the
- generated equality and comparison methods (:meth:`__eq__`,
- :meth:`__gt__`, et al.).
+ generated equality and comparison methods (:meth:`~object.__eq__`,
+ :meth:`~object.__gt__`, et al.).
- ``metadata``: This can be a mapping or None. None is treated as
an empty dict. This value is wrapped in
@@ -287,7 +287,7 @@ Module contents
namespace in the metadata.
- ``kw_only``: If true, this field will be marked as keyword-only.
- This is used when the generated :meth:`__init__` method's
+ This is used when the generated :meth:`~object.__init__` method's
parameters are computed.
.. versionadded:: 3.10
@@ -435,13 +435,13 @@ Module contents
Class, raises :exc:`TypeError`. If values in ``changes`` do not
specify fields, raises :exc:`TypeError`.
- The newly returned object is created by calling the :meth:`__init__`
+ The newly returned object is created by calling the :meth:`~object.__init__`
method of the dataclass. This ensures that
- :meth:`__post_init__`, if present, is also called.
+ :ref:`__post_init__ <post-init-processing>`, if present, is also called.
Init-only variables without default values, if any exist, must be
specified on the call to :func:`replace` so that they can be passed to
- :meth:`__init__` and :meth:`__post_init__`.
+ :meth:`~object.__init__` and :ref:`__post_init__ <post-init-processing>`.
It is an error for ``changes`` to contain any fields that are
defined as having ``init=False``. A :exc:`ValueError` will be raised
@@ -449,7 +449,7 @@ Module contents
Be forewarned about how ``init=False`` fields work during a call to
:func:`replace`. They are not copied from the source object, but
- rather are initialized in :meth:`__post_init__`, if they're
+ rather are initialized in :ref:`__post_init__ <post-init-processing>`, if they're
initialized at all. It is expected that ``init=False`` fields will
be rarely and judiciously used. If they are used, it might be wise
to have alternate class constructors, or perhaps a custom
@@ -480,7 +480,7 @@ Module contents
:const:`KW_ONLY` is otherwise completely ignored. This includes the
name of such a field. By convention, a name of ``_`` is used for a
:const:`KW_ONLY` field. Keyword-only fields signify
- :meth:`__init__` parameters that must be specified as keywords when
+ :meth:`~object.__init__` parameters that must be specified as keywords when
the class is instantiated.
In this example, the fields ``y`` and ``z`` will be marked as keyword-only fields::
@@ -501,20 +501,22 @@ Module contents
.. exception:: FrozenInstanceError
- Raised when an implicitly defined :meth:`__setattr__` or
- :meth:`__delattr__` is called on a dataclass which was defined with
+ Raised when an implicitly defined :meth:`~object.__setattr__` or
+ :meth:`~object.__delattr__` is called on a dataclass which was defined with
``frozen=True``. It is a subclass of :exc:`AttributeError`.
+.. _post-init-processing:
+
Post-init processing
--------------------
-The generated :meth:`__init__` code will call a method named
-:meth:`__post_init__`, if :meth:`__post_init__` is defined on the
+The generated :meth:`~object.__init__` code will call a method named
+:meth:`!__post_init__`, if :meth:`!__post_init__` is defined on the
class. It will normally be called as ``self.__post_init__()``.
However, if any ``InitVar`` fields are defined, they will also be
-passed to :meth:`__post_init__` in the order they were defined in the
-class. If no :meth:`__init__` method is generated, then
-:meth:`__post_init__` will not automatically be called.
+passed to :meth:`!__post_init__` in the order they were defined in the
+class. If no :meth:`~object.__init__` method is generated, then
+:meth:`!__post_init__` will not automatically be called.
Among other uses, this allows for initializing field values that
depend on one or more other fields. For example::
@@ -528,10 +530,10 @@ depend on one or more other fields. For example::
def __post_init__(self):
self.c = self.a + self.b
-The :meth:`__init__` method generated by :func:`dataclass` does not call base
-class :meth:`__init__` methods. If the base class has an :meth:`__init__` method
+The :meth:`~object.__init__` method generated by :func:`dataclass` does not call base
+class :meth:`~object.__init__` methods. If the base class has an :meth:`~object.__init__` method
that has to be called, it is common to call this method in a
-:meth:`__post_init__` method::
+:meth:`!__post_init__` method::
@dataclass
class Rectangle:
@@ -545,12 +547,12 @@ that has to be called, it is common to call this method in a
def __post_init__(self):
super().__init__(self.side, self.side)
-Note, however, that in general the dataclass-generated :meth:`__init__` methods
+Note, however, that in general the dataclass-generated :meth:`~object.__init__` methods
don't need to be called, since the derived dataclass will take care of
initializing all fields of any base class that is a dataclass itself.
See the section below on init-only variables for ways to pass
-parameters to :meth:`__post_init__`. Also see the warning about how
+parameters to :meth:`!__post_init__`. Also see the warning about how
:func:`replace` handles ``init=False`` fields.
Class variables
@@ -573,8 +575,8 @@ if the type of a field is of type ``dataclasses.InitVar``. If a field
is an ``InitVar``, it is considered a pseudo-field called an init-only
field. As it is not a true field, it is not returned by the
module-level :func:`fields` function. Init-only fields are added as
-parameters to the generated :meth:`__init__` method, and are passed to
-the optional :meth:`__post_init__` method. They are not otherwise used
+parameters to the generated :meth:`~object.__init__` method, and are passed to
+the optional :ref:`__post_init__ <post-init-processing>` method. They are not otherwise used
by dataclasses.
For example, suppose a field will be initialized from a database, if a
@@ -601,12 +603,12 @@ Frozen instances
It is not possible to create truly immutable Python objects. However,
by passing ``frozen=True`` to the :meth:`dataclass` decorator you can
emulate immutability. In that case, dataclasses will add
-:meth:`__setattr__` and :meth:`__delattr__` methods to the class. These
+:meth:`~object.__setattr__` and :meth:`~object.__delattr__` methods to the class. These
methods will raise a :exc:`FrozenInstanceError` when invoked.
There is a tiny performance penalty when using ``frozen=True``:
-:meth:`__init__` cannot use simple assignment to initialize fields, and
-must use :meth:`object.__setattr__`.
+:meth:`~object.__init__` cannot use simple assignment to initialize fields, and
+must use :meth:`~object.__setattr__`.
Inheritance
-----------
@@ -634,14 +636,14 @@ example::
The final list of fields is, in order, ``x``, ``y``, ``z``. The final
type of ``x`` is ``int``, as specified in class ``C``.
-The generated :meth:`__init__` method for ``C`` will look like::
+The generated :meth:`~object.__init__` method for ``C`` will look like::
def __init__(self, x: int = 15, y: int = 0, z: int = 10):
-Re-ordering of keyword-only parameters in :meth:`__init__`
-----------------------------------------------------------
+Re-ordering of keyword-only parameters in :meth:`~object.__init__`
+------------------------------------------------------------------
-After the parameters needed for :meth:`__init__` are computed, any
+After the parameters needed for :meth:`~object.__init__` are computed, any
keyword-only parameters are moved to come after all regular
(non-keyword-only) parameters. This is a requirement of how
keyword-only parameters are implemented in Python: they must come
@@ -662,7 +664,7 @@ fields, and ``Base.x`` and ``D.z`` are regular fields::
z: int = 10
t: int = field(kw_only=True, default=0)
-The generated :meth:`__init__` method for ``D`` will look like::
+The generated :meth:`~object.__init__` method for ``D`` will look like::
def __init__(self, x: Any = 15.0, z: int = 10, *, y: int = 0, w: int = 1, t: int = 0):
@@ -671,7 +673,7 @@ the list of fields: parameters derived from regular fields are
followed by parameters derived from keyword-only fields.
The relative ordering of keyword-only parameters is maintained in the
-re-ordered :meth:`__init__` parameter list.
+re-ordered :meth:`~object.__init__` parameter list.
Default factory functions
@@ -683,10 +685,10 @@ example, to create a new instance of a list, use::
mylist: list = field(default_factory=list)
-If a field is excluded from :meth:`__init__` (using ``init=False``)
+If a field is excluded from :meth:`~object.__init__` (using ``init=False``)
and the field also specifies ``default_factory``, then the default
factory function will always be called from the generated
-:meth:`__init__` function. This happens because there is no other
+:meth:`~object.__init__` function. This happens because there is no other
way to give the field an initial value.
Mutable default values