:mod:`!dataclasses` --- Data Classes
====================================

.. module:: dataclasses
    :synopsis: Generate special methods on user-defined classes.

.. moduleauthor:: Eric V. Smith <eric@trueblade.com>
.. sectionauthor:: Eric V. Smith <eric@trueblade.com>

**Source code:** :source:`Lib/dataclasses.py`

--------------

This module provides a decorator and functions for automatically
adding generated :term:`special methods <special method>` 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
using :pep:`526` type annotations.  For example, this code::

  from dataclasses import dataclass

  @dataclass
  class InventoryItem:
      """Class for keeping track of an item in inventory."""
      name: str
      unit_price: float
      quantity_on_hand: int = 0

      def total_cost(self) -> float:
          return self.unit_price * self.quantity_on_hand

will add, among other things, a :meth:`!__init__` that looks like::

  def __init__(self, name: str, unit_price: float, quantity_on_hand: int = 0):
      self.name = name
      self.unit_price = unit_price
      self.quantity_on_hand = quantity_on_hand

Note that this method is automatically added to the class: it is not
directly specified in the :class:`!InventoryItem` definition shown above.

.. versionadded:: 3.7

Module contents
---------------

.. decorator:: dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False)

   This function is a :term:`decorator` that is used to add generated
   :term:`special methods <special method>` to classes, as described below.

   The ``@dataclass`` decorator examines the class to find
   ``field``\s.  A ``field`` is defined as a class variable that has a
   :term:`type annotation <variable annotation>`.  With two
   exceptions described below, nothing in ``@dataclass``
   examines the type specified in the variable annotation.

   The order of the fields in all of the generated methods is the
   order in which they appear in the class definition.

   The ``@dataclass`` decorator will add various "dunder" methods to
   the class, described below.  If any of the added methods already
   exist in the class, the behavior depends on the parameter, as documented
   below. The decorator returns the same class that it is called on; no new
   class is created.

   If ``@dataclass`` is used just as a simple decorator with no parameters,
   it acts as if it has the default values documented in this
   signature.  That is, these three uses of ``@dataclass`` are
   equivalent::

     @dataclass
     class C:
         ...

     @dataclass()
     class C:
         ...

     @dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False,
                match_args=True, kw_only=False, slots=False, weakref_slot=False)
     class C:
         ...

   The parameters to ``@dataclass`` are:

   - *init*: If true (the default), a :meth:`~object.__init__` method will be
     generated.

     If the class already defines :meth:`!__init__`, this parameter is
     ignored.

   - *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
     ignored.

   - *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
     ignored.

   - *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
     :exc:`TypeError` is raised.

   - *unsafe_hash*: If true, force ``dataclasses`` to create a
     :meth:`~object.__hash__` method, even though it may not be safe to do so.
     Otherwise, generate a :meth:`~object.__hash__` method according to how
     *eq* and *frozen* are set.
     The default value is ``False``.

     :meth:`!__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.
     Mutability is a complicated property that depends on the programmer's
     intent, the existence and behavior of :meth:`!__eq__`, and the values of
     the *eq* and *frozen* flags in the ``@dataclass`` decorator.

     By default, ``@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
     attribute ``__hash__ = None`` has a specific meaning to Python, as
     described in the :meth:`!__hash__` documentation.

     If :meth:`!__hash__` is not explicitly defined, or if it is set to ``None``,
     then ``@dataclass`` *may* add an implicit :meth:`!__hash__` method.
     Although not recommended, you can force ``@dataclass`` to create a
     :meth:`!__hash__` method with ``unsafe_hash=True``. This might be the case
     if your class is logically immutable but can still 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__`
     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 ``@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
     unhashable (which it is, since it is mutable).  If *eq* is false,
     :meth:`!__hash__` will be left untouched meaning the :meth:`!__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.
     See the :ref:`discussion <dataclasses-frozen>` below.

     If :meth:`~object.__setattr__` or :meth:`~object.__delattr__` is defined in the class
     and *frozen* is true, then :exc:`TypeError` is raised.

   - *match_args*: If true (the default is ``True``), the
     :attr:`~object.__match_args__` tuple will be created from the list of
     non keyword-only parameters to the generated :meth:`~object.__init__` method (even if
     :meth:`!__init__` is not generated, see above).  If false, or if
     :attr:`!__match_args__` is already defined in the class, then
     :attr:`!__match_args__` will not be generated.

    .. versionadded:: 3.10

   - *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:`~object.__init__`
     parameter generated from a keyword-only field must be specified
     with a keyword when :meth:`!__init__` is called. See the :term:`parameter`
     glossary entry for details.  Also see the
     :const:`KW_ONLY` section.

     Keyword-only fields are not included in :attr:`!__match_args__`.

    .. versionadded:: 3.10

   - *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`
     is raised.

    .. warning::
       Passing parameters to a base class :meth:`~object.__init_subclass__`
       when using ``slots=True`` will result in a :exc:`TypeError`.
       Either use ``__init_subclass__`` with no parameters
       or use default values as a workaround.
       See :gh:`91126` for full details.

    .. versionadded:: 3.10

    .. versionchanged:: 3.11
       If a field name is already included in the :attr:`!__slots__`
       of a base class, it will not be included in the generated :attr:`!__slots__`
       to prevent :ref:`overriding them <datamodel-note-slots>`.
       Therefore, do not use :attr:`!__slots__` to retrieve the field names of a
       dataclass. Use :func:`fields` instead.
       To be able to determine inherited slots,
       base class :attr:`!__slots__` may be any iterable, but *not* an iterator.


   - *weakref_slot*: If true (the default is ``False``), add a slot
     named "__weakref__", which is required to make an instance
     :func:`weakref-able <weakref.ref>`.
     It is an error to specify ``weakref_slot=True``
     without also specifying ``slots=True``.

    .. versionadded:: 3.11

   ``field``\s may optionally specify a default value, using normal
   Python syntax::

     @dataclass
     class C:
         a: int       # 'a' has no default value
         b: int = 0   # assign a default value for 'b'

   In this example, both :attr:`!a` and :attr:`!b` will be included in the added
   :meth:`~object.__init__` method, which will be defined as::

     def __init__(self, a: int, b: int = 0):

   :exc:`TypeError` will be raised if a field without a default value
   follows a field with a default value.  This is true whether this
   occurs in a single class, or as a result of class inheritance.

.. function:: field(*, default=MISSING, default_factory=MISSING, init=True, repr=True, hash=None, compare=True, metadata=None, kw_only=MISSING, doc=None)

   For common and simple use cases, no other functionality is
   required.  There are, however, some dataclass features that
   require additional per-field information.  To satisfy this need for
   additional information, you can replace the default field value
   with a call to the provided :func:`!field` function.  For example::

     @dataclass
     class C:
         mylist: list[int] = field(default_factory=list)

     c = C()
     c.mylist += [1, 2, 3]

   As shown above, the :const:`MISSING` value is a sentinel object used to
   detect if some parameters are provided by the user. This sentinel is
   used because ``None`` is a valid value for some parameters with
   a distinct meaning.  No code should directly use the :const:`MISSING` value.

   The parameters to :func:`!field` are:

   - *default*: If provided, this will be the default value for this
     field.  This is needed because the :func:`!field` call itself
     replaces the normal position of the default value.

   - *default_factory*: If provided, it must be a zero-argument
     callable that will be called when a default value is needed for
     this field.  Among other purposes, this can be used to specify
     fields with mutable default values, as discussed below.  It is an
     error to specify both *default* and *default_factory*.

   - *init*: If true (the default), this field is included as a
     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:`~object.__repr__` method.

   - *hash*: This can be a bool or ``None``.  If true, this field is
     included in the generated :meth:`~object.__hash__` method.  If false,
     this field is excluded from the generated :meth:`~object.__hash__`.
     If ``None`` (the default), use the value of *compare*: this would
     normally be the expected behavior, since a field should be included
     in the hash if it's used for comparisons.  Setting this value to anything
     other than ``None`` is discouraged.

     One possible reason to set ``hash=False`` but ``compare=True``
     would be if a field is expensive to compute a hash value for,
     that field is needed for equality testing, and there are other
     fields that contribute to the type's hash value.  Even if a field
     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:`~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
     :func:`~types.MappingProxyType` to make it read-only, and exposed
     on the :class:`Field` object. It is not used at all by Data
     Classes, and is provided as a third-party extension mechanism.
     Multiple third-parties can each have their own key, to use as a
     namespace in the metadata.

   - *kw_only*: If true, this field will be marked as keyword-only.
     This is used when the generated :meth:`~object.__init__` method's
     parameters are computed.

     Keyword-only fields are also not included in :attr:`!__match_args__`.

    .. versionadded:: 3.10

   - *doc*: optional docstring for this field.

    .. versionadded:: 3.14

   If the default value of a field is specified by a call to
   :func:`!field`, then the class attribute for this field will be
   replaced by the specified *default* value.  If *default* is not
   provided, then the class attribute will be deleted.  The intent is
   that after the :deco:`dataclass` decorator runs, the class
   attributes will all contain the default values for the fields, just
   as if the default value itself were specified.  For example,
   after::

     @dataclass
     class C:
         x: int
         y: int = field(repr=False)
         z: int = field(repr=False, default=10)
         t: int = 20

   The class attribute :attr:`!C.z` will be ``10``, the class attribute
   :attr:`!C.t` will be ``20``, and the class attributes :attr:`!C.x` and
   :attr:`!C.y` will not be set.

.. class:: Field

   :class:`!Field` objects describe each defined field. These objects
   are created internally, and are returned by the :func:`fields`
   module-level method (see below).  Users should never instantiate a
   :class:`!Field` object directly.  Its documented attributes are:

   - :attr:`!name`: The name of the field.
   - :attr:`!type`: The type of the field.
   - :attr:`!default`, :attr:`!default_factory`, :attr:`!init`, :attr:`!repr`, :attr:`!hash`,
     :attr:`!compare`, :attr:`!metadata`, and :attr:`!kw_only` have the identical
     meaning and values as they do in the :func:`field` function.

   Other attributes may exist, but they are private and must not be
   inspected or relied on.

.. class:: InitVar

   ``InitVar[T]`` type annotations describe variables that are :ref:`init-only
   <dataclasses-init-only-variables>`. Fields annotated with :class:`!InitVar`
   are considered pseudo-fields, and thus are neither returned by the
   :func:`fields` function nor used in any way except adding them as
   parameters to :meth:`~object.__init__` and an optional
   :meth:`__post_init__`.

.. function:: fields(class_or_instance)

   Returns a tuple of :class:`Field` objects that define the fields for this
   dataclass.  Accepts either a dataclass, or an instance of a dataclass.
   Raises :exc:`TypeError` if not passed a dataclass or instance of one.
   Does not return pseudo-fields which are ``ClassVar`` or ``InitVar``.

.. function:: asdict(obj, *, dict_factory=dict)

   Converts the dataclass *obj* to a dict (by using the
   factory function *dict_factory*).  Each dataclass is converted
   to a dict of its fields, as ``name: value`` pairs.  dataclasses, dicts,
   lists, and tuples are recursed into.  Other objects are copied with
   :func:`copy.deepcopy`.

   Example of using :func:`!asdict` on nested dataclasses::

     @dataclass
     class Point:
          x: int
          y: int

     @dataclass
     class C:
          mylist: list[Point]

     p = Point(10, 20)
     assert asdict(p) == {'x': 10, 'y': 20}

     c = C([Point(0, 0), Point(10, 4)])
     assert asdict(c) == {'mylist': [{'x': 0, 'y': 0}, {'x': 10, 'y': 4}]}

   To create a shallow copy, the following workaround may be used::

     {field.name: getattr(obj, field.name) for field in fields(obj)}

   :func:`!asdict` raises :exc:`TypeError` if *obj* is not a dataclass
   instance.

.. function:: astuple(obj, *, tuple_factory=tuple)

   Converts the dataclass *obj* to a tuple (by using the
   factory function *tuple_factory*).  Each dataclass is converted
   to a tuple of its field values.  dataclasses, dicts, lists, and
   tuples are recursed into. Other objects are copied with
   :func:`copy.deepcopy`.

   Continuing from the previous example::

     assert astuple(p) == (10, 20)
     assert astuple(c) == ([(0, 0), (10, 4)],)

   To create a shallow copy, the following workaround may be used::

     tuple(getattr(obj, field.name) for field in dataclasses.fields(obj))

   :func:`!astuple` raises :exc:`TypeError` if *obj* is not a dataclass
   instance.

.. function:: make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False, module=None, decorator=dataclass)

   Creates a new dataclass with name *cls_name*, fields as defined
   in *fields*, base classes as given in *bases*, and initialized
   with a namespace as given in *namespace*.  *fields* is an
   iterable whose elements are each either ``name``, ``(name, type)``,
   or ``(name, type, Field)``.  If just ``name`` is supplied,
   :data:`typing.Any` is used for ``type``.  The values of *init*,
   *repr*, *eq*, *order*, *unsafe_hash*, *frozen*,
   *match_args*, *kw_only*, *slots*, and *weakref_slot* have
   the same meaning as they do in :deco:`dataclass`.

   If *module* is defined, the :attr:`!__module__` attribute
   of the dataclass is set to that value.
   By default, it is set to the module name of the caller.

   The *decorator* parameter is a callable that will be used to create the dataclass.
   It should take the class object as a first argument and the same keyword arguments
   as :deco:`dataclass`. By default, the :deco:`dataclass`
   function is used.

   This function is not strictly required, because any Python
   mechanism for creating a new class with :attr:`~object.__annotations__` can
   then apply the :deco:`dataclass` function to convert that class to
   a dataclass.  This function is provided as a convenience.  For
   example::

     C = make_dataclass('C',
                        [('x', int),
                          'y',
                         ('z', int, field(default=5))],
                        namespace={'add_one': lambda self: self.x + 1})

   Is equivalent to::

     @dataclass
     class C:
         x: int
         y: 'typing.Any'
         z: int = 5

         def add_one(self):
             return self.x + 1

   .. versionadded:: 3.14
      Added the *decorator* parameter.

.. function:: replace(obj, /, **changes)

   Creates a new object of the same type as *obj*, replacing
   fields with values from *changes*.  If *obj* is not a Data
   Class, raises :exc:`TypeError`.  If keys in *changes* are not
   field names of the given dataclass, raises :exc:`TypeError`.

   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.

   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__`.

   It is an error for *changes* to contain any fields that are
   defined as having ``init=False``.  A :exc:`ValueError` will be raised
   in this case.

   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
   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
   :func:`!replace` (or similarly named) method which handles instance
   copying.

   Dataclass instances are also supported by generic function :func:`copy.replace`.

.. function:: is_dataclass(obj)

   Return ``True`` if its parameter is a dataclass (including subclasses of a
   dataclass) or an instance of one, otherwise return ``False``.

   If you need to know if a class is an instance of a dataclass (and
   not a dataclass itself), then add a further check for ``not
   isinstance(obj, type)``::

     def is_dataclass_instance(obj):
         return is_dataclass(obj) and not isinstance(obj, type)

.. data:: MISSING

   A sentinel value signifying a missing default or default_factory.

.. data:: KW_ONLY

   A sentinel value used as a type annotation.  Any fields after a
   pseudo-field with the type of :const:`!KW_ONLY` are marked as
   keyword-only fields.  Note that a pseudo-field of type
   :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:`~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::

    @dataclass
    class Point:
        x: float
        _: KW_ONLY
        y: float
        z: float

    p = Point(0, y=1.5, z=2.0)

   In a single dataclass, it is an error to specify more than one
   field whose type is :const:`!KW_ONLY`.

   .. versionadded:: 3.10

.. exception:: FrozenInstanceError

   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
--------------------

.. function:: __post_init__()

   When defined on the class, it will be called by the generated
   :meth:`~object.__init__`, normally as :meth:`!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.

   Among other uses, this allows for initializing field values that
   depend on one or more other fields.  For example::

     @dataclass
     class C:
         a: float
         b: float
         c: float = field(init=False)

         def __post_init__(self):
             self.c = self.a + self.b

The :meth:`~object.__init__` method generated by :deco:`dataclass` does not call base
class :meth:`!__init__` methods. If the base class has an :meth:`!__init__` method
that has to be called, it is common to call this method in a
:meth:`__post_init__` method::

    class Rectangle:
        def __init__(self, height, width):
            self.height = height
            self.width = width

    @dataclass
    class Square(Rectangle):
        side: float

        def __post_init__(self):
            super().__init__(self.side, self.side)

Note, however, that in general the dataclass-generated :meth:`!__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
:func:`replace` handles ``init=False`` fields.

.. _dataclasses-class-variables:

Class variables
---------------

One of the few places where :deco:`dataclass` actually inspects the type
of a field is to determine if a field is a class variable as defined
in :pep:`526`.  It does this by checking if the type of the field is
:data:`typing.ClassVar`.  If a field is a ``ClassVar``, it is excluded
from consideration as a field and is ignored by the dataclass
mechanisms.  Such ``ClassVar`` pseudo-fields are not returned by the
module-level :func:`fields` function.

.. _dataclasses-init-only-variables:

Init-only variables
-------------------

Another place where :deco:`dataclass` inspects a type annotation is to
determine if a field is an init-only variable.  It does this by seeing
if the type of a field is of type :class:`InitVar`.  If a field
is an :class:`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:`~object.__init__` method, and are passed to
the optional :meth:`__post_init__` method.  They are not otherwise used
by dataclasses.

For example, suppose a field will be initialized from a database, if a
value is not provided when creating the class::

  @dataclass
  class C:
      i: int
      j: int | None = None
      database: InitVar[DatabaseType | None] = None

      def __post_init__(self, database):
          if self.j is None and database is not None:
              self.j = database.lookup('j')

  c = C(10, database=my_database)

In this case, :func:`fields` will return :class:`Field` objects for :attr:`!i` and
:attr:`!j`, but not for :attr:`!database`.

.. _dataclasses-frozen:

Frozen instances
----------------

It is not possible to create truly immutable Python objects.  However,
by passing ``frozen=True`` to the :deco:`dataclass` decorator you can
emulate immutability.  In that case, dataclasses will add
: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:`~object.__init__` cannot use simple assignment to initialize fields, and
must use :meth:`!object.__setattr__`.

.. Make sure to not remove "object" from "object.__setattr__" in the above markup!

.. _dataclasses-inheritance:

Inheritance
-----------

When the dataclass is being created by the :deco:`dataclass` decorator,
it looks through all of the class's base classes in reverse MRO (that
is, starting at :class:`object`) and, for each dataclass that it finds,
adds the fields from that base class to an ordered mapping of fields.
After all of the base class fields are added, it adds its own fields
to the ordered mapping.  All of the generated methods will use this
combined, calculated ordered mapping of fields.  Because the fields
are in insertion order, derived classes override base classes.  An
example::

  @dataclass
  class Base:
      x: Any = 15.0
      y: int = 0

  @dataclass
  class C(Base):
      z: int = 10
      x: int = 15

The final list of fields is, in order, :attr:`!x`, :attr:`!y`, :attr:`!z`.  The final
type of :attr:`!x` is :class:`int`, as specified in class :class:`!C`.

The generated :meth:`~object.__init__` method for :class:`!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__`
-----------------------------------------------------------

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
after non-keyword-only parameters.

In this example, :attr:`!Base.y`, :attr:`!Base.w`, and :attr:`!D.t` are keyword-only
fields, and :attr:`!Base.x` and :attr:`!D.z` are regular fields::

  @dataclass
  class Base:
      x: Any = 15.0
      _: KW_ONLY
      y: int = 0
      w: int = 1

  @dataclass
  class D(Base):
      z: int = 10
      t: int = field(kw_only=True, default=0)

The generated :meth:`!__init__` method for :class:`!D` will look like::

  def __init__(self, x: Any = 15.0, z: int = 10, *, y: int = 0, w: int = 1, t: int = 0):

Note that the parameters have been re-ordered from how they appear in
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.


Default factory functions
-------------------------

If a :func:`field` specifies a *default_factory*, it is called with
zero arguments when a default value for the field is needed.  For
example, to create a new instance of a list, use::

  mylist: list = field(default_factory=list)

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
way to give the field an initial value.

Mutable default values
----------------------

Python stores default member variable values in class attributes.
Consider this example, not using dataclasses::

  class C:
      x = []
      def add(self, element):
          self.x.append(element)

  o1 = C()
  o2 = C()
  o1.add(1)
  o2.add(2)
  assert o1.x == [1, 2]
  assert o1.x is o2.x

Note that the two instances of class :class:`!C` share the same class
variable :attr:`!x`, as expected.

Using dataclasses, *if* this code was valid::

  @dataclass
  class D:
      x: list = []      # This code raises ValueError
      def add(self, element):
          self.x.append(element)

it would generate code similar to::

  class D:
      x = []
      def __init__(self, x=x):
          self.x = x
      def add(self, element):
          self.x.append(element)

  assert D().x is D().x

This has the same issue as the original example using class :class:`!C`.
That is, two instances of class :class:`!D` that do not specify a value
for :attr:`!x` when creating a class instance will share the same copy
of :attr:`!x`.  Because dataclasses just use normal Python class
creation they also share this behavior.  There is no general way
for Data Classes to detect this condition.  Instead, the
:deco:`dataclass` decorator will raise a :exc:`ValueError` if it
detects an unhashable default parameter.  The assumption is that if
a value is unhashable, it is mutable.  This is a partial solution,
but it does protect against many common errors.

Using default factory functions is a way to create new instances of
mutable types as default values for fields::

  @dataclass
  class D:
      x: list = field(default_factory=list)

  assert D().x is not D().x

.. versionchanged:: 3.11
   Instead of looking for and disallowing objects of type :class:`list`,
   :class:`dict`, or :class:`set`, unhashable objects are now not allowed as
   default values.  Unhashability is used to approximate
   mutability.

Descriptor-typed fields
-----------------------

Fields that are assigned :ref:`descriptor objects <descriptors>` as their
default value have the following special behaviors:

* The value for the field passed to the dataclass's :meth:`~object.__init__` method is
  passed to the descriptor's :meth:`~object.__set__` method rather than overwriting the
  descriptor object.

* Similarly, when getting or setting the field, the descriptor's
  :meth:`~object.__get__` or :meth:`!__set__` method is called rather than returning or
  overwriting the descriptor object.

* To determine whether a field contains a default value, :deco:`dataclass`
  will call the descriptor's :meth:`!__get__` method using its class access
  form: ``descriptor.__get__(obj=None, type=cls)``.  If the
  descriptor returns a value in this case, it will be used as the
  field's default. On the other hand, if the descriptor raises
  :exc:`AttributeError` in this situation, no default value will be
  provided for the field.

::

  class IntConversionDescriptor:
      def __init__(self, *, default):
          self._default = default

      def __set_name__(self, owner, name):
          self._name = "_" + name

      def __get__(self, obj, type):
          if obj is None:
              return self._default

          return getattr(obj, self._name, self._default)

      def __set__(self, obj, value):
          setattr(obj, self._name, int(value))

  @dataclass
  class InventoryItem:
      quantity_on_hand: IntConversionDescriptor = IntConversionDescriptor(default=100)

  i = InventoryItem()
  print(i.quantity_on_hand)   # 100
  i.quantity_on_hand = 2.5    # calls __set__ with 2.5
  print(i.quantity_on_hand)   # 2

Note that if a field is annotated with a descriptor type, but is not assigned
a descriptor object as its default value, the field will act like a normal
field.
