2025-08-15 18:14:21 +00:00
<!DOCTYPE html>
< html lang = "en" data-content_root = "../" >
< head >
< meta charset = "utf-8" / >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" / >
< title > dataclasses — Evennia latest documentation< / title >
< link rel = "stylesheet" type = "text/css" href = "../_static/pygments.css?v=d75fae25" / >
< link rel = "stylesheet" type = "text/css" href = "../_static/nature.css?v=279e0f84" / >
< link rel = "stylesheet" type = "text/css" href = "../_static/custom.css?v=e4a91a55" / >
< script src = "../_static/documentation_options.js?v=c6e86fd7" > < / script >
< script src = "../_static/doctools.js?v=9bcbadda" > < / script >
< script src = "../_static/sphinx_highlight.js?v=dc90522c" > < / script >
< link rel = "icon" href = "../_static/favicon.ico" / >
< link rel = "index" title = "Index" href = "../genindex.html" / >
< link rel = "search" title = "Search" href = "../search.html" / >
< / head > < body >
< div class = "related" role = "navigation" aria-label = "Related" >
< h3 > Navigation< / h3 >
< ul >
< li class = "right" style = "margin-right: 10px" >
< a href = "../genindex.html" title = "General Index"
accesskey="I">index< / a > < / li >
< li class = "right" >
< a href = "../py-modindex.html" title = "Python Module Index"
>modules< / a > |< / li >
< li class = "nav-item nav-item-0" > < a href = "../index.html" > Evennia< / a > » < / li >
< li class = "nav-item nav-item-1" > < a href = "index.html" accesskey = "U" > Module code< / a > » < / li >
< li class = "nav-item nav-item-this" > < a href = "" > dataclasses< / a > < / li >
< / ul >
< / div >
< div class = "document" >
< div class = "documentwrapper" >
< div class = "bodywrapper" >
< div class = "body" role = "main" >
< h1 > Source code for dataclasses< / h1 > < div class = "highlight" > < pre >
< span > < / span > < span class = "kn" > import< / span > < span class = "w" > < / span > < span class = "nn" > re< / span >
< span class = "kn" > import< / span > < span class = "w" > < / span > < span class = "nn" > sys< / span >
< span class = "kn" > import< / span > < span class = "w" > < / span > < span class = "nn" > copy< / span >
< span class = "kn" > import< / span > < span class = "w" > < / span > < span class = "nn" > types< / span >
< span class = "kn" > import< / span > < span class = "w" > < / span > < span class = "nn" > inspect< / span >
< span class = "kn" > import< / span > < span class = "w" > < / span > < span class = "nn" > keyword< / span >
< span class = "kn" > import< / span > < span class = "w" > < / span > < span class = "nn" > itertools< / span >
< span class = "kn" > import< / span > < span class = "w" > < / span > < span class = "nn" > abc< / span >
< span class = "kn" > from< / span > < span class = "w" > < / span > < span class = "nn" > reprlib< / span > < span class = "w" > < / span > < span class = "kn" > import< / span > < span class = "n" > recursive_repr< / span >
< span class = "n" > __all__< / span > < span class = "o" > =< / span > < span class = "p" > [< / span > < span class = "s1" > ' dataclass' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' field' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' Field' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' FrozenInstanceError' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' InitVar' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' KW_ONLY' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' MISSING' < / span > < span class = "p" > ,< / span >
< span class = "c1" > # Helper functions.< / span >
< span class = "s1" > ' fields' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' asdict' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' astuple' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' make_dataclass' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' replace' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' is_dataclass' < / span > < span class = "p" > ,< / span >
< span class = "p" > ]< / span >
< span class = "c1" > # Conditions for adding methods. The boxes indicate what action the< / span >
< span class = "c1" > # dataclass decorator takes. For all of these tables, when I talk< / span >
< span class = "c1" > # about init=, repr=, eq=, order=, unsafe_hash=, or frozen=, I' m< / span >
< span class = "c1" > # referring to the arguments to the @dataclass decorator. When< / span >
< span class = "c1" > # checking if a dunder method already exists, I mean check for an< / span >
< span class = "c1" > # entry in the class' s __dict__. I never check to see if an attribute< / span >
< span class = "c1" > # is defined in a base class.< / span >
< span class = "c1" > # Key:< / span >
< span class = "c1" > # +=========+=========================================+< / span >
< span class = "c1" > # + Value | Meaning |< / span >
< span class = "c1" > # +=========+=========================================+< / span >
< span class = "c1" > # | < blank> | No action: no method is added. |< / span >
< span class = "c1" > # +---------+-----------------------------------------+< / span >
< span class = "c1" > # | add | Generated method is added. |< / span >
< span class = "c1" > # +---------+-----------------------------------------+< / span >
< span class = "c1" > # | raise | TypeError is raised. |< / span >
< span class = "c1" > # +---------+-----------------------------------------+< / span >
< span class = "c1" > # | None | Attribute is set to None. |< / span >
< span class = "c1" > # +=========+=========================================+< / span >
< span class = "c1" > # __init__< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # +--- init= parameter< / span >
< span class = "c1" > # |< / span >
< span class = "c1" > # v | | |< / span >
< span class = "c1" > # | no | yes | < --- class has __init__ in __dict__?< / span >
< span class = "c1" > # +=======+=======+=======+< / span >
< span class = "c1" > # | False | | |< / span >
< span class = "c1" > # +-------+-------+-------+< / span >
< span class = "c1" > # | True | add | | < - the default< / span >
< span class = "c1" > # +=======+=======+=======+< / span >
< span class = "c1" > # __repr__< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # +--- repr= parameter< / span >
< span class = "c1" > # |< / span >
< span class = "c1" > # v | | |< / span >
< span class = "c1" > # | no | yes | < --- class has __repr__ in __dict__?< / span >
< span class = "c1" > # +=======+=======+=======+< / span >
< span class = "c1" > # | False | | |< / span >
< span class = "c1" > # +-------+-------+-------+< / span >
< span class = "c1" > # | True | add | | < - the default< / span >
< span class = "c1" > # +=======+=======+=======+< / span >
< span class = "c1" > # __setattr__< / span >
< span class = "c1" > # __delattr__< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # +--- frozen= parameter< / span >
< span class = "c1" > # |< / span >
< span class = "c1" > # v | | |< / span >
< span class = "c1" > # | no | yes | < --- class has __setattr__ or __delattr__ in __dict__?< / span >
< span class = "c1" > # +=======+=======+=======+< / span >
< span class = "c1" > # | False | | | < - the default< / span >
< span class = "c1" > # +-------+-------+-------+< / span >
< span class = "c1" > # | True | add | raise |< / span >
< span class = "c1" > # +=======+=======+=======+< / span >
< span class = "c1" > # Raise because not adding these methods would break the " frozen-ness" < / span >
< span class = "c1" > # of the class.< / span >
< span class = "c1" > # __eq__< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # +--- eq= parameter< / span >
< span class = "c1" > # |< / span >
< span class = "c1" > # v | | |< / span >
< span class = "c1" > # | no | yes | < --- class has __eq__ in __dict__?< / span >
< span class = "c1" > # +=======+=======+=======+< / span >
< span class = "c1" > # | False | | |< / span >
< span class = "c1" > # +-------+-------+-------+< / span >
< span class = "c1" > # | True | add | | < - the default< / span >
< span class = "c1" > # +=======+=======+=======+< / span >
< span class = "c1" > # __lt__< / span >
< span class = "c1" > # __le__< / span >
< span class = "c1" > # __gt__< / span >
< span class = "c1" > # __ge__< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # +--- order= parameter< / span >
< span class = "c1" > # |< / span >
< span class = "c1" > # v | | |< / span >
< span class = "c1" > # | no | yes | < --- class has any comparison method in __dict__?< / span >
< span class = "c1" > # +=======+=======+=======+< / span >
< span class = "c1" > # | False | | | < - the default< / span >
< span class = "c1" > # +-------+-------+-------+< / span >
< span class = "c1" > # | True | add | raise |< / span >
< span class = "c1" > # +=======+=======+=======+< / span >
< span class = "c1" > # Raise because to allow this case would interfere with using< / span >
< span class = "c1" > # functools.total_ordering.< / span >
< span class = "c1" > # __hash__< / span >
< span class = "c1" > # +------------------- unsafe_hash= parameter< / span >
< span class = "c1" > # | +----------- eq= parameter< / span >
< span class = "c1" > # | | +--- frozen= parameter< / span >
< span class = "c1" > # | | |< / span >
< span class = "c1" > # v v v | | |< / span >
< span class = "c1" > # | no | yes | < --- class has explicitly defined __hash__< / span >
< span class = "c1" > # +=======+=======+=======+========+========+< / span >
< span class = "c1" > # | False | False | False | | | No __eq__, use the base class __hash__< / span >
< span class = "c1" > # +-------+-------+-------+--------+--------+< / span >
< span class = "c1" > # | False | False | True | | | No __eq__, use the base class __hash__< / span >
< span class = "c1" > # +-------+-------+-------+--------+--------+< / span >
< span class = "c1" > # | False | True | False | None | | < -- the default, not hashable< / span >
< span class = "c1" > # +-------+-------+-------+--------+--------+< / span >
< span class = "c1" > # | False | True | True | add | | Frozen, so hashable, allows override< / span >
< span class = "c1" > # +-------+-------+-------+--------+--------+< / span >
< span class = "c1" > # | True | False | False | add | raise | Has no __eq__, but hashable< / span >
< span class = "c1" > # +-------+-------+-------+--------+--------+< / span >
< span class = "c1" > # | True | False | True | add | raise | Has no __eq__, but hashable< / span >
< span class = "c1" > # +-------+-------+-------+--------+--------+< / span >
< span class = "c1" > # | True | True | False | add | raise | Not frozen, but hashable< / span >
< span class = "c1" > # +-------+-------+-------+--------+--------+< / span >
< span class = "c1" > # | True | True | True | add | raise | Frozen, so hashable< / span >
< span class = "c1" > # +=======+=======+=======+========+========+< / span >
< span class = "c1" > # For boxes that are blank, __hash__ is untouched and therefore< / span >
< span class = "c1" > # inherited from the base class. If the base is object, then< / span >
< span class = "c1" > # id-based hashing is used.< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # Note that a class may already have __hash__=None if it specified an< / span >
< span class = "c1" > # __eq__ method in the class body (not one that was created by< / span >
< span class = "c1" > # @dataclass).< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # See _hash_action (below) for a coded version of this table.< / span >
< span class = "c1" > # __match_args__< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # +--- match_args= parameter< / span >
< span class = "c1" > # |< / span >
< span class = "c1" > # v | | |< / span >
< span class = "c1" > # | no | yes | < --- class has __match_args__ in __dict__?< / span >
< span class = "c1" > # +=======+=======+=======+< / span >
< span class = "c1" > # | False | | |< / span >
< span class = "c1" > # +-------+-------+-------+< / span >
< span class = "c1" > # | True | add | | < - the default< / span >
< span class = "c1" > # +=======+=======+=======+< / span >
< span class = "c1" > # __match_args__ is always added unless the class already defines it. It is a< / span >
< span class = "c1" > # tuple of __init__ parameter names; non-init fields must be matched by keyword.< / span >
< span class = "c1" > # Raised when an attempt is made to modify a frozen class.< / span >
< span class = "k" > class< / span > < span class = "w" > < / span > < span class = "nc" > FrozenInstanceError< / span > < span class = "p" > (< / span > < span class = "ne" > AttributeError< / span > < span class = "p" > ):< / span > < span class = "k" > pass< / span >
< span class = "c1" > # A sentinel object for default values to signal that a default< / span >
< span class = "c1" > # factory will be used. This is given a nice repr() which will appear< / span >
< span class = "c1" > # in the function signature of dataclasses' constructors.< / span >
< span class = "k" > class< / span > < span class = "w" > < / span > < span class = "nc" > _HAS_DEFAULT_FACTORY_CLASS< / span > < span class = "p" > :< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "fm" > __repr__< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ):< / span >
< span class = "k" > return< / span > < span class = "s1" > ' < factory> ' < / span >
< span class = "n" > _HAS_DEFAULT_FACTORY< / span > < span class = "o" > =< / span > < span class = "n" > _HAS_DEFAULT_FACTORY_CLASS< / span > < span class = "p" > ()< / span >
< span class = "c1" > # A sentinel object to detect if a parameter is supplied or not. Use< / span >
< span class = "c1" > # a class to give it a better repr.< / span >
< span class = "k" > class< / span > < span class = "w" > < / span > < span class = "nc" > _MISSING_TYPE< / span > < span class = "p" > :< / span >
< span class = "k" > pass< / span >
< span class = "n" > MISSING< / span > < span class = "o" > =< / span > < span class = "n" > _MISSING_TYPE< / span > < span class = "p" > ()< / span >
< span class = "c1" > # A sentinel object to indicate that following fields are keyword-only by< / span >
< span class = "c1" > # default. Use a class to give it a better repr.< / span >
< span class = "k" > class< / span > < span class = "w" > < / span > < span class = "nc" > _KW_ONLY_TYPE< / span > < span class = "p" > :< / span >
< span class = "k" > pass< / span >
< span class = "n" > KW_ONLY< / span > < span class = "o" > =< / span > < span class = "n" > _KW_ONLY_TYPE< / span > < span class = "p" > ()< / span >
< span class = "c1" > # Since most per-field metadata will be unused, create an empty< / span >
< span class = "c1" > # read-only proxy that can be shared among all fields.< / span >
< span class = "n" > _EMPTY_METADATA< / span > < span class = "o" > =< / span > < span class = "n" > types< / span > < span class = "o" > .< / span > < span class = "n" > MappingProxyType< / span > < span class = "p" > ({})< / span >
< span class = "c1" > # Markers for the various kinds of fields and pseudo-fields.< / span >
< span class = "k" > class< / span > < span class = "w" > < / span > < span class = "nc" > _FIELD_BASE< / span > < span class = "p" > :< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "fm" > __init__< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "n" > name< / span > < span class = "p" > ):< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "o" > =< / span > < span class = "n" > name< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "fm" > __repr__< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ):< / span >
< span class = "k" > return< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > name< / span >
< span class = "n" > _FIELD< / span > < span class = "o" > =< / span > < span class = "n" > _FIELD_BASE< / span > < span class = "p" > (< / span > < span class = "s1" > ' _FIELD' < / span > < span class = "p" > )< / span >
< span class = "n" > _FIELD_CLASSVAR< / span > < span class = "o" > =< / span > < span class = "n" > _FIELD_BASE< / span > < span class = "p" > (< / span > < span class = "s1" > ' _FIELD_CLASSVAR' < / span > < span class = "p" > )< / span >
< span class = "n" > _FIELD_INITVAR< / span > < span class = "o" > =< / span > < span class = "n" > _FIELD_BASE< / span > < span class = "p" > (< / span > < span class = "s1" > ' _FIELD_INITVAR' < / span > < span class = "p" > )< / span >
< span class = "c1" > # The name of an attribute on the class where we store the Field< / span >
< span class = "c1" > # objects. Also used to check if a class is a Data Class.< / span >
< span class = "n" > _FIELDS< / span > < span class = "o" > =< / span > < span class = "s1" > ' __dataclass_fields__' < / span >
< span class = "c1" > # The name of an attribute on the class that stores the parameters to< / span >
< span class = "c1" > # @dataclass.< / span >
< span class = "n" > _PARAMS< / span > < span class = "o" > =< / span > < span class = "s1" > ' __dataclass_params__' < / span >
< span class = "c1" > # The name of the function, that if it exists, is called at the end of< / span >
< span class = "c1" > # __init__.< / span >
< span class = "n" > _POST_INIT_NAME< / span > < span class = "o" > =< / span > < span class = "s1" > ' __post_init__' < / span >
< span class = "c1" > # String regex that string annotations for ClassVar or InitVar must match.< / span >
< span class = "c1" > # Allows " identifier.identifier[" or " identifier[" .< / span >
< span class = "c1" > # https://bugs.python.org/issue33453 for details.< / span >
< span class = "n" > _MODULE_IDENTIFIER_RE< / span > < span class = "o" > =< / span > < span class = "n" > re< / span > < span class = "o" > .< / span > < span class = "n" > compile< / span > < span class = "p" > (< / span > < span class = "sa" > r< / span > < span class = "s1" > ' ^(?:\s*(\w+)\s*\.)?\s*(\w+)' < / span > < span class = "p" > )< / span >
< span class = "c1" > # Atomic immutable types which don' t require any recursive handling and for which deepcopy< / span >
< span class = "c1" > # returns the same object. We can provide a fast-path for these types in asdict and astuple.< / span >
< span class = "n" > _ATOMIC_TYPES< / span > < span class = "o" > =< / span > < span class = "nb" > frozenset< / span > < span class = "p" > ({< / span >
< span class = "c1" > # Common JSON Serializable types< / span >
< span class = "n" > types< / span > < span class = "o" > .< / span > < span class = "n" > NoneType< / span > < span class = "p" > ,< / span >
< span class = "nb" > bool< / span > < span class = "p" > ,< / span >
< span class = "nb" > int< / span > < span class = "p" > ,< / span >
< span class = "nb" > float< / span > < span class = "p" > ,< / span >
< span class = "nb" > str< / span > < span class = "p" > ,< / span >
< span class = "c1" > # Other common types< / span >
< span class = "nb" > complex< / span > < span class = "p" > ,< / span >
< span class = "nb" > bytes< / span > < span class = "p" > ,< / span >
< span class = "c1" > # Other types that are also unaffected by deepcopy< / span >
< span class = "n" > types< / span > < span class = "o" > .< / span > < span class = "n" > EllipsisType< / span > < span class = "p" > ,< / span >
< span class = "n" > types< / span > < span class = "o" > .< / span > < span class = "n" > NotImplementedType< / span > < span class = "p" > ,< / span >
< span class = "n" > types< / span > < span class = "o" > .< / span > < span class = "n" > CodeType< / span > < span class = "p" > ,< / span >
< span class = "n" > types< / span > < span class = "o" > .< / span > < span class = "n" > BuiltinFunctionType< / span > < span class = "p" > ,< / span >
< span class = "n" > types< / span > < span class = "o" > .< / span > < span class = "n" > FunctionType< / span > < span class = "p" > ,< / span >
< span class = "nb" > type< / span > < span class = "p" > ,< / span >
< span class = "nb" > range< / span > < span class = "p" > ,< / span >
< span class = "nb" > property< / span > < span class = "p" > ,< / span >
< span class = "p" > })< / span >
< span class = "k" > class< / span > < span class = "w" > < / span > < span class = "nc" > InitVar< / span > < span class = "p" > :< / span >
< span class = "vm" > __slots__< / span > < span class = "o" > =< / span > < span class = "p" > (< / span > < span class = "s1" > ' type' < / span > < span class = "p" > ,< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "fm" > __init__< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "nb" > type< / span > < span class = "p" > ):< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > type< / span > < span class = "o" > =< / span > < span class = "nb" > type< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "fm" > __repr__< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ):< / span >
< span class = "k" > if< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > type< / span > < span class = "p" > ,< / span > < span class = "nb" > type< / span > < span class = "p" > ):< / span >
< span class = "n" > type_name< / span > < span class = "o" > =< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > type< / span > < span class = "o" > .< / span > < span class = "vm" > __name__< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "c1" > # typing objects, e.g. List[int]< / span >
< span class = "n" > type_name< / span > < span class = "o" > =< / span > < span class = "nb" > repr< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > type< / span > < span class = "p" > )< / span >
< span class = "k" > return< / span > < span class = "sa" > f< / span > < span class = "s1" > ' dataclasses.InitVar[< / span > < span class = "si" > {< / span > < span class = "n" > type_name< / span > < span class = "si" > }< / span > < span class = "s1" > ]' < / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > __class_getitem__< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "nb" > type< / span > < span class = "p" > ):< / span >
< span class = "k" > return< / span > < span class = "n" > InitVar< / span > < span class = "p" > (< / span > < span class = "nb" > type< / span > < span class = "p" > )< / span >
< span class = "c1" > # Instances of Field are only ever created from within this module,< / span >
< span class = "c1" > # and only from the field() function, although Field instances are< / span >
< span class = "c1" > # exposed externally as (conceptually) read-only objects.< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # name and type are filled in after the fact, not in __init__.< / span >
< span class = "c1" > # They' re not known at the time this class is instantiated, but it' s< / span >
< span class = "c1" > # convenient if they' re available later.< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # When cls._FIELDS is filled in with a list of Field objects, the name< / span >
< span class = "c1" > # and type fields will have been populated.< / span >
< span class = "k" > class< / span > < span class = "w" > < / span > < span class = "nc" > Field< / span > < span class = "p" > :< / span >
< span class = "vm" > __slots__< / span > < span class = "o" > =< / span > < span class = "p" > (< / span > < span class = "s1" > ' name' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' type' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' default' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' default_factory' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' repr' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' hash' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' init' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' compare' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' metadata' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' kw_only' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' _field_type' < / span > < span class = "p" > ,< / span > < span class = "c1" > # Private: not to be used by user code.< / span >
< span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "fm" > __init__< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "n" > default< / span > < span class = "p" > ,< / span > < span class = "n" > default_factory< / span > < span class = "p" > ,< / span > < span class = "n" > init< / span > < span class = "p" > ,< / span > < span class = "nb" > repr< / span > < span class = "p" > ,< / span > < span class = "nb" > hash< / span > < span class = "p" > ,< / span > < span class = "n" > compare< / span > < span class = "p" > ,< / span >
< span class = "n" > metadata< / span > < span class = "p" > ,< / span > < span class = "n" > kw_only< / span > < span class = "p" > ):< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > type< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "o" > =< / span > < span class = "n" > default< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > default_factory< / span > < span class = "o" > =< / span > < span class = "n" > default_factory< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > init< / span > < span class = "o" > =< / span > < span class = "n" > init< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > repr< / span > < span class = "o" > =< / span > < span class = "nb" > repr< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > hash< / span > < span class = "o" > =< / span > < span class = "nb" > hash< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > compare< / span > < span class = "o" > =< / span > < span class = "n" > compare< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > metadata< / span > < span class = "o" > =< / span > < span class = "p" > (< / span > < span class = "n" > _EMPTY_METADATA< / span >
< span class = "k" > if< / span > < span class = "n" > metadata< / span > < span class = "ow" > is< / span > < span class = "kc" > None< / span > < span class = "k" > else< / span >
< span class = "n" > types< / span > < span class = "o" > .< / span > < span class = "n" > MappingProxyType< / span > < span class = "p" > (< / span > < span class = "n" > metadata< / span > < span class = "p" > ))< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > kw_only< / span > < span class = "o" > =< / span > < span class = "n" > kw_only< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span >
< span class = "nd" > @recursive_repr< / span > < span class = "p" > ()< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "fm" > __repr__< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ):< / span >
< span class = "k" > return< / span > < span class = "p" > (< / span > < span class = "s1" > ' Field(' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' name=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' type=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > type< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' default=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' default_factory=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > default_factory< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' init=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > init< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' repr=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > repr< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' hash=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > hash< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' compare=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > compare< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' metadata=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > metadata< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' kw_only=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > kw_only< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' _field_type=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "si" > }< / span > < span class = "s1" > ' < / span >
< span class = "s1" > ' )' < / span > < span class = "p" > )< / span >
< span class = "c1" > # This is used to support the PEP 487 __set_name__ protocol in the< / span >
< span class = "c1" > # case where we' re using a field that contains a descriptor as a< / span >
< span class = "c1" > # default value. For details on __set_name__, see< / span >
< span class = "c1" > # https://peps.python.org/pep-0487/#implementation-details.< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # Note that in _process_class, this Field object is overwritten< / span >
< span class = "c1" > # with the default value, so the end result is a descriptor that< / span >
< span class = "c1" > # had __set_name__ called on it at the right time.< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > __set_name__< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "n" > owner< / span > < span class = "p" > ,< / span > < span class = "n" > name< / span > < span class = "p" > ):< / span >
< span class = "n" > func< / span > < span class = "o" > =< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "nb" > type< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "p" > ),< / span > < span class = "s1" > ' __set_name__' < / span > < span class = "p" > ,< / span > < span class = "kc" > None< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > func< / span > < span class = "p" > :< / span >
< span class = "c1" > # There is a __set_name__ method on the descriptor, call< / span >
< span class = "c1" > # it.< / span >
< span class = "n" > func< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "p" > ,< / span > < span class = "n" > owner< / span > < span class = "p" > ,< / span > < span class = "n" > name< / span > < span class = "p" > )< / span >
< span class = "n" > __class_getitem__< / span > < span class = "o" > =< / span > < span class = "nb" > classmethod< / span > < span class = "p" > (< / span > < span class = "n" > types< / span > < span class = "o" > .< / span > < span class = "n" > GenericAlias< / span > < span class = "p" > )< / span >
< span class = "k" > class< / span > < span class = "w" > < / span > < span class = "nc" > _DataclassParams< / span > < span class = "p" > :< / span >
< span class = "vm" > __slots__< / span > < span class = "o" > =< / span > < span class = "p" > (< / span > < span class = "s1" > ' init' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' repr' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' eq' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' order' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' unsafe_hash' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' frozen' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' match_args' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' kw_only' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' slots' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' weakref_slot' < / span > < span class = "p" > ,< / span >
< span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "fm" > __init__< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span >
< span class = "n" > init< / span > < span class = "p" > ,< / span > < span class = "nb" > repr< / span > < span class = "p" > ,< / span > < span class = "n" > eq< / span > < span class = "p" > ,< / span > < span class = "n" > order< / span > < span class = "p" > ,< / span > < span class = "n" > unsafe_hash< / span > < span class = "p" > ,< / span > < span class = "n" > frozen< / span > < span class = "p" > ,< / span >
< span class = "n" > match_args< / span > < span class = "p" > ,< / span > < span class = "n" > kw_only< / span > < span class = "p" > ,< / span > < span class = "n" > slots< / span > < span class = "p" > ,< / span > < span class = "n" > weakref_slot< / span > < span class = "p" > ):< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > init< / span > < span class = "o" > =< / span > < span class = "n" > init< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > repr< / span > < span class = "o" > =< / span > < span class = "nb" > repr< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > eq< / span > < span class = "o" > =< / span > < span class = "n" > eq< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > order< / span > < span class = "o" > =< / span > < span class = "n" > order< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > unsafe_hash< / span > < span class = "o" > =< / span > < span class = "n" > unsafe_hash< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > frozen< / span > < span class = "o" > =< / span > < span class = "n" > frozen< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > match_args< / span > < span class = "o" > =< / span > < span class = "n" > match_args< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > kw_only< / span > < span class = "o" > =< / span > < span class = "n" > kw_only< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > slots< / span > < span class = "o" > =< / span > < span class = "n" > slots< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > weakref_slot< / span > < span class = "o" > =< / span > < span class = "n" > weakref_slot< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "fm" > __repr__< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ):< / span >
< span class = "k" > return< / span > < span class = "p" > (< / span > < span class = "s1" > ' _DataclassParams(' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' init=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > init< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' repr=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > repr< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' eq=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > eq< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' order=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > order< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' unsafe_hash=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > unsafe_hash< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' frozen=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > frozen< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' match_args=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > match_args< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' kw_only=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > kw_only< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' slots=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > slots< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' weakref_slot=< / span > < span class = "si" > {< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > weakref_slot< / span > < span class = "si" > !r}< / span > < span class = "s1" > ' < / span >
< span class = "s1" > ' )' < / span > < span class = "p" > )< / span >
< span class = "c1" > # This function is used instead of exposing Field creation directly,< / span >
< span class = "c1" > # so that a type checker can be told (via overloads) that this is a< / span >
< span class = "c1" > # function whose type depends on its parameters.< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > field< / span > < span class = "p" > (< / span > < span class = "o" > *< / span > < span class = "p" > ,< / span > < span class = "n" > default< / span > < span class = "o" > =< / span > < span class = "n" > MISSING< / span > < span class = "p" > ,< / span > < span class = "n" > default_factory< / span > < span class = "o" > =< / span > < span class = "n" > MISSING< / span > < span class = "p" > ,< / span > < span class = "n" > init< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "nb" > repr< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span >
< span class = "nb" > hash< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span > < span class = "p" > ,< / span > < span class = "n" > compare< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "n" > metadata< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span > < span class = "p" > ,< / span > < span class = "n" > kw_only< / span > < span class = "o" > =< / span > < span class = "n" > MISSING< / span > < span class = "p" > ):< / span >
< span class = "w" > < / span > < span class = "sd" > " " " Return an object to identify dataclass fields.< / span >
< span class = "sd" > default is the default value of the field. default_factory is a< / span >
< span class = "sd" > 0-argument function called to initialize a field' s value. If init< / span >
< span class = "sd" > is true, the field will be a parameter to the class' s __init__()< / span >
< span class = "sd" > function. If repr is true, the field will be included in the< / span >
< span class = "sd" > object' s repr(). If hash is true, the field will be included in the< / span >
< span class = "sd" > object' s hash(). If compare is true, the field will be used in< / span >
< span class = "sd" > comparison functions. metadata, if specified, must be a mapping< / span >
< span class = "sd" > which is stored but not otherwise examined by dataclass. If kw_only< / span >
< span class = "sd" > is true, the field will become a keyword-only parameter to< / span >
< span class = "sd" > __init__().< / span >
< span class = "sd" > It is an error to specify both default and default_factory.< / span >
< span class = "sd" > " " " < / span >
< span class = "k" > if< / span > < span class = "n" > default< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "n" > MISSING< / span > < span class = "ow" > and< / span > < span class = "n" > default_factory< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > ValueError< / span > < span class = "p" > (< / span > < span class = "s1" > ' cannot specify both default and default_factory' < / span > < span class = "p" > )< / span >
< span class = "k" > return< / span > < span class = "n" > Field< / span > < span class = "p" > (< / span > < span class = "n" > default< / span > < span class = "p" > ,< / span > < span class = "n" > default_factory< / span > < span class = "p" > ,< / span > < span class = "n" > init< / span > < span class = "p" > ,< / span > < span class = "nb" > repr< / span > < span class = "p" > ,< / span > < span class = "nb" > hash< / span > < span class = "p" > ,< / span > < span class = "n" > compare< / span > < span class = "p" > ,< / span >
< span class = "n" > metadata< / span > < span class = "p" > ,< / span > < span class = "n" > kw_only< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _fields_in_init_order< / span > < span class = "p" > (< / span > < span class = "n" > fields< / span > < span class = "p" > ):< / span >
< span class = "c1" > # Returns the fields as __init__ will output them. It returns 2 tuples:< / span >
< span class = "c1" > # the first for normal args, and the second for keyword args.< / span >
< span class = "k" > return< / span > < span class = "p" > (< / span > < span class = "nb" > tuple< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > init< / span > < span class = "ow" > and< / span > < span class = "ow" > not< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > kw_only< / span > < span class = "p" > ),< / span >
< span class = "nb" > tuple< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > init< / span > < span class = "ow" > and< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > kw_only< / span > < span class = "p" > )< / span >
< span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _tuple_str< / span > < span class = "p" > (< / span > < span class = "n" > obj_name< / span > < span class = "p" > ,< / span > < span class = "n" > fields< / span > < span class = "p" > ):< / span >
< span class = "c1" > # Return a string representing each field of obj_name as a tuple< / span >
< span class = "c1" > # member. So, if fields is [' x' , ' y' ] and obj_name is " self" ,< / span >
< span class = "c1" > # return " (self.x,self.y)" .< / span >
< span class = "c1" > # Special case for the 0-tuple.< / span >
< span class = "k" > if< / span > < span class = "ow" > not< / span > < span class = "n" > fields< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "s1" > ' ()' < / span >
< span class = "c1" > # Note the trailing comma, needed if this turns out to be a 1-tuple.< / span >
< span class = "k" > return< / span > < span class = "sa" > f< / span > < span class = "s1" > ' (< / span > < span class = "si" > {< / span > < span class = "s2" > " ," < / span > < span class = "o" > .< / span > < span class = "n" > join< / span > < span class = "p" > ([< / span > < span class = "sa" > f< / span > < span class = "s2" > " < / span > < span class = "si" > {< / span > < span class = "n" > obj_name< / span > < span class = "si" > }< / span > < span class = "s2" > .< / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s2" > " < / span > < span class = "w" > < / span > < span class = "k" > for< / span > < span class = "w" > < / span > < span class = "n" > f< / span > < span class = "w" > < / span > < span class = "ow" > in< / span > < span class = "w" > < / span > < span class = "n" > fields< / span > < span class = "p" > ])< / span > < span class = "si" > }< / span > < span class = "s1" > ,)' < / span >
< span class = "k" > class< / span > < span class = "w" > < / span > < span class = "nc" > _FuncBuilder< / span > < span class = "p" > :< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "fm" > __init__< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "nb" > globals< / span > < span class = "p" > ):< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > names< / span > < span class = "o" > =< / span > < span class = "p" > []< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > src< / span > < span class = "o" > =< / span > < span class = "p" > []< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > globals< / span > < span class = "o" > =< / span > < span class = "nb" > globals< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > locals< / span > < span class = "o" > =< / span > < span class = "p" > {}< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > overwrite_errors< / span > < span class = "o" > =< / span > < span class = "p" > {}< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > unconditional_adds< / span > < span class = "o" > =< / span > < span class = "p" > {}< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > add_fn< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > args< / span > < span class = "p" > ,< / span > < span class = "n" > body< / span > < span class = "p" > ,< / span > < span class = "o" > *< / span > < span class = "p" > ,< / span > < span class = "nb" > locals< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span > < span class = "p" > ,< / span > < span class = "n" > return_type< / span > < span class = "o" > =< / span > < span class = "n" > MISSING< / span > < span class = "p" > ,< / span >
< span class = "n" > overwrite_error< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "n" > unconditional_add< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "n" > decorator< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span > < span class = "p" > ):< / span >
< span class = "k" > if< / span > < span class = "nb" > locals< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "kc" > None< / span > < span class = "p" > :< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > locals< / span > < span class = "o" > .< / span > < span class = "n" > update< / span > < span class = "p" > (< / span > < span class = "nb" > locals< / span > < span class = "p" > )< / span >
< span class = "c1" > # Keep track if this method is allowed to be overwritten if it already< / span >
< span class = "c1" > # exists in the class. The error is method-specific, so keep it with< / span >
< span class = "c1" > # the name. We' ll use this when we generate all of the functions in< / span >
< span class = "c1" > # the add_fns_to_class call. overwrite_error is either True, in which< / span >
< span class = "c1" > # case we' ll raise an error, or it' s a string, in which case we' ll< / span >
< span class = "c1" > # raise an error and append this string.< / span >
< span class = "k" > if< / span > < span class = "n" > overwrite_error< / span > < span class = "p" > :< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > overwrite_errors< / span > < span class = "p" > [< / span > < span class = "n" > name< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "n" > overwrite_error< / span >
< span class = "c1" > # Should this function always overwrite anything that' s already in the< / span >
< span class = "c1" > # class? The default is to not overwrite a function that already< / span >
< span class = "c1" > # exists.< / span >
< span class = "k" > if< / span > < span class = "n" > unconditional_add< / span > < span class = "p" > :< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > unconditional_adds< / span > < span class = "p" > [< / span > < span class = "n" > name< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > names< / span > < span class = "o" > .< / span > < span class = "n" > append< / span > < span class = "p" > (< / span > < span class = "n" > name< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > return_type< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > locals< / span > < span class = "p" > [< / span > < span class = "sa" > f< / span > < span class = "s1" > ' __dataclass_< / span > < span class = "si" > {< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > _return_type__' < / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "n" > return_type< / span >
< span class = "n" > return_annotation< / span > < span class = "o" > =< / span > < span class = "sa" > f< / span > < span class = "s1" > ' -> __dataclass_< / span > < span class = "si" > {< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > _return_type__' < / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "n" > return_annotation< / span > < span class = "o" > =< / span > < span class = "s1" > ' ' < / span >
< span class = "n" > args< / span > < span class = "o" > =< / span > < span class = "s1" > ' ,' < / span > < span class = "o" > .< / span > < span class = "n" > join< / span > < span class = "p" > (< / span > < span class = "n" > args< / span > < span class = "p" > )< / span >
< span class = "n" > body< / span > < span class = "o" > =< / span > < span class = "s1" > ' < / span > < span class = "se" > \n< / span > < span class = "s1" > ' < / span > < span class = "o" > .< / span > < span class = "n" > join< / span > < span class = "p" > (< / span > < span class = "n" > body< / span > < span class = "p" > )< / span >
< span class = "c1" > # Compute the text of the entire function, add it to the text we' re generating.< / span >
< span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > src< / span > < span class = "o" > .< / span > < span class = "n" > append< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' < / span > < span class = "si" > {< / span > < span class = "sa" > f< / span > < span class = "s1" > ' < / span > < span class = "si" > {< / span > < span class = "n" > decorator< / span > < span class = "si" > }< / span > < span class = "se" > \n< / span > < span class = "s1" > ' < / span > < span class = "w" > < / span > < span class = "k" > if< / span > < span class = "w" > < / span > < span class = "n" > decorator< / span > < span class = "w" > < / span > < span class = "k" > else< / span > < span class = "w" > < / span > < span class = "s1" > ' ' < / span > < span class = "si" > }< / span > < span class = "s1" > def < / span > < span class = "si" > {< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > (< / span > < span class = "si" > {< / span > < span class = "n" > args< / span > < span class = "si" > }< / span > < span class = "s1" > )< / span > < span class = "si" > {< / span > < span class = "n" > return_annotation< / span > < span class = "si" > }< / span > < span class = "s1" > :< / span > < span class = "se" > \n< / span > < span class = "si" > {< / span > < span class = "n" > body< / span > < span class = "si" > }< / span > < span class = "s1" > ' < / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > add_fns_to_class< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "bp" > cls< / span > < span class = "p" > ):< / span >
< span class = "c1" > # The source to all of the functions we' re generating.< / span >
< span class = "n" > fns_src< / span > < span class = "o" > =< / span > < span class = "s1" > ' < / span > < span class = "se" > \n< / span > < span class = "s1" > ' < / span > < span class = "o" > .< / span > < span class = "n" > join< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > src< / span > < span class = "p" > )< / span >
< span class = "c1" > # The locals they use.< / span >
< span class = "n" > local_vars< / span > < span class = "o" > =< / span > < span class = "s1" > ' ,' < / span > < span class = "o" > .< / span > < span class = "n" > join< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > locals< / span > < span class = "o" > .< / span > < span class = "n" > keys< / span > < span class = "p" > ())< / span >
< span class = "c1" > # The names of all of the functions, used for the return value of the< / span >
< span class = "c1" > # outer function. Need to handle the 0-tuple specially.< / span >
< span class = "k" > if< / span > < span class = "nb" > len< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > names< / span > < span class = "p" > )< / span > < span class = "o" > ==< / span > < span class = "mi" > 0< / span > < span class = "p" > :< / span >
< span class = "n" > return_names< / span > < span class = "o" > =< / span > < span class = "s1" > ' ()' < / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "n" > return_names< / span > < span class = "o" > =< / span > < span class = "sa" > f< / span > < span class = "s1" > ' (< / span > < span class = "si" > {< / span > < span class = "s2" > " ," < / span > < span class = "o" > .< / span > < span class = "n" > join< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > names< / span > < span class = "p" > )< / span > < span class = "si" > }< / span > < span class = "s1" > ,)' < / span >
< span class = "c1" > # txt is the entire function we' re going to execute, including the< / span >
< span class = "c1" > # bodies of the functions we' re defining. Here' s a greatly simplified< / span >
< span class = "c1" > # version:< / span >
< span class = "c1" > # def __create_fn__():< / span >
< span class = "c1" > # def __init__(self, x, y):< / span >
< span class = "c1" > # self.x = x< / span >
< span class = "c1" > # self.y = y< / span >
< span class = "c1" > # @recursive_repr< / span >
< span class = "c1" > # def __repr__(self):< / span >
< span class = "c1" > # return f" cls(x={self.x!r},y={self.y!r})" < / span >
< span class = "c1" > # return __init__,__repr__< / span >
< span class = "n" > txt< / span > < span class = "o" > =< / span > < span class = "sa" > f< / span > < span class = "s2" > " def __create_fn__(< / span > < span class = "si" > {< / span > < span class = "n" > local_vars< / span > < span class = "si" > }< / span > < span class = "s2" > ):< / span > < span class = "se" > \n< / span > < span class = "si" > {< / span > < span class = "n" > fns_src< / span > < span class = "si" > }< / span > < span class = "se" > \n< / span > < span class = "s2" > return < / span > < span class = "si" > {< / span > < span class = "n" > return_names< / span > < span class = "si" > }< / span > < span class = "s2" > " < / span >
< span class = "n" > ns< / span > < span class = "o" > =< / span > < span class = "p" > {}< / span >
< span class = "n" > exec< / span > < span class = "p" > (< / span > < span class = "n" > txt< / span > < span class = "p" > ,< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > globals< / span > < span class = "p" > ,< / span > < span class = "n" > ns< / span > < span class = "p" > )< / span >
< span class = "n" > fns< / span > < span class = "o" > =< / span > < span class = "n" > ns< / span > < span class = "p" > [< / span > < span class = "s1" > ' __create_fn__' < / span > < span class = "p" > ](< / span > < span class = "o" > **< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > locals< / span > < span class = "p" > )< / span >
< span class = "c1" > # Now that we' ve generated the functions, assign them into cls.< / span >
< span class = "k" > for< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > fn< / span > < span class = "ow" > in< / span > < span class = "nb" > zip< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > names< / span > < span class = "p" > ,< / span > < span class = "n" > fns< / span > < span class = "p" > ):< / span >
< span class = "n" > fn< / span > < span class = "o" > .< / span > < span class = "vm" > __qualname__< / span > < span class = "o" > =< / span > < span class = "sa" > f< / span > < span class = "s2" > " < / span > < span class = "si" > {< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __qualname__< / span > < span class = "si" > }< / span > < span class = "s2" > .< / span > < span class = "si" > {< / span > < span class = "n" > fn< / span > < span class = "o" > .< / span > < span class = "vm" > __name__< / span > < span class = "si" > }< / span > < span class = "s2" > " < / span >
< span class = "k" > if< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > unconditional_adds< / span > < span class = "o" > .< / span > < span class = "n" > get< / span > < span class = "p" > (< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ):< / span >
< span class = "nb" > setattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > fn< / span > < span class = "p" > )< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "n" > already_exists< / span > < span class = "o" > =< / span > < span class = "n" > _set_new_attribute< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > fn< / span > < span class = "p" > )< / span >
< span class = "c1" > # See if it' s an error to overwrite this particular function.< / span >
< span class = "k" > if< / span > < span class = "n" > already_exists< / span > < span class = "ow" > and< / span > < span class = "p" > (< / span > < span class = "n" > msg_extra< / span > < span class = "o" > :=< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "n" > overwrite_errors< / span > < span class = "o" > .< / span > < span class = "n" > get< / span > < span class = "p" > (< / span > < span class = "n" > name< / span > < span class = "p" > )):< / span >
< span class = "n" > error_msg< / span > < span class = "o" > =< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' Cannot overwrite attribute < / span > < span class = "si" > {< / span > < span class = "n" > fn< / span > < span class = "o" > .< / span > < span class = "vm" > __name__< / span > < span class = "si" > }< / span > < span class = "s1" > ' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' in class < / span > < span class = "si" > {< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __name__< / span > < span class = "si" > }< / span > < span class = "s1" > ' < / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "ow" > not< / span > < span class = "n" > msg_extra< / span > < span class = "ow" > is< / span > < span class = "kc" > True< / span > < span class = "p" > :< / span >
< span class = "n" > error_msg< / span > < span class = "o" > =< / span > < span class = "sa" > f< / span > < span class = "s1" > ' < / span > < span class = "si" > {< / span > < span class = "n" > error_msg< / span > < span class = "si" > }< / span > < span class = "s1" > < / span > < span class = "si" > {< / span > < span class = "n" > msg_extra< / span > < span class = "si" > }< / span > < span class = "s1" > ' < / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "n" > error_msg< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _field_assign< / span > < span class = "p" > (< / span > < span class = "n" > frozen< / span > < span class = "p" > ,< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > value< / span > < span class = "p" > ,< / span > < span class = "n" > self_name< / span > < span class = "p" > ):< / span >
< span class = "c1" > # If we' re a frozen class, then assign to our fields in __init__< / span >
< span class = "c1" > # via object.__setattr__. Otherwise, just use a simple< / span >
< span class = "c1" > # assignment.< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # self_name is what " self" is called in this function: don' t< / span >
< span class = "c1" > # hard-code " self" , since that might be a field name.< / span >
< span class = "k" > if< / span > < span class = "n" > frozen< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "sa" > f< / span > < span class = "s1" > ' __dataclass_builtins_object__.__setattr__(< / span > < span class = "si" > {< / span > < span class = "n" > self_name< / span > < span class = "si" > }< / span > < span class = "s1" > ,< / span > < span class = "si" > {< / span > < span class = "n" > name< / span > < span class = "si" > !r}< / span > < span class = "s1" > ,< / span > < span class = "si" > {< / span > < span class = "n" > value< / span > < span class = "si" > }< / span > < span class = "s1" > )' < / span >
< span class = "k" > return< / span > < span class = "sa" > f< / span > < span class = "s1" > ' < / span > < span class = "si" > {< / span > < span class = "n" > self_name< / span > < span class = "si" > }< / span > < span class = "s1" > .< / span > < span class = "si" > {< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > =< / span > < span class = "si" > {< / span > < span class = "n" > value< / span > < span class = "si" > }< / span > < span class = "s1" > ' < / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _field_init< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "p" > ,< / span > < span class = "n" > frozen< / span > < span class = "p" > ,< / span > < span class = "nb" > globals< / span > < span class = "p" > ,< / span > < span class = "n" > self_name< / span > < span class = "p" > ,< / span > < span class = "n" > slots< / span > < span class = "p" > ):< / span >
< span class = "c1" > # Return the text of the line in the body of __init__ that will< / span >
< span class = "c1" > # initialize this field.< / span >
< span class = "n" > default_name< / span > < span class = "o" > =< / span > < span class = "sa" > f< / span > < span class = "s1" > ' __dataclass_dflt_< / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > __' < / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default_factory< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > init< / span > < span class = "p" > :< / span >
< span class = "c1" > # This field has a default factory. If a parameter is< / span >
< span class = "c1" > # given, use it. If not, call the factory.< / span >
< span class = "nb" > globals< / span > < span class = "p" > [< / span > < span class = "n" > default_name< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default_factory< / span >
< span class = "n" > value< / span > < span class = "o" > =< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' < / span > < span class = "si" > {< / span > < span class = "n" > default_name< / span > < span class = "si" > }< / span > < span class = "s1" > () ' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' if < / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > is __dataclass_HAS_DEFAULT_FACTORY__ ' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' else < / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > ' < / span > < span class = "p" > )< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "c1" > # This is a field that' s not in the __init__ params, but< / span >
< span class = "c1" > # has a default factory function. It needs to be< / span >
< span class = "c1" > # initialized here by calling the factory function,< / span >
< span class = "c1" > # because there' s no other way to initialize it.< / span >
< span class = "c1" > # For a field initialized with a default=defaultvalue, the< / span >
< span class = "c1" > # class dict just has the default value< / span >
< span class = "c1" > # (cls.fieldname=defaultvalue). But that won' t work for a< / span >
< span class = "c1" > # default factory, the factory must be called in __init__< / span >
< span class = "c1" > # and we must assign that to self.fieldname. We can' t< / span >
< span class = "c1" > # fall back to the class dict' s value, both because it' s< / span >
< span class = "c1" > # not set, and because it might be different per-class< / span >
< span class = "c1" > # (which, after all, is why we have a factory function!).< / span >
< span class = "nb" > globals< / span > < span class = "p" > [< / span > < span class = "n" > default_name< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default_factory< / span >
< span class = "n" > value< / span > < span class = "o" > =< / span > < span class = "sa" > f< / span > < span class = "s1" > ' < / span > < span class = "si" > {< / span > < span class = "n" > default_name< / span > < span class = "si" > }< / span > < span class = "s1" > ()' < / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "c1" > # No default factory.< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > init< / span > < span class = "p" > :< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "ow" > is< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "c1" > # There' s no default, just do an assignment.< / span >
< span class = "n" > value< / span > < span class = "o" > =< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span >
< span class = "k" > elif< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "nb" > globals< / span > < span class = "p" > [< / span > < span class = "n" > default_name< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span >
< span class = "n" > value< / span > < span class = "o" > =< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "c1" > # If the class has slots, then initialize this field.< / span >
< span class = "k" > if< / span > < span class = "n" > slots< / span > < span class = "ow" > and< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "nb" > globals< / span > < span class = "p" > [< / span > < span class = "n" > default_name< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span >
< span class = "n" > value< / span > < span class = "o" > =< / span > < span class = "n" > default_name< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "c1" > # This field does not need initialization: reading from it will< / span >
< span class = "c1" > # just use the class attribute that contains the default.< / span >
< span class = "c1" > # Signify that to the caller by returning None.< / span >
< span class = "k" > return< / span > < span class = "kc" > None< / span >
< span class = "c1" > # Only test this now, so that we can create variables for the< / span >
< span class = "c1" > # default. However, return None to signify that we' re not going< / span >
< span class = "c1" > # to actually do the assignment statement for InitVars.< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "ow" > is< / span > < span class = "n" > _FIELD_INITVAR< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "kc" > None< / span >
< span class = "c1" > # Now, actually generate the field assignment.< / span >
< span class = "k" > return< / span > < span class = "n" > _field_assign< / span > < span class = "p" > (< / span > < span class = "n" > frozen< / span > < span class = "p" > ,< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > value< / span > < span class = "p" > ,< / span > < span class = "n" > self_name< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _init_param< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "p" > ):< / span >
< span class = "c1" > # Return the __init__ parameter string for this field. For< / span >
< span class = "c1" > # example, the equivalent of ' x:int=3' (except instead of ' int' ,< / span >
< span class = "c1" > # reference a variable set to int, and instead of ' 3' , reference a< / span >
< span class = "c1" > # variable set to 3).< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "ow" > is< / span > < span class = "n" > MISSING< / span > < span class = "ow" > and< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default_factory< / span > < span class = "ow" > is< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "c1" > # There' s no default, and no default_factory, just output the< / span >
< span class = "c1" > # variable name and type.< / span >
< span class = "n" > default< / span > < span class = "o" > =< / span > < span class = "s1" > ' ' < / span >
< span class = "k" > elif< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "c1" > # There' s a default, this will be the name that' s used to look< / span >
< span class = "c1" > # it up.< / span >
< span class = "n" > default< / span > < span class = "o" > =< / span > < span class = "sa" > f< / span > < span class = "s1" > ' =__dataclass_dflt_< / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > __' < / span >
< span class = "k" > elif< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default_factory< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "c1" > # There' s a factory function. Set a marker.< / span >
< span class = "n" > default< / span > < span class = "o" > =< / span > < span class = "s1" > ' =__dataclass_HAS_DEFAULT_FACTORY__' < / span >
< span class = "k" > return< / span > < span class = "sa" > f< / span > < span class = "s1" > ' < / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > :__dataclass_type_< / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > __< / span > < span class = "si" > {< / span > < span class = "n" > default< / span > < span class = "si" > }< / span > < span class = "s1" > ' < / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _init_fn< / span > < span class = "p" > (< / span > < span class = "n" > fields< / span > < span class = "p" > ,< / span > < span class = "n" > std_fields< / span > < span class = "p" > ,< / span > < span class = "n" > kw_only_fields< / span > < span class = "p" > ,< / span > < span class = "n" > frozen< / span > < span class = "p" > ,< / span > < span class = "n" > has_post_init< / span > < span class = "p" > ,< / span >
< span class = "n" > self_name< / span > < span class = "p" > ,< / span > < span class = "n" > func_builder< / span > < span class = "p" > ,< / span > < span class = "n" > slots< / span > < span class = "p" > ):< / span >
< span class = "c1" > # fields contains both real fields and InitVar pseudo-fields.< / span >
< span class = "c1" > # Make sure we don' t have fields without defaults following fields< / span >
< span class = "c1" > # with defaults. This actually would be caught when exec-ing the< / span >
< span class = "c1" > # function source code, but catching it here gives a better error< / span >
< span class = "c1" > # message, and future-proofs us in case we build up the function< / span >
< span class = "c1" > # using ast.< / span >
< span class = "n" > seen_default< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span >
< span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > std_fields< / span > < span class = "p" > :< / span >
< span class = "c1" > # Only consider the non-kw-only fields in the __init__ call.< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > init< / span > < span class = "p" > :< / span >
< span class = "k" > if< / span > < span class = "ow" > not< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "ow" > is< / span > < span class = "n" > MISSING< / span > < span class = "ow" > and< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default_factory< / span > < span class = "ow" > is< / span > < span class = "n" > MISSING< / span > < span class = "p" > ):< / span >
< span class = "n" > seen_default< / span > < span class = "o" > =< / span > < span class = "n" > f< / span >
< span class = "k" > elif< / span > < span class = "n" > seen_default< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' non-default argument < / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > !r}< / span > < span class = "s1" > ' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' follows default argument < / span > < span class = "si" > {< / span > < span class = "n" > seen_default< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > !r}< / span > < span class = "s1" > ' < / span > < span class = "p" > )< / span >
< span class = "nb" > locals< / span > < span class = "o" > =< / span > < span class = "p" > {< / span > < span class = "o" > **< / span > < span class = "p" > {< / span > < span class = "sa" > f< / span > < span class = "s1" > ' __dataclass_type_< / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > __' < / span > < span class = "p" > :< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > type< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "p" > },< / span >
< span class = "o" > **< / span > < span class = "p" > {< / span > < span class = "s1" > ' __dataclass_HAS_DEFAULT_FACTORY__' < / span > < span class = "p" > :< / span > < span class = "n" > _HAS_DEFAULT_FACTORY< / span > < span class = "p" > ,< / span >
< span class = "s1" > ' __dataclass_builtins_object__' < / span > < span class = "p" > :< / span > < span class = "nb" > object< / span > < span class = "p" > ,< / span >
< span class = "p" > }< / span >
< span class = "p" > }< / span >
< span class = "n" > body_lines< / span > < span class = "o" > =< / span > < span class = "p" > []< / span >
< span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "p" > :< / span >
< span class = "n" > line< / span > < span class = "o" > =< / span > < span class = "n" > _field_init< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "p" > ,< / span > < span class = "n" > frozen< / span > < span class = "p" > ,< / span > < span class = "nb" > locals< / span > < span class = "p" > ,< / span > < span class = "n" > self_name< / span > < span class = "p" > ,< / span > < span class = "n" > slots< / span > < span class = "p" > )< / span >
< span class = "c1" > # line is None means that this field doesn' t require< / span >
< span class = "c1" > # initialization (it' s a pseudo-field). Just skip it.< / span >
< span class = "k" > if< / span > < span class = "n" > line< / span > < span class = "p" > :< / span >
< span class = "n" > body_lines< / span > < span class = "o" > .< / span > < span class = "n" > append< / span > < span class = "p" > (< / span > < span class = "n" > line< / span > < span class = "p" > )< / span >
< span class = "c1" > # Does this class have a post-init function?< / span >
< span class = "k" > if< / span > < span class = "n" > has_post_init< / span > < span class = "p" > :< / span >
< span class = "n" > params_str< / span > < span class = "o" > =< / span > < span class = "s1" > ' ,' < / span > < span class = "o" > .< / span > < span class = "n" > join< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "ow" > is< / span > < span class = "n" > _FIELD_INITVAR< / span > < span class = "p" > )< / span >
< span class = "n" > body_lines< / span > < span class = "o" > .< / span > < span class = "n" > append< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' < / span > < span class = "si" > {< / span > < span class = "n" > self_name< / span > < span class = "si" > }< / span > < span class = "s1" > .< / span > < span class = "si" > {< / span > < span class = "n" > _POST_INIT_NAME< / span > < span class = "si" > }< / span > < span class = "s1" > (< / span > < span class = "si" > {< / span > < span class = "n" > params_str< / span > < span class = "si" > }< / span > < span class = "s1" > )' < / span > < span class = "p" > )< / span >
< span class = "c1" > # If no body lines, use ' pass' .< / span >
< span class = "k" > if< / span > < span class = "ow" > not< / span > < span class = "n" > body_lines< / span > < span class = "p" > :< / span >
< span class = "n" > body_lines< / span > < span class = "o" > =< / span > < span class = "p" > [< / span > < span class = "s1" > ' pass' < / span > < span class = "p" > ]< / span >
< span class = "n" > _init_params< / span > < span class = "o" > =< / span > < span class = "p" > [< / span > < span class = "n" > _init_param< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "p" > )< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > std_fields< / span > < span class = "p" > ]< / span >
< span class = "k" > if< / span > < span class = "n" > kw_only_fields< / span > < span class = "p" > :< / span >
< span class = "c1" > # Add the keyword-only args. Because the * can only be added if< / span >
< span class = "c1" > # there' s at least one keyword-only arg, there needs to be a test here< / span >
< span class = "c1" > # (instead of just concatenting the lists together).< / span >
< span class = "n" > _init_params< / span > < span class = "o" > +=< / span > < span class = "p" > [< / span > < span class = "s1" > ' *' < / span > < span class = "p" > ]< / span >
< span class = "n" > _init_params< / span > < span class = "o" > +=< / span > < span class = "p" > [< / span > < span class = "n" > _init_param< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "p" > )< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > kw_only_fields< / span > < span class = "p" > ]< / span >
< span class = "n" > func_builder< / span > < span class = "o" > .< / span > < span class = "n" > add_fn< / span > < span class = "p" > (< / span > < span class = "s1" > ' __init__' < / span > < span class = "p" > ,< / span >
< span class = "p" > [< / span > < span class = "n" > self_name< / span > < span class = "p" > ]< / span > < span class = "o" > +< / span > < span class = "n" > _init_params< / span > < span class = "p" > ,< / span >
< span class = "n" > body_lines< / span > < span class = "p" > ,< / span >
< span class = "nb" > locals< / span > < span class = "o" > =< / span > < span class = "nb" > locals< / span > < span class = "p" > ,< / span >
< span class = "n" > return_type< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _frozen_get_del_attr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > fields< / span > < span class = "p" > ,< / span > < span class = "n" > func_builder< / span > < span class = "p" > ):< / span >
< span class = "nb" > locals< / span > < span class = "o" > =< / span > < span class = "p" > {< / span > < span class = "s1" > ' cls' < / span > < span class = "p" > :< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span >
< span class = "s1" > ' FrozenInstanceError' < / span > < span class = "p" > :< / span > < span class = "n" > FrozenInstanceError< / span > < span class = "p" > }< / span >
< span class = "n" > condition< / span > < span class = "o" > =< / span > < span class = "s1" > ' type(self) is cls' < / span >
< span class = "k" > if< / span > < span class = "n" > fields< / span > < span class = "p" > :< / span >
< span class = "n" > condition< / span > < span class = "o" > +=< / span > < span class = "s1" > ' or name in {' < / span > < span class = "o" > +< / span > < span class = "s1" > ' , ' < / span > < span class = "o" > .< / span > < span class = "n" > join< / span > < span class = "p" > (< / span > < span class = "nb" > repr< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > )< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "p" > )< / span > < span class = "o" > +< / span > < span class = "s1" > ' }' < / span >
< span class = "n" > func_builder< / span > < span class = "o" > .< / span > < span class = "n" > add_fn< / span > < span class = "p" > (< / span > < span class = "s1" > ' __setattr__' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' self' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' name' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' value' < / span > < span class = "p" > ),< / span >
< span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' if < / span > < span class = "si" > {< / span > < span class = "n" > condition< / span > < span class = "si" > }< / span > < span class = "s1" > :' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' raise FrozenInstanceError(f" cannot assign to field < / span > < span class = "si" > {name!r}< / span > < span class = "s1" > " )' < / span > < span class = "p" > ,< / span >
< span class = "sa" > f< / span > < span class = "s1" > ' super(cls, self).__setattr__(name, value)' < / span > < span class = "p" > ),< / span >
< span class = "nb" > locals< / span > < span class = "o" > =< / span > < span class = "nb" > locals< / span > < span class = "p" > ,< / span >
< span class = "n" > overwrite_error< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > )< / span >
< span class = "n" > func_builder< / span > < span class = "o" > .< / span > < span class = "n" > add_fn< / span > < span class = "p" > (< / span > < span class = "s1" > ' __delattr__' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' self' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' name' < / span > < span class = "p" > ),< / span >
< span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' if < / span > < span class = "si" > {< / span > < span class = "n" > condition< / span > < span class = "si" > }< / span > < span class = "s1" > :' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' raise FrozenInstanceError(f" cannot delete field < / span > < span class = "si" > {name!r}< / span > < span class = "s1" > " )' < / span > < span class = "p" > ,< / span >
< span class = "sa" > f< / span > < span class = "s1" > ' super(cls, self).__delattr__(name)' < / span > < span class = "p" > ),< / span >
< span class = "nb" > locals< / span > < span class = "o" > =< / span > < span class = "nb" > locals< / span > < span class = "p" > ,< / span >
< span class = "n" > overwrite_error< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _is_classvar< / span > < span class = "p" > (< / span > < span class = "n" > a_type< / span > < span class = "p" > ,< / span > < span class = "n" > typing< / span > < span class = "p" > ):< / span >
< span class = "c1" > # This test uses a typing internal class, but it' s the best way to< / span >
< span class = "c1" > # test if this is a ClassVar.< / span >
< span class = "k" > return< / span > < span class = "p" > (< / span > < span class = "n" > a_type< / span > < span class = "ow" > is< / span > < span class = "n" > typing< / span > < span class = "o" > .< / span > < span class = "n" > ClassVar< / span >
< span class = "ow" > or< / span > < span class = "p" > (< / span > < span class = "nb" > type< / span > < span class = "p" > (< / span > < span class = "n" > a_type< / span > < span class = "p" > )< / span > < span class = "ow" > is< / span > < span class = "n" > typing< / span > < span class = "o" > .< / span > < span class = "n" > _GenericAlias< / span >
< span class = "ow" > and< / span > < span class = "n" > a_type< / span > < span class = "o" > .< / span > < span class = "n" > __origin__< / span > < span class = "ow" > is< / span > < span class = "n" > typing< / span > < span class = "o" > .< / span > < span class = "n" > ClassVar< / span > < span class = "p" > ))< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _is_initvar< / span > < span class = "p" > (< / span > < span class = "n" > a_type< / span > < span class = "p" > ,< / span > < span class = "n" > dataclasses< / span > < span class = "p" > ):< / span >
< span class = "c1" > # The module we' re checking against is the module we' re< / span >
< span class = "c1" > # currently in (dataclasses.py).< / span >
< span class = "k" > return< / span > < span class = "p" > (< / span > < span class = "n" > a_type< / span > < span class = "ow" > is< / span > < span class = "n" > dataclasses< / span > < span class = "o" > .< / span > < span class = "n" > InitVar< / span >
< span class = "ow" > or< / span > < span class = "nb" > type< / span > < span class = "p" > (< / span > < span class = "n" > a_type< / span > < span class = "p" > )< / span > < span class = "ow" > is< / span > < span class = "n" > dataclasses< / span > < span class = "o" > .< / span > < span class = "n" > InitVar< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _is_kw_only< / span > < span class = "p" > (< / span > < span class = "n" > a_type< / span > < span class = "p" > ,< / span > < span class = "n" > dataclasses< / span > < span class = "p" > ):< / span >
< span class = "k" > return< / span > < span class = "n" > a_type< / span > < span class = "ow" > is< / span > < span class = "n" > dataclasses< / span > < span class = "o" > .< / span > < span class = "n" > KW_ONLY< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _is_type< / span > < span class = "p" > (< / span > < span class = "n" > annotation< / span > < span class = "p" > ,< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > a_module< / span > < span class = "p" > ,< / span > < span class = "n" > a_type< / span > < span class = "p" > ,< / span > < span class = "n" > is_type_predicate< / span > < span class = "p" > ):< / span >
< span class = "c1" > # Given a type annotation string, does it refer to a_type in< / span >
< span class = "c1" > # a_module? For example, when checking that annotation denotes a< / span >
< span class = "c1" > # ClassVar, then a_module is typing, and a_type is< / span >
< span class = "c1" > # typing.ClassVar.< / span >
< span class = "c1" > # It' s possible to look up a_module given a_type, but it involves< / span >
< span class = "c1" > # looking in sys.modules (again!), and seems like a waste since< / span >
< span class = "c1" > # the caller already knows a_module.< / span >
< span class = "c1" > # - annotation is a string type annotation< / span >
< span class = "c1" > # - cls is the class that this annotation was found in< / span >
< span class = "c1" > # - a_module is the module we want to match< / span >
< span class = "c1" > # - a_type is the type in that module we want to match< / span >
< span class = "c1" > # - is_type_predicate is a function called with (obj, a_module)< / span >
< span class = "c1" > # that determines if obj is of the desired type.< / span >
< span class = "c1" > # Since this test does not do a local namespace lookup (and< / span >
< span class = "c1" > # instead only a module (global) lookup), there are some things it< / span >
< span class = "c1" > # gets wrong.< / span >
< span class = "c1" > # With string annotations, cv0 will be detected as a ClassVar:< / span >
< span class = "c1" > # CV = ClassVar< / span >
< span class = "c1" > # @dataclass< / span >
< span class = "c1" > # class C0:< / span >
< span class = "c1" > # cv0: CV< / span >
< span class = "c1" > # But in this example cv1 will not be detected as a ClassVar:< / span >
< span class = "c1" > # @dataclass< / span >
< span class = "c1" > # class C1:< / span >
< span class = "c1" > # CV = ClassVar< / span >
< span class = "c1" > # cv1: CV< / span >
< span class = "c1" > # In C1, the code in this function (_is_type) will look up " CV" in< / span >
< span class = "c1" > # the module and not find it, so it will not consider cv1 as a< / span >
< span class = "c1" > # ClassVar. This is a fairly obscure corner case, and the best< / span >
< span class = "c1" > # way to fix it would be to eval() the string " CV" with the< / span >
< span class = "c1" > # correct global and local namespaces. However that would involve< / span >
< span class = "c1" > # a eval() penalty for every single field of every dataclass< / span >
< span class = "c1" > # that' s defined. It was judged not worth it.< / span >
< span class = "n" > match< / span > < span class = "o" > =< / span > < span class = "n" > _MODULE_IDENTIFIER_RE< / span > < span class = "o" > .< / span > < span class = "n" > match< / span > < span class = "p" > (< / span > < span class = "n" > annotation< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > match< / span > < span class = "p" > :< / span >
< span class = "n" > ns< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span >
< span class = "n" > module_name< / span > < span class = "o" > =< / span > < span class = "n" > match< / span > < span class = "o" > .< / span > < span class = "n" > group< / span > < span class = "p" > (< / span > < span class = "mi" > 1< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "ow" > not< / span > < span class = "n" > module_name< / span > < span class = "p" > :< / span >
< span class = "c1" > # No module name, assume the class' s module did< / span >
< span class = "c1" > # " from dataclasses import InitVar" .< / span >
< span class = "n" > ns< / span > < span class = "o" > =< / span > < span class = "n" > sys< / span > < span class = "o" > .< / span > < span class = "n" > modules< / span > < span class = "o" > .< / span > < span class = "n" > get< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __module__< / span > < span class = "p" > )< / span > < span class = "o" > .< / span > < span class = "vm" > __dict__< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "c1" > # Look up module_name in the class' s module.< / span >
< span class = "n" > module< / span > < span class = "o" > =< / span > < span class = "n" > sys< / span > < span class = "o" > .< / span > < span class = "n" > modules< / span > < span class = "o" > .< / span > < span class = "n" > get< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __module__< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > module< / span > < span class = "ow" > and< / span > < span class = "n" > module< / span > < span class = "o" > .< / span > < span class = "vm" > __dict__< / span > < span class = "o" > .< / span > < span class = "n" > get< / span > < span class = "p" > (< / span > < span class = "n" > module_name< / span > < span class = "p" > )< / span > < span class = "ow" > is< / span > < span class = "n" > a_module< / span > < span class = "p" > :< / span >
< span class = "n" > ns< / span > < span class = "o" > =< / span > < span class = "n" > sys< / span > < span class = "o" > .< / span > < span class = "n" > modules< / span > < span class = "o" > .< / span > < span class = "n" > get< / span > < span class = "p" > (< / span > < span class = "n" > a_type< / span > < span class = "o" > .< / span > < span class = "vm" > __module__< / span > < span class = "p" > )< / span > < span class = "o" > .< / span > < span class = "vm" > __dict__< / span >
< span class = "k" > if< / span > < span class = "n" > ns< / span > < span class = "ow" > and< / span > < span class = "n" > is_type_predicate< / span > < span class = "p" > (< / span > < span class = "n" > ns< / span > < span class = "o" > .< / span > < span class = "n" > get< / span > < span class = "p" > (< / span > < span class = "n" > match< / span > < span class = "o" > .< / span > < span class = "n" > group< / span > < span class = "p" > (< / span > < span class = "mi" > 2< / span > < span class = "p" > )),< / span > < span class = "n" > a_module< / span > < span class = "p" > ):< / span >
< span class = "k" > return< / span > < span class = "kc" > True< / span >
< span class = "k" > return< / span > < span class = "kc" > False< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _get_field< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > a_name< / span > < span class = "p" > ,< / span > < span class = "n" > a_type< / span > < span class = "p" > ,< / span > < span class = "n" > default_kw_only< / span > < span class = "p" > ):< / span >
< span class = "c1" > # Return a Field object for this field name and type. ClassVars and< / span >
< span class = "c1" > # InitVars are also returned, but marked as such (see f._field_type).< / span >
< span class = "c1" > # default_kw_only is the value of kw_only to use if there isn' t a field()< / span >
< span class = "c1" > # that defines it.< / span >
< span class = "c1" > # If the default value isn' t derived from Field, then it' s only a< / span >
< span class = "c1" > # normal default value. Convert it to a Field().< / span >
< span class = "n" > default< / span > < span class = "o" > =< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > a_name< / span > < span class = "p" > ,< / span > < span class = "n" > MISSING< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "n" > default< / span > < span class = "p" > ,< / span > < span class = "n" > Field< / span > < span class = "p" > ):< / span >
< span class = "n" > f< / span > < span class = "o" > =< / span > < span class = "n" > default< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "k" > if< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "n" > default< / span > < span class = "p" > ,< / span > < span class = "n" > types< / span > < span class = "o" > .< / span > < span class = "n" > MemberDescriptorType< / span > < span class = "p" > ):< / span >
< span class = "c1" > # This is a field in __slots__, so it has no default value.< / span >
< span class = "n" > default< / span > < span class = "o" > =< / span > < span class = "n" > MISSING< / span >
< span class = "n" > f< / span > < span class = "o" > =< / span > < span class = "n" > field< / span > < span class = "p" > (< / span > < span class = "n" > default< / span > < span class = "o" > =< / span > < span class = "n" > default< / span > < span class = "p" > )< / span >
< span class = "c1" > # Only at this point do we know the name and the type. Set them.< / span >
< span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "o" > =< / span > < span class = "n" > a_name< / span >
< span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > type< / span > < span class = "o" > =< / span > < span class = "n" > a_type< / span >
< span class = "c1" > # Assume it' s a normal field until proven otherwise. We' re next< / span >
< span class = "c1" > # going to decide if it' s a ClassVar or InitVar, everything else< / span >
< span class = "c1" > # is just a normal field.< / span >
< span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "o" > =< / span > < span class = "n" > _FIELD< / span >
< span class = "c1" > # In addition to checking for actual types here, also check for< / span >
< span class = "c1" > # string annotations. get_type_hints() won' t always work for us< / span >
< span class = "c1" > # (see https://github.com/python/typing/issues/508 for example),< / span >
< span class = "c1" > # plus it' s expensive and would require an eval for every string< / span >
< span class = "c1" > # annotation. So, make a best effort to see if this is a ClassVar< / span >
< span class = "c1" > # or InitVar using regex' s and checking that the thing referenced< / span >
< span class = "c1" > # is actually of the correct type.< / span >
< span class = "c1" > # For the complete discussion, see https://bugs.python.org/issue33453< / span >
< span class = "c1" > # If typing has not been imported, then it' s impossible for any< / span >
< span class = "c1" > # annotation to be a ClassVar. So, only look for ClassVar if< / span >
< span class = "c1" > # typing has been imported by any module (not necessarily cls' s< / span >
< span class = "c1" > # module).< / span >
< span class = "n" > typing< / span > < span class = "o" > =< / span > < span class = "n" > sys< / span > < span class = "o" > .< / span > < span class = "n" > modules< / span > < span class = "o" > .< / span > < span class = "n" > get< / span > < span class = "p" > (< / span > < span class = "s1" > ' typing' < / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > typing< / span > < span class = "p" > :< / span >
< span class = "k" > if< / span > < span class = "p" > (< / span > < span class = "n" > _is_classvar< / span > < span class = "p" > (< / span > < span class = "n" > a_type< / span > < span class = "p" > ,< / span > < span class = "n" > typing< / span > < span class = "p" > )< / span >
< span class = "ow" > or< / span > < span class = "p" > (< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > type< / span > < span class = "p" > ,< / span > < span class = "nb" > str< / span > < span class = "p" > )< / span >
< span class = "ow" > and< / span > < span class = "n" > _is_type< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > type< / span > < span class = "p" > ,< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > typing< / span > < span class = "p" > ,< / span > < span class = "n" > typing< / span > < span class = "o" > .< / span > < span class = "n" > ClassVar< / span > < span class = "p" > ,< / span >
< span class = "n" > _is_classvar< / span > < span class = "p" > ))):< / span >
< span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "o" > =< / span > < span class = "n" > _FIELD_CLASSVAR< / span >
< span class = "c1" > # If the type is InitVar, or if it' s a matching string annotation,< / span >
< span class = "c1" > # then it' s an InitVar.< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "ow" > is< / span > < span class = "n" > _FIELD< / span > < span class = "p" > :< / span >
< span class = "c1" > # The module we' re checking against is the module we' re< / span >
< span class = "c1" > # currently in (dataclasses.py).< / span >
< span class = "n" > dataclasses< / span > < span class = "o" > =< / span > < span class = "n" > sys< / span > < span class = "o" > .< / span > < span class = "n" > modules< / span > < span class = "p" > [< / span > < span class = "vm" > __name__< / span > < span class = "p" > ]< / span >
< span class = "k" > if< / span > < span class = "p" > (< / span > < span class = "n" > _is_initvar< / span > < span class = "p" > (< / span > < span class = "n" > a_type< / span > < span class = "p" > ,< / span > < span class = "n" > dataclasses< / span > < span class = "p" > )< / span >
< span class = "ow" > or< / span > < span class = "p" > (< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > type< / span > < span class = "p" > ,< / span > < span class = "nb" > str< / span > < span class = "p" > )< / span >
< span class = "ow" > and< / span > < span class = "n" > _is_type< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > type< / span > < span class = "p" > ,< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > dataclasses< / span > < span class = "p" > ,< / span > < span class = "n" > dataclasses< / span > < span class = "o" > .< / span > < span class = "n" > InitVar< / span > < span class = "p" > ,< / span >
< span class = "n" > _is_initvar< / span > < span class = "p" > ))):< / span >
< span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "o" > =< / span > < span class = "n" > _FIELD_INITVAR< / span >
< span class = "c1" > # Validations for individual fields. This is delayed until now,< / span >
< span class = "c1" > # instead of in the Field() constructor, since only here do we< / span >
< span class = "c1" > # know the field name, which allows for better error reporting.< / span >
< span class = "c1" > # Special restrictions for ClassVar and InitVar.< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "ow" > in< / span > < span class = "p" > (< / span > < span class = "n" > _FIELD_CLASSVAR< / span > < span class = "p" > ,< / span > < span class = "n" > _FIELD_INITVAR< / span > < span class = "p" > ):< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default_factory< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' field < / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > cannot have a ' < / span >
< span class = "s1" > ' default factory' < / span > < span class = "p" > )< / span >
< span class = "c1" > # Should I check for other field settings? default_factory< / span >
< span class = "c1" > # seems the most serious to check for. Maybe add others. For< / span >
< span class = "c1" > # example, how about init=False (or really,< / span >
< span class = "c1" > # init=< not-the-default-init-value> )? It makes no sense for< / span >
< span class = "c1" > # ClassVar and InitVar to specify init=< anything> .< / span >
< span class = "c1" > # kw_only validation and assignment.< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "ow" > in< / span > < span class = "p" > (< / span > < span class = "n" > _FIELD< / span > < span class = "p" > ,< / span > < span class = "n" > _FIELD_INITVAR< / span > < span class = "p" > ):< / span >
< span class = "c1" > # For real and InitVar fields, if kw_only wasn' t specified use the< / span >
< span class = "c1" > # default value.< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > kw_only< / span > < span class = "ow" > is< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > kw_only< / span > < span class = "o" > =< / span > < span class = "n" > default_kw_only< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "c1" > # Make sure kw_only isn' t set for ClassVars< / span >
< span class = "k" > assert< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "ow" > is< / span > < span class = "n" > _FIELD_CLASSVAR< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > kw_only< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' field < / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > is a ClassVar but specifies ' < / span >
< span class = "s1" > ' kw_only' < / span > < span class = "p" > )< / span >
< span class = "c1" > # For real fields, disallow mutable defaults. Use unhashable as a proxy< / span >
< span class = "c1" > # indicator for mutability. Read the __hash__ attribute from the class,< / span >
< span class = "c1" > # not the instance.< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "ow" > is< / span > < span class = "n" > _FIELD< / span > < span class = "ow" > and< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "o" > .< / span > < span class = "vm" > __class__< / span > < span class = "o" > .< / span > < span class = "fm" > __hash__< / span > < span class = "ow" > is< / span > < span class = "kc" > None< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > ValueError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' mutable default < / span > < span class = "si" > {< / span > < span class = "nb" > type< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "p" > )< / span > < span class = "si" > }< / span > < span class = "s1" > for field ' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' < / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > is not allowed: use default_factory' < / span > < span class = "p" > )< / span >
< span class = "k" > return< / span > < span class = "n" > f< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _set_new_attribute< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > value< / span > < span class = "p" > ):< / span >
< span class = "c1" > # Never overwrites an existing attribute. Returns True if the< / span >
< span class = "c1" > # attribute already exists.< / span >
< span class = "k" > if< / span > < span class = "n" > name< / span > < span class = "ow" > in< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __dict__< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "kc" > True< / span >
< span class = "nb" > setattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > value< / span > < span class = "p" > )< / span >
< span class = "k" > return< / span > < span class = "kc" > False< / span >
< span class = "c1" > # Decide if/how we' re going to create a hash function. Key is< / span >
< span class = "c1" > # (unsafe_hash, eq, frozen, does-hash-exist). Value is the action to< / span >
< span class = "c1" > # take. The common case is to do nothing, so instead of providing a< / span >
< span class = "c1" > # function that is a no-op, use None to signify that.< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _hash_set_none< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > fields< / span > < span class = "p" > ,< / span > < span class = "n" > func_builder< / span > < span class = "p" > ):< / span >
< span class = "c1" > # It' s sort of a hack that I' m setting this here, instead of at< / span >
< span class = "c1" > # func_builder.add_fns_to_class time, but since this is an exceptional case< / span >
< span class = "c1" > # (it' s not setting an attribute to a function, but to a scalar value),< / span >
< span class = "c1" > # just do it directly here. I might come to regret this.< / span >
< span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "fm" > __hash__< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _hash_add< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > fields< / span > < span class = "p" > ,< / span > < span class = "n" > func_builder< / span > < span class = "p" > ):< / span >
< span class = "n" > flds< / span > < span class = "o" > =< / span > < span class = "p" > [< / span > < span class = "n" > f< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "k" > if< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > compare< / span > < span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > hash< / span > < span class = "ow" > is< / span > < span class = "kc" > None< / span > < span class = "k" > else< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > hash< / span > < span class = "p" > )]< / span >
< span class = "n" > self_tuple< / span > < span class = "o" > =< / span > < span class = "n" > _tuple_str< / span > < span class = "p" > (< / span > < span class = "s1" > ' self' < / span > < span class = "p" > ,< / span > < span class = "n" > flds< / span > < span class = "p" > )< / span >
< span class = "n" > func_builder< / span > < span class = "o" > .< / span > < span class = "n" > add_fn< / span > < span class = "p" > (< / span > < span class = "s1" > ' __hash__' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' self' < / span > < span class = "p" > ,),< / span >
< span class = "p" > [< / span > < span class = "sa" > f< / span > < span class = "s1" > ' return hash(< / span > < span class = "si" > {< / span > < span class = "n" > self_tuple< / span > < span class = "si" > }< / span > < span class = "s1" > )' < / span > < span class = "p" > ],< / span >
< span class = "n" > unconditional_add< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _hash_exception< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > fields< / span > < span class = "p" > ,< / span > < span class = "n" > func_builder< / span > < span class = "p" > ):< / span >
< span class = "c1" > # Raise an exception.< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' Cannot overwrite attribute __hash__ ' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' in class < / span > < span class = "si" > {< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __name__< / span > < span class = "si" > }< / span > < span class = "s1" > ' < / span > < span class = "p" > )< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # +-------------------------------------- unsafe_hash?< / span >
< span class = "c1" > # | +------------------------------- eq?< / span >
< span class = "c1" > # | | +------------------------ frozen?< / span >
< span class = "c1" > # | | | +---------------- has-explicit-hash?< / span >
< span class = "c1" > # | | | |< / span >
< span class = "c1" > # | | | | +------- action< / span >
< span class = "c1" > # | | | | |< / span >
< span class = "c1" > # v v v v v< / span >
< span class = "n" > _hash_action< / span > < span class = "o" > =< / span > < span class = "p" > {(< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ):< / span > < span class = "kc" > None< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ):< / span > < span class = "kc" > None< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ):< / span > < span class = "kc" > None< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ):< / span > < span class = "kc" > None< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ):< / span > < span class = "n" > _hash_set_none< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ):< / span > < span class = "kc" > None< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ):< / span > < span class = "n" > _hash_add< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ):< / span > < span class = "kc" > None< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ):< / span > < span class = "n" > _hash_add< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ):< / span > < span class = "n" > _hash_exception< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ):< / span > < span class = "n" > _hash_add< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ):< / span > < span class = "n" > _hash_exception< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ):< / span > < span class = "n" > _hash_add< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ):< / span > < span class = "n" > _hash_exception< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > False< / span > < span class = "p" > ):< / span > < span class = "n" > _hash_add< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "kc" > True< / span > < span class = "p" > ):< / span > < span class = "n" > _hash_exception< / span > < span class = "p" > ,< / span >
< span class = "p" > }< / span >
< span class = "c1" > # See https://bugs.python.org/issue32929#msg312829 for an if-statement< / span >
< span class = "c1" > # version of this table.< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _process_class< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > init< / span > < span class = "p" > ,< / span > < span class = "nb" > repr< / span > < span class = "p" > ,< / span > < span class = "n" > eq< / span > < span class = "p" > ,< / span > < span class = "n" > order< / span > < span class = "p" > ,< / span > < span class = "n" > unsafe_hash< / span > < span class = "p" > ,< / span > < span class = "n" > frozen< / span > < span class = "p" > ,< / span >
< span class = "n" > match_args< / span > < span class = "p" > ,< / span > < span class = "n" > kw_only< / span > < span class = "p" > ,< / span > < span class = "n" > slots< / span > < span class = "p" > ,< / span > < span class = "n" > weakref_slot< / span > < span class = "p" > ):< / span >
< span class = "c1" > # Now that dicts retain insertion order, there' s no reason to use< / span >
< span class = "c1" > # an ordered dict. I am leveraging that ordering here, because< / span >
< span class = "c1" > # derived class fields overwrite base class fields, but the order< / span >
< span class = "c1" > # is defined by the base class, which is found first.< / span >
< span class = "n" > fields< / span > < span class = "o" > =< / span > < span class = "p" > {}< / span >
< span class = "k" > if< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __module__< / span > < span class = "ow" > in< / span > < span class = "n" > sys< / span > < span class = "o" > .< / span > < span class = "n" > modules< / span > < span class = "p" > :< / span >
< span class = "nb" > globals< / span > < span class = "o" > =< / span > < span class = "n" > sys< / span > < span class = "o" > .< / span > < span class = "n" > modules< / span > < span class = "p" > [< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __module__< / span > < span class = "p" > ]< / span > < span class = "o" > .< / span > < span class = "vm" > __dict__< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "c1" > # Theoretically this can happen if someone writes< / span >
< span class = "c1" > # a custom string to cls.__module__. In which case< / span >
< span class = "c1" > # such dataclass won' t be fully introspectable< / span >
< span class = "c1" > # (w.r.t. typing.get_type_hints) but will still function< / span >
< span class = "c1" > # correctly.< / span >
< span class = "nb" > globals< / span > < span class = "o" > =< / span > < span class = "p" > {}< / span >
< span class = "nb" > setattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > _PARAMS< / span > < span class = "p" > ,< / span > < span class = "n" > _DataclassParams< / span > < span class = "p" > (< / span > < span class = "n" > init< / span > < span class = "p" > ,< / span > < span class = "nb" > repr< / span > < span class = "p" > ,< / span > < span class = "n" > eq< / span > < span class = "p" > ,< / span > < span class = "n" > order< / span > < span class = "p" > ,< / span >
< span class = "n" > unsafe_hash< / span > < span class = "p" > ,< / span > < span class = "n" > frozen< / span > < span class = "p" > ,< / span >
< span class = "n" > match_args< / span > < span class = "p" > ,< / span > < span class = "n" > kw_only< / span > < span class = "p" > ,< / span >
< span class = "n" > slots< / span > < span class = "p" > ,< / span > < span class = "n" > weakref_slot< / span > < span class = "p" > ))< / span >
< span class = "c1" > # Find our base classes in reverse MRO order, and exclude< / span >
< span class = "c1" > # ourselves. In reversed order so that more derived classes< / span >
< span class = "c1" > # override earlier field definitions in base classes. As long as< / span >
< span class = "c1" > # we' re iterating over them, see if all or any of them are frozen.< / span >
< span class = "n" > any_frozen_base< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span >
< span class = "c1" > # By default `all_frozen_bases` is `None` to represent a case,< / span >
< span class = "c1" > # where some dataclasses does not have any bases with `_FIELDS`< / span >
< span class = "n" > all_frozen_bases< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span >
< span class = "n" > has_dataclass_bases< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span >
< span class = "k" > for< / span > < span class = "n" > b< / span > < span class = "ow" > in< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __mro__< / span > < span class = "p" > [< / span > < span class = "o" > -< / span > < span class = "mi" > 1< / span > < span class = "p" > :< / span > < span class = "mi" > 0< / span > < span class = "p" > :< / span > < span class = "o" > -< / span > < span class = "mi" > 1< / span > < span class = "p" > ]:< / span >
< span class = "c1" > # Only process classes that have been processed by our< / span >
< span class = "c1" > # decorator. That is, they have a _FIELDS attribute.< / span >
< span class = "n" > base_fields< / span > < span class = "o" > =< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "n" > b< / span > < span class = "p" > ,< / span > < span class = "n" > _FIELDS< / span > < span class = "p" > ,< / span > < span class = "kc" > None< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > base_fields< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "kc" > None< / span > < span class = "p" > :< / span >
< span class = "n" > has_dataclass_bases< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span >
< span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > base_fields< / span > < span class = "o" > .< / span > < span class = "n" > values< / span > < span class = "p" > ():< / span >
< span class = "n" > fields< / span > < span class = "p" > [< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "n" > f< / span >
< span class = "k" > if< / span > < span class = "n" > all_frozen_bases< / span > < span class = "ow" > is< / span > < span class = "kc" > None< / span > < span class = "p" > :< / span >
< span class = "n" > all_frozen_bases< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span >
< span class = "n" > current_frozen< / span > < span class = "o" > =< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "n" > b< / span > < span class = "p" > ,< / span > < span class = "n" > _PARAMS< / span > < span class = "p" > )< / span > < span class = "o" > .< / span > < span class = "n" > frozen< / span >
< span class = "n" > all_frozen_bases< / span > < span class = "o" > =< / span > < span class = "n" > all_frozen_bases< / span > < span class = "ow" > and< / span > < span class = "n" > current_frozen< / span >
< span class = "n" > any_frozen_base< / span > < span class = "o" > =< / span > < span class = "n" > any_frozen_base< / span > < span class = "ow" > or< / span > < span class = "n" > current_frozen< / span >
< span class = "c1" > # Annotations defined specifically in this class (not in base classes).< / span >
< span class = "c1" > #< / span >
< span class = "c1" > # Fields are found from cls_annotations, which is guaranteed to be< / span >
< span class = "c1" > # ordered. Default values are from class attributes, if a field< / span >
< span class = "c1" > # has a default. If the default value is a Field(), then it< / span >
< span class = "c1" > # contains additional info beyond (and possibly including) the< / span >
< span class = "c1" > # actual default value. Pseudo-fields ClassVars and InitVars are< / span >
< span class = "c1" > # included, despite the fact that they' re not real fields. That' s< / span >
< span class = "c1" > # dealt with later.< / span >
< span class = "n" > cls_annotations< / span > < span class = "o" > =< / span > < span class = "n" > inspect< / span > < span class = "o" > .< / span > < span class = "n" > get_annotations< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > )< / span >
< span class = "c1" > # Now find fields in our class. While doing so, validate some< / span >
< span class = "c1" > # things, and set the default values (as class attributes) where< / span >
< span class = "c1" > # we can.< / span >
< span class = "n" > cls_fields< / span > < span class = "o" > =< / span > < span class = "p" > []< / span >
< span class = "c1" > # Get a reference to this module for the _is_kw_only() test.< / span >
< span class = "n" > KW_ONLY_seen< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span >
< span class = "n" > dataclasses< / span > < span class = "o" > =< / span > < span class = "n" > sys< / span > < span class = "o" > .< / span > < span class = "n" > modules< / span > < span class = "p" > [< / span > < span class = "vm" > __name__< / span > < span class = "p" > ]< / span >
< span class = "k" > for< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "nb" > type< / span > < span class = "ow" > in< / span > < span class = "n" > cls_annotations< / span > < span class = "o" > .< / span > < span class = "n" > items< / span > < span class = "p" > ():< / span >
< span class = "c1" > # See if this is a marker to change the value of kw_only.< / span >
< span class = "k" > if< / span > < span class = "p" > (< / span > < span class = "n" > _is_kw_only< / span > < span class = "p" > (< / span > < span class = "nb" > type< / span > < span class = "p" > ,< / span > < span class = "n" > dataclasses< / span > < span class = "p" > )< / span >
< span class = "ow" > or< / span > < span class = "p" > (< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "nb" > type< / span > < span class = "p" > ,< / span > < span class = "nb" > str< / span > < span class = "p" > )< / span >
< span class = "ow" > and< / span > < span class = "n" > _is_type< / span > < span class = "p" > (< / span > < span class = "nb" > type< / span > < span class = "p" > ,< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > dataclasses< / span > < span class = "p" > ,< / span > < span class = "n" > dataclasses< / span > < span class = "o" > .< / span > < span class = "n" > KW_ONLY< / span > < span class = "p" > ,< / span >
< span class = "n" > _is_kw_only< / span > < span class = "p" > ))):< / span >
< span class = "c1" > # Switch the default to kw_only=True, and ignore this< / span >
< span class = "c1" > # annotation: it' s not a real field.< / span >
< span class = "k" > if< / span > < span class = "n" > KW_ONLY_seen< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' < / span > < span class = "si" > {< / span > < span class = "n" > name< / span > < span class = "si" > !r}< / span > < span class = "s1" > is KW_ONLY, but KW_ONLY ' < / span >
< span class = "s1" > ' has already been specified' < / span > < span class = "p" > )< / span >
< span class = "n" > KW_ONLY_seen< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span >
< span class = "n" > kw_only< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "c1" > # Otherwise it' s a field of some type.< / span >
< span class = "n" > cls_fields< / span > < span class = "o" > .< / span > < span class = "n" > append< / span > < span class = "p" > (< / span > < span class = "n" > _get_field< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "nb" > type< / span > < span class = "p" > ,< / span > < span class = "n" > kw_only< / span > < span class = "p" > ))< / span >
< span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > cls_fields< / span > < span class = "p" > :< / span >
< span class = "n" > fields< / span > < span class = "p" > [< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "n" > f< / span >
< span class = "c1" > # If the class attribute (which is the default value for this< / span >
< span class = "c1" > # field) exists and is of type ' Field' , replace it with the< / span >
< span class = "c1" > # real default. This is so that normal class introspection< / span >
< span class = "c1" > # sees a real default value, not a Field.< / span >
< span class = "k" > if< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "kc" > None< / span > < span class = "p" > ),< / span > < span class = "n" > Field< / span > < span class = "p" > ):< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "ow" > is< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "c1" > # If there' s no default, delete the class attribute.< / span >
< span class = "c1" > # This happens if we specify field(repr=False), for< / span >
< span class = "c1" > # example (that is, we specified a field object, but< / span >
< span class = "c1" > # no default value). Also if we' re using a default< / span >
< span class = "c1" > # factory. The class attribute should not be set at< / span >
< span class = "c1" > # all in the post-processed class.< / span >
< span class = "nb" > delattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > )< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "nb" > setattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "p" > )< / span >
< span class = "c1" > # Do we have any Field members that don' t also have annotations?< / span >
< span class = "k" > for< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > value< / span > < span class = "ow" > in< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __dict__< / span > < span class = "o" > .< / span > < span class = "n" > items< / span > < span class = "p" > ():< / span >
< span class = "k" > if< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "n" > value< / span > < span class = "p" > ,< / span > < span class = "n" > Field< / span > < span class = "p" > )< / span > < span class = "ow" > and< / span > < span class = "ow" > not< / span > < span class = "n" > name< / span > < span class = "ow" > in< / span > < span class = "n" > cls_annotations< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' < / span > < span class = "si" > {< / span > < span class = "n" > name< / span > < span class = "si" > !r}< / span > < span class = "s1" > is a field but has no type annotation' < / span > < span class = "p" > )< / span >
< span class = "c1" > # Check rules that apply if we are derived from any dataclasses.< / span >
< span class = "k" > if< / span > < span class = "n" > has_dataclass_bases< / span > < span class = "p" > :< / span >
< span class = "c1" > # Raise an exception if any of our bases are frozen, but we' re not.< / span >
< span class = "k" > if< / span > < span class = "n" > any_frozen_base< / span > < span class = "ow" > and< / span > < span class = "ow" > not< / span > < span class = "n" > frozen< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "s1" > ' cannot inherit non-frozen dataclass from a ' < / span >
< span class = "s1" > ' frozen one' < / span > < span class = "p" > )< / span >
< span class = "c1" > # Raise an exception if we' re frozen, but none of our bases are.< / span >
< span class = "k" > if< / span > < span class = "n" > all_frozen_bases< / span > < span class = "ow" > is< / span > < span class = "kc" > False< / span > < span class = "ow" > and< / span > < span class = "n" > frozen< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "s1" > ' cannot inherit frozen dataclass from a ' < / span >
< span class = "s1" > ' non-frozen one' < / span > < span class = "p" > )< / span >
< span class = "c1" > # Remember all of the fields on our class (including bases). This< / span >
< span class = "c1" > # also marks this class as being a dataclass.< / span >
< span class = "nb" > setattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > _FIELDS< / span > < span class = "p" > ,< / span > < span class = "n" > fields< / span > < span class = "p" > )< / span >
< span class = "c1" > # Was this class defined with an explicit __hash__? Note that if< / span >
< span class = "c1" > # __eq__ is defined in this class, then python will automatically< / span >
< span class = "c1" > # set __hash__ to None. This is a heuristic, as it' s possible< / span >
< span class = "c1" > # that such a __hash__ == None was not auto-generated, but it' s< / span >
< span class = "c1" > # close enough.< / span >
< span class = "n" > class_hash< / span > < span class = "o" > =< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __dict__< / span > < span class = "o" > .< / span > < span class = "n" > get< / span > < span class = "p" > (< / span > < span class = "s1" > ' __hash__' < / span > < span class = "p" > ,< / span > < span class = "n" > MISSING< / span > < span class = "p" > )< / span >
< span class = "n" > has_explicit_hash< / span > < span class = "o" > =< / span > < span class = "ow" > not< / span > < span class = "p" > (< / span > < span class = "n" > class_hash< / span > < span class = "ow" > is< / span > < span class = "n" > MISSING< / span > < span class = "ow" > or< / span >
< span class = "p" > (< / span > < span class = "n" > class_hash< / span > < span class = "ow" > is< / span > < span class = "kc" > None< / span > < span class = "ow" > and< / span > < span class = "s1" > ' __eq__' < / span > < span class = "ow" > in< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __dict__< / span > < span class = "p" > ))< / span >
< span class = "c1" > # If we' re generating ordering methods, we must be generating the< / span >
< span class = "c1" > # eq methods.< / span >
< span class = "k" > if< / span > < span class = "n" > order< / span > < span class = "ow" > and< / span > < span class = "ow" > not< / span > < span class = "n" > eq< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > ValueError< / span > < span class = "p" > (< / span > < span class = "s1" > ' eq must be true if order is true' < / span > < span class = "p" > )< / span >
< span class = "c1" > # Include InitVars and regular fields (so, not ClassVars). This is< / span >
< span class = "c1" > # initialized here, outside of the " if init:" test, because std_init_fields< / span >
< span class = "c1" > # is used with match_args, below.< / span >
< span class = "n" > all_init_fields< / span > < span class = "o" > =< / span > < span class = "p" > [< / span > < span class = "n" > f< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "o" > .< / span > < span class = "n" > values< / span > < span class = "p" > ()< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "ow" > in< / span > < span class = "p" > (< / span > < span class = "n" > _FIELD< / span > < span class = "p" > ,< / span > < span class = "n" > _FIELD_INITVAR< / span > < span class = "p" > )]< / span >
< span class = "p" > (< / span > < span class = "n" > std_init_fields< / span > < span class = "p" > ,< / span >
< span class = "n" > kw_only_init_fields< / span > < span class = "p" > )< / span > < span class = "o" > =< / span > < span class = "n" > _fields_in_init_order< / span > < span class = "p" > (< / span > < span class = "n" > all_init_fields< / span > < span class = "p" > )< / span >
< span class = "n" > func_builder< / span > < span class = "o" > =< / span > < span class = "n" > _FuncBuilder< / span > < span class = "p" > (< / span > < span class = "nb" > globals< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > init< / span > < span class = "p" > :< / span >
< span class = "c1" > # Does this class have a post-init function?< / span >
< span class = "n" > has_post_init< / span > < span class = "o" > =< / span > < span class = "nb" > hasattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > _POST_INIT_NAME< / span > < span class = "p" > )< / span >
< span class = "n" > _init_fn< / span > < span class = "p" > (< / span > < span class = "n" > all_init_fields< / span > < span class = "p" > ,< / span >
< span class = "n" > std_init_fields< / span > < span class = "p" > ,< / span >
< span class = "n" > kw_only_init_fields< / span > < span class = "p" > ,< / span >
< span class = "n" > frozen< / span > < span class = "p" > ,< / span >
< span class = "n" > has_post_init< / span > < span class = "p" > ,< / span >
< span class = "c1" > # The name to use for the " self" < / span >
< span class = "c1" > # param in __init__. Use " self" < / span >
< span class = "c1" > # if possible.< / span >
< span class = "s1" > ' __dataclass_self__' < / span > < span class = "k" > if< / span > < span class = "s1" > ' self' < / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span >
< span class = "k" > else< / span > < span class = "s1" > ' self' < / span > < span class = "p" > ,< / span >
< span class = "n" > func_builder< / span > < span class = "p" > ,< / span >
< span class = "n" > slots< / span > < span class = "p" > ,< / span >
< span class = "p" > )< / span >
< span class = "n" > _set_new_attribute< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "s1" > ' __replace__' < / span > < span class = "p" > ,< / span > < span class = "n" > _replace< / span > < span class = "p" > )< / span >
< span class = "c1" > # Get the fields as a list, and include only real fields. This is< / span >
< span class = "c1" > # used in all of the following methods.< / span >
< span class = "n" > field_list< / span > < span class = "o" > =< / span > < span class = "p" > [< / span > < span class = "n" > f< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "o" > .< / span > < span class = "n" > values< / span > < span class = "p" > ()< / span > < span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "ow" > is< / span > < span class = "n" > _FIELD< / span > < span class = "p" > ]< / span >
< span class = "k" > if< / span > < span class = "nb" > repr< / span > < span class = "p" > :< / span >
< span class = "n" > flds< / span > < span class = "o" > =< / span > < span class = "p" > [< / span > < span class = "n" > f< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > field_list< / span > < span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > repr< / span > < span class = "p" > ]< / span >
< span class = "n" > func_builder< / span > < span class = "o" > .< / span > < span class = "n" > add_fn< / span > < span class = "p" > (< / span > < span class = "s1" > ' __repr__' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' self' < / span > < span class = "p" > ,),< / span >
< span class = "p" > [< / span > < span class = "s1" > ' return f" < / span > < span class = "si" > {self.__class__.__qualname__}< / span > < span class = "s1" > (' < / span > < span class = "o" > +< / span >
< span class = "s1" > ' , ' < / span > < span class = "o" > .< / span > < span class = "n" > join< / span > < span class = "p" > ([< / span > < span class = "sa" > f< / span > < span class = "s2" > " < / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s2" > =< / span > < span class = "se" > {{< / span > < span class = "s2" > self.< / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s2" > !r< / span > < span class = "se" > }}< / span > < span class = "s2" > " < / span >
< span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > flds< / span > < span class = "p" > ])< / span > < span class = "o" > +< / span > < span class = "s1" > ' )" ' < / span > < span class = "p" > ],< / span >
< span class = "nb" > locals< / span > < span class = "o" > =< / span > < span class = "p" > {< / span > < span class = "s1" > ' __dataclasses_recursive_repr' < / span > < span class = "p" > :< / span > < span class = "n" > recursive_repr< / span > < span class = "p" > },< / span >
< span class = "n" > decorator< / span > < span class = "o" > =< / span > < span class = "s2" > " @__dataclasses_recursive_repr()" < / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > eq< / span > < span class = "p" > :< / span >
< span class = "c1" > # Create __eq__ method. There' s no need for a __ne__ method,< / span >
< span class = "c1" > # since python will call __eq__ and negate it.< / span >
< span class = "n" > cmp_fields< / span > < span class = "o" > =< / span > < span class = "p" > (< / span > < span class = "n" > field< / span > < span class = "k" > for< / span > < span class = "n" > field< / span > < span class = "ow" > in< / span > < span class = "n" > field_list< / span > < span class = "k" > if< / span > < span class = "n" > field< / span > < span class = "o" > .< / span > < span class = "n" > compare< / span > < span class = "p" > )< / span >
< span class = "n" > terms< / span > < span class = "o" > =< / span > < span class = "p" > [< / span > < span class = "sa" > f< / span > < span class = "s1" > ' self.< / span > < span class = "si" > {< / span > < span class = "n" > field< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > ==other.< / span > < span class = "si" > {< / span > < span class = "n" > field< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > ' < / span > < span class = "k" > for< / span > < span class = "n" > field< / span > < span class = "ow" > in< / span > < span class = "n" > cmp_fields< / span > < span class = "p" > ]< / span >
< span class = "n" > field_comparisons< / span > < span class = "o" > =< / span > < span class = "s1" > ' and ' < / span > < span class = "o" > .< / span > < span class = "n" > join< / span > < span class = "p" > (< / span > < span class = "n" > terms< / span > < span class = "p" > )< / span > < span class = "ow" > or< / span > < span class = "s1" > ' True' < / span >
< span class = "n" > func_builder< / span > < span class = "o" > .< / span > < span class = "n" > add_fn< / span > < span class = "p" > (< / span > < span class = "s1" > ' __eq__' < / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' self' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' other' < / span > < span class = "p" > ),< / span >
< span class = "p" > [< / span > < span class = "s1" > ' if self is other:' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' return True' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' if other.__class__ is self.__class__:' < / span > < span class = "p" > ,< / span >
< span class = "sa" > f< / span > < span class = "s1" > ' return < / span > < span class = "si" > {< / span > < span class = "n" > field_comparisons< / span > < span class = "si" > }< / span > < span class = "s1" > ' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' return NotImplemented' < / span > < span class = "p" > ])< / span >
< span class = "k" > if< / span > < span class = "n" > order< / span > < span class = "p" > :< / span >
< span class = "c1" > # Create and set the ordering methods.< / span >
< span class = "n" > flds< / span > < span class = "o" > =< / span > < span class = "p" > [< / span > < span class = "n" > f< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > field_list< / span > < span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > compare< / span > < span class = "p" > ]< / span >
< span class = "n" > self_tuple< / span > < span class = "o" > =< / span > < span class = "n" > _tuple_str< / span > < span class = "p" > (< / span > < span class = "s1" > ' self' < / span > < span class = "p" > ,< / span > < span class = "n" > flds< / span > < span class = "p" > )< / span >
< span class = "n" > other_tuple< / span > < span class = "o" > =< / span > < span class = "n" > _tuple_str< / span > < span class = "p" > (< / span > < span class = "s1" > ' other' < / span > < span class = "p" > ,< / span > < span class = "n" > flds< / span > < span class = "p" > )< / span >
< span class = "k" > for< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > op< / span > < span class = "ow" > in< / span > < span class = "p" > [(< / span > < span class = "s1" > ' __lt__' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' < ' < / span > < span class = "p" > ),< / span >
< span class = "p" > (< / span > < span class = "s1" > ' __le__' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' < =' < / span > < span class = "p" > ),< / span >
< span class = "p" > (< / span > < span class = "s1" > ' __gt__' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' > ' < / span > < span class = "p" > ),< / span >
< span class = "p" > (< / span > < span class = "s1" > ' __ge__' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' > =' < / span > < span class = "p" > ),< / span >
< span class = "p" > ]:< / span >
< span class = "c1" > # Create a comparison function. If the fields in the object are< / span >
< span class = "c1" > # named ' x' and ' y' , then self_tuple is the string< / span >
< span class = "c1" > # ' (self.x,self.y)' and other_tuple is the string< / span >
< span class = "c1" > # ' (other.x,other.y)' .< / span >
< span class = "n" > func_builder< / span > < span class = "o" > .< / span > < span class = "n" > add_fn< / span > < span class = "p" > (< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span >
< span class = "p" > (< / span > < span class = "s1" > ' self' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' other' < / span > < span class = "p" > ),< / span >
< span class = "p" > [< / span > < span class = "s1" > ' if other.__class__ is self.__class__:' < / span > < span class = "p" > ,< / span >
< span class = "sa" > f< / span > < span class = "s1" > ' return < / span > < span class = "si" > {< / span > < span class = "n" > self_tuple< / span > < span class = "si" > }{< / span > < span class = "n" > op< / span > < span class = "si" > }{< / span > < span class = "n" > other_tuple< / span > < span class = "si" > }< / span > < span class = "s1" > ' < / span > < span class = "p" > ,< / span >
< span class = "s1" > ' return NotImplemented' < / span > < span class = "p" > ],< / span >
< span class = "n" > overwrite_error< / span > < span class = "o" > =< / span > < span class = "s1" > ' Consider using functools.total_ordering' < / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > frozen< / span > < span class = "p" > :< / span >
< span class = "n" > _frozen_get_del_attr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > field_list< / span > < span class = "p" > ,< / span > < span class = "n" > func_builder< / span > < span class = "p" > )< / span >
< span class = "c1" > # Decide if/how we' re going to create a hash function.< / span >
< span class = "n" > hash_action< / span > < span class = "o" > =< / span > < span class = "n" > _hash_action< / span > < span class = "p" > [< / span > < span class = "nb" > bool< / span > < span class = "p" > (< / span > < span class = "n" > unsafe_hash< / span > < span class = "p" > ),< / span >
< span class = "nb" > bool< / span > < span class = "p" > (< / span > < span class = "n" > eq< / span > < span class = "p" > ),< / span >
< span class = "nb" > bool< / span > < span class = "p" > (< / span > < span class = "n" > frozen< / span > < span class = "p" > ),< / span >
< span class = "n" > has_explicit_hash< / span > < span class = "p" > ]< / span >
< span class = "k" > if< / span > < span class = "n" > hash_action< / span > < span class = "p" > :< / span >
< span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "fm" > __hash__< / span > < span class = "o" > =< / span > < span class = "n" > hash_action< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > field_list< / span > < span class = "p" > ,< / span > < span class = "n" > func_builder< / span > < span class = "p" > )< / span >
< span class = "c1" > # Generate the methods and add them to the class. This needs to be done< / span >
< span class = "c1" > # before the __doc__ logic below, since inspect will look at the __init__< / span >
< span class = "c1" > # signature.< / span >
< span class = "n" > func_builder< / span > < span class = "o" > .< / span > < span class = "n" > add_fns_to_class< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "ow" > not< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "s1" > ' __doc__' < / span > < span class = "p" > ):< / span >
< span class = "c1" > # Create a class doc-string.< / span >
< span class = "k" > try< / span > < span class = "p" > :< / span >
< span class = "c1" > # In some cases fetching a signature is not possible.< / span >
< span class = "c1" > # But, we surely should not fail in this case.< / span >
< span class = "n" > text_sig< / span > < span class = "o" > =< / span > < span class = "nb" > str< / span > < span class = "p" > (< / span > < span class = "n" > inspect< / span > < span class = "o" > .< / span > < span class = "n" > signature< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ))< / span > < span class = "o" > .< / span > < span class = "n" > replace< / span > < span class = "p" > (< / span > < span class = "s1" > ' -> None' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' ' < / span > < span class = "p" > )< / span >
< span class = "k" > except< / span > < span class = "p" > (< / span > < span class = "ne" > TypeError< / span > < span class = "p" > ,< / span > < span class = "ne" > ValueError< / span > < span class = "p" > ):< / span >
< span class = "n" > text_sig< / span > < span class = "o" > =< / span > < span class = "s1" > ' ' < / span >
< span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __doc__< / span > < span class = "o" > =< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __name__< / span > < span class = "o" > +< / span > < span class = "n" > text_sig< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > match_args< / span > < span class = "p" > :< / span >
< span class = "c1" > # I could probably compute this once.< / span >
< span class = "n" > _set_new_attribute< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "s1" > ' __match_args__' < / span > < span class = "p" > ,< / span >
< span class = "nb" > tuple< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > std_init_fields< / span > < span class = "p" > ))< / span >
< span class = "c1" > # It' s an error to specify weakref_slot if slots is False.< / span >
< span class = "k" > if< / span > < span class = "n" > weakref_slot< / span > < span class = "ow" > and< / span > < span class = "ow" > not< / span > < span class = "n" > slots< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "s1" > ' weakref_slot is True but slots is False' < / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > slots< / span > < span class = "p" > :< / span >
< span class = "bp" > cls< / span > < span class = "o" > =< / span > < span class = "n" > _add_slots< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > frozen< / span > < span class = "p" > ,< / span > < span class = "n" > weakref_slot< / span > < span class = "p" > )< / span >
< span class = "n" > abc< / span > < span class = "o" > .< / span > < span class = "n" > update_abstractmethods< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > )< / span >
< span class = "k" > return< / span > < span class = "bp" > cls< / span >
< span class = "c1" > # _dataclass_getstate and _dataclass_setstate are needed for pickling frozen< / span >
< span class = "c1" > # classes with slots. These could be slightly more performant if we generated< / span >
< span class = "c1" > # the code instead of iterating over fields. But that can be a project for< / span >
< span class = "c1" > # another day, if performance becomes an issue.< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _dataclass_getstate< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ):< / span >
< span class = "k" > return< / span > < span class = "p" > [< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > )< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > )]< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _dataclass_setstate< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "n" > state< / span > < span class = "p" > ):< / span >
< span class = "k" > for< / span > < span class = "n" > field< / span > < span class = "p" > ,< / span > < span class = "n" > value< / span > < span class = "ow" > in< / span > < span class = "nb" > zip< / span > < span class = "p" > (< / span > < span class = "n" > fields< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ),< / span > < span class = "n" > state< / span > < span class = "p" > ):< / span >
< span class = "c1" > # use setattr because dataclass may be frozen< / span >
< span class = "nb" > object< / span > < span class = "o" > .< / span > < span class = "fm" > __setattr__< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "n" > field< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > value< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _get_slots< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ):< / span >
< span class = "k" > match< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __dict__< / span > < span class = "o" > .< / span > < span class = "n" > get< / span > < span class = "p" > (< / span > < span class = "s1" > ' __slots__' < / span > < span class = "p" > ):< / span >
< span class = "c1" > # `__dictoffset__` and `__weakrefoffset__` can tell us whether< / span >
< span class = "c1" > # the base type has dict/weakref slots, in a way that works correctly< / span >
< span class = "c1" > # for both Python classes and C extension types. Extension types< / span >
< span class = "c1" > # don' t use `__slots__` for slot creation< / span >
< span class = "k" > case< / span > < span class = "kc" > None< / span > < span class = "p" > :< / span >
< span class = "n" > slots< / span > < span class = "o" > =< / span > < span class = "p" > []< / span >
< span class = "k" > if< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "s1" > ' __weakrefoffset__' < / span > < span class = "p" > ,< / span > < span class = "o" > -< / span > < span class = "mi" > 1< / span > < span class = "p" > )< / span > < span class = "o" > !=< / span > < span class = "mi" > 0< / span > < span class = "p" > :< / span >
< span class = "n" > slots< / span > < span class = "o" > .< / span > < span class = "n" > append< / span > < span class = "p" > (< / span > < span class = "s1" > ' __weakref__' < / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "s1" > ' __dictoffset__' < / span > < span class = "p" > ,< / span > < span class = "o" > -< / span > < span class = "mi" > 1< / span > < span class = "p" > )< / span > < span class = "o" > !=< / span > < span class = "mi" > 0< / span > < span class = "p" > :< / span >
< span class = "n" > slots< / span > < span class = "o" > .< / span > < span class = "n" > append< / span > < span class = "p" > (< / span > < span class = "s1" > ' __dict__' < / span > < span class = "p" > )< / span >
< span class = "k" > yield from< / span > < span class = "n" > slots< / span >
< span class = "k" > case< / span > < span class = "nb" > str< / span > < span class = "p" > (< / span > < span class = "n" > slot< / span > < span class = "p" > ):< / span >
< span class = "k" > yield< / span > < span class = "n" > slot< / span >
< span class = "c1" > # Slots may be any iterable, but we cannot handle an iterator< / span >
< span class = "c1" > # because it will already be (partially) consumed.< / span >
< span class = "k" > case< / span > < span class = "n" > iterable< / span > < span class = "k" > if< / span > < span class = "ow" > not< / span > < span class = "nb" > hasattr< / span > < span class = "p" > (< / span > < span class = "n" > iterable< / span > < span class = "p" > ,< / span > < span class = "s1" > ' __next__' < / span > < span class = "p" > ):< / span >
< span class = "k" > yield from< / span > < span class = "n" > iterable< / span >
< span class = "k" > case< / span > < span class = "w" > < / span > < span class = "k" > _< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s2" > " Slots of ' < / span > < span class = "si" > {< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __name__< / span > < span class = "si" > }< / span > < span class = "s2" > ' cannot be determined" < / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _add_slots< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > is_frozen< / span > < span class = "p" > ,< / span > < span class = "n" > weakref_slot< / span > < span class = "p" > ):< / span >
< span class = "c1" > # Need to create a new class, since we can' t set __slots__< / span >
< span class = "c1" > # after a class has been created.< / span >
< span class = "c1" > # Make sure __slots__ isn' t already set.< / span >
< span class = "k" > if< / span > < span class = "s1" > ' __slots__' < / span > < span class = "ow" > in< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __dict__< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' < / span > < span class = "si" > {< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __name__< / span > < span class = "si" > }< / span > < span class = "s1" > already specifies __slots__' < / span > < span class = "p" > )< / span >
< span class = "c1" > # Create a new dict for our new class.< / span >
< span class = "n" > cls_dict< / span > < span class = "o" > =< / span > < span class = "nb" > dict< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __dict__< / span > < span class = "p" > )< / span >
< span class = "n" > field_names< / span > < span class = "o" > =< / span > < span class = "nb" > tuple< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ))< / span >
< span class = "c1" > # Make sure slots don' t overlap with those in base classes.< / span >
< span class = "n" > inherited_slots< / span > < span class = "o" > =< / span > < span class = "nb" > set< / span > < span class = "p" > (< / span >
< span class = "n" > itertools< / span > < span class = "o" > .< / span > < span class = "n" > chain< / span > < span class = "o" > .< / span > < span class = "n" > from_iterable< / span > < span class = "p" > (< / span > < span class = "nb" > map< / span > < span class = "p" > (< / span > < span class = "n" > _get_slots< / span > < span class = "p" > ,< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __mro__< / span > < span class = "p" > [< / span > < span class = "mi" > 1< / span > < span class = "p" > :< / span > < span class = "o" > -< / span > < span class = "mi" > 1< / span > < span class = "p" > ]))< / span >
< span class = "p" > )< / span >
< span class = "c1" > # The slots for our class. Remove slots from our base classes. Add< / span >
< span class = "c1" > # ' __weakref__' if weakref_slot was given, unless it is already present.< / span >
< span class = "n" > cls_dict< / span > < span class = "p" > [< / span > < span class = "s2" > " __slots__" < / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "nb" > tuple< / span > < span class = "p" > (< / span >
< span class = "n" > itertools< / span > < span class = "o" > .< / span > < span class = "n" > filterfalse< / span > < span class = "p" > (< / span >
< span class = "n" > inherited_slots< / span > < span class = "o" > .< / span > < span class = "fm" > __contains__< / span > < span class = "p" > ,< / span >
< span class = "n" > itertools< / span > < span class = "o" > .< / span > < span class = "n" > chain< / span > < span class = "p" > (< / span >
< span class = "c1" > # gh-93521: ' __weakref__' also needs to be filtered out if< / span >
< span class = "c1" > # already present in inherited_slots< / span >
< span class = "n" > field_names< / span > < span class = "p" > ,< / span > < span class = "p" > (< / span > < span class = "s1" > ' __weakref__' < / span > < span class = "p" > ,)< / span > < span class = "k" > if< / span > < span class = "n" > weakref_slot< / span > < span class = "k" > else< / span > < span class = "p" > ()< / span >
< span class = "p" > )< / span >
< span class = "p" > ),< / span >
< span class = "p" > )< / span >
< span class = "k" > for< / span > < span class = "n" > field_name< / span > < span class = "ow" > in< / span > < span class = "n" > field_names< / span > < span class = "p" > :< / span >
< span class = "c1" > # Remove our attributes, if present. They' ll still be< / span >
< span class = "c1" > # available in _MARKER.< / span >
< span class = "n" > cls_dict< / span > < span class = "o" > .< / span > < span class = "n" > pop< / span > < span class = "p" > (< / span > < span class = "n" > field_name< / span > < span class = "p" > ,< / span > < span class = "kc" > None< / span > < span class = "p" > )< / span >
< span class = "c1" > # Remove __dict__ itself.< / span >
< span class = "n" > cls_dict< / span > < span class = "o" > .< / span > < span class = "n" > pop< / span > < span class = "p" > (< / span > < span class = "s1" > ' __dict__' < / span > < span class = "p" > ,< / span > < span class = "kc" > None< / span > < span class = "p" > )< / span >
< span class = "c1" > # Clear existing `__weakref__` descriptor, it belongs to a previous type:< / span >
< span class = "n" > cls_dict< / span > < span class = "o" > .< / span > < span class = "n" > pop< / span > < span class = "p" > (< / span > < span class = "s1" > ' __weakref__' < / span > < span class = "p" > ,< / span > < span class = "kc" > None< / span > < span class = "p" > )< / span > < span class = "c1" > # gh-102069< / span >
< span class = "c1" > # And finally create the class.< / span >
< span class = "n" > qualname< / span > < span class = "o" > =< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "s1" > ' __qualname__' < / span > < span class = "p" > ,< / span > < span class = "kc" > None< / span > < span class = "p" > )< / span >
< span class = "bp" > cls< / span > < span class = "o" > =< / span > < span class = "nb" > type< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > )(< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __name__< / span > < span class = "p" > ,< / span > < span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __bases__< / span > < span class = "p" > ,< / span > < span class = "n" > cls_dict< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > qualname< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "kc" > None< / span > < span class = "p" > :< / span >
< span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __qualname__< / span > < span class = "o" > =< / span > < span class = "n" > qualname< / span >
< span class = "k" > if< / span > < span class = "n" > is_frozen< / span > < span class = "p" > :< / span >
< span class = "c1" > # Need this for pickling frozen classes with slots.< / span >
< span class = "k" > if< / span > < span class = "s1" > ' __getstate__' < / span > < span class = "ow" > not< / span > < span class = "ow" > in< / span > < span class = "n" > cls_dict< / span > < span class = "p" > :< / span >
< span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "n" > __getstate__< / span > < span class = "o" > =< / span > < span class = "n" > _dataclass_getstate< / span >
< span class = "k" > if< / span > < span class = "s1" > ' __setstate__' < / span > < span class = "ow" > not< / span > < span class = "ow" > in< / span > < span class = "n" > cls_dict< / span > < span class = "p" > :< / span >
< span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "n" > __setstate__< / span > < span class = "o" > =< / span > < span class = "n" > _dataclass_setstate< / span >
< span class = "k" > return< / span > < span class = "bp" > cls< / span >
< div class = "viewcode-block" id = "dataclass" >
< a class = "viewcode-back" href = "../api/evennia.commands.default.help.html#evennia.commands.default.help.dataclass" > [docs]< / a >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > dataclass< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span > < span class = "p" > ,< / span > < span class = "o" > /< / span > < span class = "p" > ,< / span > < span class = "o" > *< / span > < span class = "p" > ,< / span > < span class = "n" > init< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "nb" > repr< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "n" > eq< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "n" > order< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span >
< span class = "n" > unsafe_hash< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "n" > frozen< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "n" > match_args< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span >
< span class = "n" > kw_only< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "n" > slots< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "n" > weakref_slot< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ):< / span >
< span class = "w" > < / span > < span class = "sd" > " " " Add dunder methods based on the fields defined in the class.< / span >
< span class = "sd" > Examines PEP 526 __annotations__ to determine fields.< / span >
< span class = "sd" > If init is true, an __init__() method is added to the class. If repr< / span >
< span class = "sd" > is true, a __repr__() method is added. If order is true, rich< / span >
< span class = "sd" > comparison dunder methods are added. If unsafe_hash is true, a< / span >
< span class = "sd" > __hash__() method is added. If frozen is true, fields may not be< / span >
< span class = "sd" > assigned to after instance creation. If match_args is true, the< / span >
< span class = "sd" > __match_args__ tuple is added. If kw_only is true, then by default< / span >
< span class = "sd" > all fields are keyword-only. If slots is true, a new class with a< / span >
< span class = "sd" > __slots__ attribute is returned.< / span >
< span class = "sd" > " " " < / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > wrap< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ):< / span >
< span class = "k" > return< / span > < span class = "n" > _process_class< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > init< / span > < span class = "p" > ,< / span > < span class = "nb" > repr< / span > < span class = "p" > ,< / span > < span class = "n" > eq< / span > < span class = "p" > ,< / span > < span class = "n" > order< / span > < span class = "p" > ,< / span > < span class = "n" > unsafe_hash< / span > < span class = "p" > ,< / span >
< span class = "n" > frozen< / span > < span class = "p" > ,< / span > < span class = "n" > match_args< / span > < span class = "p" > ,< / span > < span class = "n" > kw_only< / span > < span class = "p" > ,< / span > < span class = "n" > slots< / span > < span class = "p" > ,< / span >
< span class = "n" > weakref_slot< / span > < span class = "p" > )< / span >
< span class = "c1" > # See if we' re being called as @dataclass or @dataclass().< / span >
< span class = "k" > if< / span > < span class = "bp" > cls< / span > < span class = "ow" > is< / span > < span class = "kc" > None< / span > < span class = "p" > :< / span >
< span class = "c1" > # We' re called with parens.< / span >
< span class = "k" > return< / span > < span class = "n" > wrap< / span >
< span class = "c1" > # We' re called as @dataclass without parens.< / span >
< span class = "k" > return< / span > < span class = "n" > wrap< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > )< / span > < / div >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > fields< / span > < span class = "p" > (< / span > < span class = "n" > class_or_instance< / span > < span class = "p" > ):< / span >
< span class = "w" > < / span > < span class = "sd" > " " " Return a tuple describing the fields of this dataclass.< / span >
< span class = "sd" > Accepts a dataclass or an instance of one. Tuple elements are of< / span >
< span class = "sd" > type Field.< / span >
< span class = "sd" > " " " < / span >
< span class = "c1" > # Might it be worth caching this, per class?< / span >
< span class = "k" > try< / span > < span class = "p" > :< / span >
< span class = "n" > fields< / span > < span class = "o" > =< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "n" > class_or_instance< / span > < span class = "p" > ,< / span > < span class = "n" > _FIELDS< / span > < span class = "p" > )< / span >
< span class = "k" > except< / span > < span class = "ne" > AttributeError< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "s1" > ' must be called with a dataclass type or instance' < / span > < span class = "p" > )< / span > < span class = "kn" > from< / span > < span class = "w" > < / span > < span class = "kc" > None< / span >
< span class = "c1" > # Exclude pseudo-fields. Note that fields is sorted by insertion< / span >
< span class = "c1" > # order, so the order of the tuple is as the fields were defined.< / span >
< span class = "k" > return< / span > < span class = "nb" > tuple< / span > < span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "o" > .< / span > < span class = "n" > values< / span > < span class = "p" > ()< / span > < span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "ow" > is< / span > < span class = "n" > _FIELD< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _is_dataclass_instance< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ):< / span >
< span class = "w" > < / span > < span class = "sd" > " " " Returns True if obj is an instance of a dataclass." " " < / span >
< span class = "k" > return< / span > < span class = "nb" > hasattr< / span > < span class = "p" > (< / span > < span class = "nb" > type< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ),< / span > < span class = "n" > _FIELDS< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > is_dataclass< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ):< / span >
< span class = "w" > < / span > < span class = "sd" > " " " Returns True if obj is a dataclass or an instance of a< / span >
< span class = "sd" > dataclass." " " < / span >
< span class = "bp" > cls< / span > < span class = "o" > =< / span > < span class = "n" > obj< / span > < span class = "k" > if< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "nb" > type< / span > < span class = "p" > )< / span > < span class = "k" > else< / span > < span class = "nb" > type< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > )< / span >
< span class = "k" > return< / span > < span class = "nb" > hasattr< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > _FIELDS< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > asdict< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "o" > *< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "o" > =< / span > < span class = "nb" > dict< / span > < span class = "p" > ):< / span >
< span class = "w" > < / span > < span class = "sd" > " " " Return the fields of a dataclass instance as a new dictionary mapping< / span >
< span class = "sd" > field names to field values.< / span >
< span class = "sd" > Example usage::< / span >
< span class = "sd" > @dataclass< / span >
< span class = "sd" > class C:< / span >
< span class = "sd" > x: int< / span >
< span class = "sd" > y: int< / span >
< span class = "sd" > c = C(1, 2)< / span >
< span class = "sd" > assert asdict(c) == {' x' : 1, ' y' : 2}< / span >
< span class = "sd" > If given, ' dict_factory' will be used instead of built-in dict.< / span >
< span class = "sd" > The function applies recursively to field values that are< / span >
< span class = "sd" > dataclass instances. This will also look into built-in containers:< / span >
< span class = "sd" > tuples, lists, and dicts. Other objects are copied with ' copy.deepcopy()' .< / span >
< span class = "sd" > " " " < / span >
< span class = "k" > if< / span > < span class = "ow" > not< / span > < span class = "n" > _is_dataclass_instance< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ):< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "s2" > " asdict() should be called on dataclass instances" < / span > < span class = "p" > )< / span >
< span class = "k" > return< / span > < span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > ):< / span >
< span class = "n" > obj_type< / span > < span class = "o" > =< / span > < span class = "nb" > type< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > obj_type< / span > < span class = "ow" > in< / span > < span class = "n" > _ATOMIC_TYPES< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "n" > obj< / span >
< span class = "k" > elif< / span > < span class = "nb" > hasattr< / span > < span class = "p" > (< / span > < span class = "n" > obj_type< / span > < span class = "p" > ,< / span > < span class = "n" > _FIELDS< / span > < span class = "p" > ):< / span >
< span class = "c1" > # dataclass instance: fast path for the common case< / span >
< span class = "k" > if< / span > < span class = "n" > dict_factory< / span > < span class = "ow" > is< / span > < span class = "nb" > dict< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "p" > {< / span >
< span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > :< / span > < span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > ),< / span > < span class = "nb" > dict< / span > < span class = "p" > )< / span >
< span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "n" > dict_factory< / span > < span class = "p" > ([< / span >
< span class = "p" > (< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > ),< / span > < span class = "n" > dict_factory< / span > < span class = "p" > ))< / span >
< span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > )< / span >
< span class = "p" > ])< / span >
< span class = "c1" > # handle the builtin types first for speed; subclasses handled below< / span >
< span class = "k" > elif< / span > < span class = "n" > obj_type< / span > < span class = "ow" > is< / span > < span class = "nb" > list< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "p" > [< / span > < span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > v< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > )< / span > < span class = "k" > for< / span > < span class = "n" > v< / span > < span class = "ow" > in< / span > < span class = "n" > obj< / span > < span class = "p" > ]< / span >
< span class = "k" > elif< / span > < span class = "n" > obj_type< / span > < span class = "ow" > is< / span > < span class = "nb" > dict< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "p" > {< / span >
< span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > k< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > ):< / span > < span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > v< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > )< / span >
< span class = "k" > for< / span > < span class = "n" > k< / span > < span class = "p" > ,< / span > < span class = "n" > v< / span > < span class = "ow" > in< / span > < span class = "n" > obj< / span > < span class = "o" > .< / span > < span class = "n" > items< / span > < span class = "p" > ()< / span >
< span class = "p" > }< / span >
< span class = "k" > elif< / span > < span class = "n" > obj_type< / span > < span class = "ow" > is< / span > < span class = "nb" > tuple< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "nb" > tuple< / span > < span class = "p" > ([< / span > < span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > v< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > )< / span > < span class = "k" > for< / span > < span class = "n" > v< / span > < span class = "ow" > in< / span > < span class = "n" > obj< / span > < span class = "p" > ])< / span >
< span class = "k" > elif< / span > < span class = "nb" > issubclass< / span > < span class = "p" > (< / span > < span class = "n" > obj_type< / span > < span class = "p" > ,< / span > < span class = "nb" > tuple< / span > < span class = "p" > ):< / span >
< span class = "k" > if< / span > < span class = "nb" > hasattr< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "s1" > ' _fields' < / span > < span class = "p" > ):< / span >
< span class = "c1" > # obj is a namedtuple. Recurse into it, but the returned< / span >
< span class = "c1" > # object is another namedtuple of the same type. This is< / span >
< span class = "c1" > # similar to how other list- or tuple-derived classes are< / span >
< span class = "c1" > # treated (see below), but we just need to create them< / span >
< span class = "c1" > # differently because a namedtuple' s __init__ needs to be< / span >
< span class = "c1" > # called differently (see bpo-34363).< / span >
< span class = "c1" > # I' m not using namedtuple' s _asdict()< / span >
< span class = "c1" > # method, because:< / span >
< span class = "c1" > # - it does not recurse in to the namedtuple fields and< / span >
< span class = "c1" > # convert them to dicts (using dict_factory).< / span >
< span class = "c1" > # - I don' t actually want to return a dict here. The main< / span >
< span class = "c1" > # use case here is json.dumps, and it handles converting< / span >
< span class = "c1" > # namedtuples to lists. Admittedly we' re losing some< / span >
< span class = "c1" > # information here when we produce a json list instead of a< / span >
< span class = "c1" > # dict. Note that if we returned dicts here instead of< / span >
< span class = "c1" > # namedtuples, we could no longer call asdict() on a data< / span >
< span class = "c1" > # structure where a namedtuple was used as a dict key.< / span >
< span class = "k" > return< / span > < span class = "n" > obj_type< / span > < span class = "p" > (< / span > < span class = "o" > *< / span > < span class = "p" > [< / span > < span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > v< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > )< / span > < span class = "k" > for< / span > < span class = "n" > v< / span > < span class = "ow" > in< / span > < span class = "n" > obj< / span > < span class = "p" > ])< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "n" > obj_type< / span > < span class = "p" > (< / span > < span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > v< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > )< / span > < span class = "k" > for< / span > < span class = "n" > v< / span > < span class = "ow" > in< / span > < span class = "n" > obj< / span > < span class = "p" > )< / span >
< span class = "k" > elif< / span > < span class = "nb" > issubclass< / span > < span class = "p" > (< / span > < span class = "n" > obj_type< / span > < span class = "p" > ,< / span > < span class = "nb" > dict< / span > < span class = "p" > ):< / span >
< span class = "k" > if< / span > < span class = "nb" > hasattr< / span > < span class = "p" > (< / span > < span class = "n" > obj_type< / span > < span class = "p" > ,< / span > < span class = "s1" > ' default_factory' < / span > < span class = "p" > ):< / span >
< span class = "c1" > # obj is a defaultdict, which has a different constructor from< / span >
< span class = "c1" > # dict as it requires the default_factory as its first arg.< / span >
< span class = "n" > result< / span > < span class = "o" > =< / span > < span class = "n" > obj_type< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "o" > .< / span > < span class = "n" > default_factory< / span > < span class = "p" > )< / span >
< span class = "k" > for< / span > < span class = "n" > k< / span > < span class = "p" > ,< / span > < span class = "n" > v< / span > < span class = "ow" > in< / span > < span class = "n" > obj< / span > < span class = "o" > .< / span > < span class = "n" > items< / span > < span class = "p" > ():< / span >
< span class = "n" > result< / span > < span class = "p" > [< / span > < span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > k< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > )]< / span > < span class = "o" > =< / span > < span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > v< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > )< / span >
< span class = "k" > return< / span > < span class = "n" > result< / span >
< span class = "k" > return< / span > < span class = "n" > obj_type< / span > < span class = "p" > ((< / span > < span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > k< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > ),< / span >
< span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > v< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > ))< / span >
< span class = "k" > for< / span > < span class = "n" > k< / span > < span class = "p" > ,< / span > < span class = "n" > v< / span > < span class = "ow" > in< / span > < span class = "n" > obj< / span > < span class = "o" > .< / span > < span class = "n" > items< / span > < span class = "p" > ())< / span >
< span class = "k" > elif< / span > < span class = "nb" > issubclass< / span > < span class = "p" > (< / span > < span class = "n" > obj_type< / span > < span class = "p" > ,< / span > < span class = "nb" > list< / span > < span class = "p" > ):< / span >
< span class = "c1" > # Assume we can create an object of this type by passing in a< / span >
< span class = "c1" > # generator< / span >
< span class = "k" > return< / span > < span class = "n" > obj_type< / span > < span class = "p" > (< / span > < span class = "n" > _asdict_inner< / span > < span class = "p" > (< / span > < span class = "n" > v< / span > < span class = "p" > ,< / span > < span class = "n" > dict_factory< / span > < span class = "p" > )< / span > < span class = "k" > for< / span > < span class = "n" > v< / span > < span class = "ow" > in< / span > < span class = "n" > obj< / span > < span class = "p" > )< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "n" > copy< / span > < span class = "o" > .< / span > < span class = "n" > deepcopy< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > astuple< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "o" > *< / span > < span class = "p" > ,< / span > < span class = "n" > tuple_factory< / span > < span class = "o" > =< / span > < span class = "nb" > tuple< / span > < span class = "p" > ):< / span >
< span class = "w" > < / span > < span class = "sd" > " " " Return the fields of a dataclass instance as a new tuple of field values.< / span >
< span class = "sd" > Example usage::< / span >
< span class = "sd" > @dataclass< / span >
< span class = "sd" > class C:< / span >
< span class = "sd" > x: int< / span >
< span class = "sd" > y: int< / span >
< span class = "sd" > c = C(1, 2)< / span >
< span class = "sd" > assert astuple(c) == (1, 2)< / span >
< span class = "sd" > If given, ' tuple_factory' will be used instead of built-in tuple.< / span >
< span class = "sd" > The function applies recursively to field values that are< / span >
< span class = "sd" > dataclass instances. This will also look into built-in containers:< / span >
< span class = "sd" > tuples, lists, and dicts. Other objects are copied with ' copy.deepcopy()' .< / span >
< span class = "sd" > " " " < / span >
< span class = "k" > if< / span > < span class = "ow" > not< / span > < span class = "n" > _is_dataclass_instance< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ):< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "s2" > " astuple() should be called on dataclass instances" < / span > < span class = "p" > )< / span >
< span class = "k" > return< / span > < span class = "n" > _astuple_inner< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "n" > tuple_factory< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _astuple_inner< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "n" > tuple_factory< / span > < span class = "p" > ):< / span >
< span class = "k" > if< / span > < span class = "nb" > type< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > )< / span > < span class = "ow" > in< / span > < span class = "n" > _ATOMIC_TYPES< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "n" > obj< / span >
< span class = "k" > elif< / span > < span class = "n" > _is_dataclass_instance< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ):< / span >
< span class = "k" > return< / span > < span class = "n" > tuple_factory< / span > < span class = "p" > ([< / span >
< span class = "n" > _astuple_inner< / span > < span class = "p" > (< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > ),< / span > < span class = "n" > tuple_factory< / span > < span class = "p" > )< / span >
< span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > )< / span >
< span class = "p" > ])< / span >
< span class = "k" > elif< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "nb" > tuple< / span > < span class = "p" > )< / span > < span class = "ow" > and< / span > < span class = "nb" > hasattr< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "s1" > ' _fields' < / span > < span class = "p" > ):< / span >
< span class = "c1" > # obj is a namedtuple. Recurse into it, but the returned< / span >
< span class = "c1" > # object is another namedtuple of the same type. This is< / span >
< span class = "c1" > # similar to how other list- or tuple-derived classes are< / span >
< span class = "c1" > # treated (see below), but we just need to create them< / span >
< span class = "c1" > # differently because a namedtuple' s __init__ needs to be< / span >
< span class = "c1" > # called differently (see bpo-34363).< / span >
< span class = "k" > return< / span > < span class = "nb" > type< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > )(< / span > < span class = "o" > *< / span > < span class = "p" > [< / span > < span class = "n" > _astuple_inner< / span > < span class = "p" > (< / span > < span class = "n" > v< / span > < span class = "p" > ,< / span > < span class = "n" > tuple_factory< / span > < span class = "p" > )< / span > < span class = "k" > for< / span > < span class = "n" > v< / span > < span class = "ow" > in< / span > < span class = "n" > obj< / span > < span class = "p" > ])< / span >
< span class = "k" > elif< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "p" > (< / span > < span class = "nb" > list< / span > < span class = "p" > ,< / span > < span class = "nb" > tuple< / span > < span class = "p" > )):< / span >
< span class = "c1" > # Assume we can create an object of this type by passing in a< / span >
< span class = "c1" > # generator (which is not true for namedtuples, handled< / span >
< span class = "c1" > # above).< / span >
< span class = "k" > return< / span > < span class = "nb" > type< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > )(< / span > < span class = "n" > _astuple_inner< / span > < span class = "p" > (< / span > < span class = "n" > v< / span > < span class = "p" > ,< / span > < span class = "n" > tuple_factory< / span > < span class = "p" > )< / span > < span class = "k" > for< / span > < span class = "n" > v< / span > < span class = "ow" > in< / span > < span class = "n" > obj< / span > < span class = "p" > )< / span >
< span class = "k" > elif< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "nb" > dict< / span > < span class = "p" > ):< / span >
< span class = "n" > obj_type< / span > < span class = "o" > =< / span > < span class = "nb" > type< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "nb" > hasattr< / span > < span class = "p" > (< / span > < span class = "n" > obj_type< / span > < span class = "p" > ,< / span > < span class = "s1" > ' default_factory' < / span > < span class = "p" > ):< / span >
< span class = "c1" > # obj is a defaultdict, which has a different constructor from< / span >
< span class = "c1" > # dict as it requires the default_factory as its first arg.< / span >
< span class = "n" > result< / span > < span class = "o" > =< / span > < span class = "n" > obj_type< / span > < span class = "p" > (< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "s1" > ' default_factory' < / span > < span class = "p" > ))< / span >
< span class = "k" > for< / span > < span class = "n" > k< / span > < span class = "p" > ,< / span > < span class = "n" > v< / span > < span class = "ow" > in< / span > < span class = "n" > obj< / span > < span class = "o" > .< / span > < span class = "n" > items< / span > < span class = "p" > ():< / span >
< span class = "n" > result< / span > < span class = "p" > [< / span > < span class = "n" > _astuple_inner< / span > < span class = "p" > (< / span > < span class = "n" > k< / span > < span class = "p" > ,< / span > < span class = "n" > tuple_factory< / span > < span class = "p" > )]< / span > < span class = "o" > =< / span > < span class = "n" > _astuple_inner< / span > < span class = "p" > (< / span > < span class = "n" > v< / span > < span class = "p" > ,< / span > < span class = "n" > tuple_factory< / span > < span class = "p" > )< / span >
< span class = "k" > return< / span > < span class = "n" > result< / span >
< span class = "k" > return< / span > < span class = "n" > obj_type< / span > < span class = "p" > ((< / span > < span class = "n" > _astuple_inner< / span > < span class = "p" > (< / span > < span class = "n" > k< / span > < span class = "p" > ,< / span > < span class = "n" > tuple_factory< / span > < span class = "p" > ),< / span > < span class = "n" > _astuple_inner< / span > < span class = "p" > (< / span > < span class = "n" > v< / span > < span class = "p" > ,< / span > < span class = "n" > tuple_factory< / span > < span class = "p" > ))< / span >
< span class = "k" > for< / span > < span class = "n" > k< / span > < span class = "p" > ,< / span > < span class = "n" > v< / span > < span class = "ow" > in< / span > < span class = "n" > obj< / span > < span class = "o" > .< / span > < span class = "n" > items< / span > < span class = "p" > ())< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "k" > return< / span > < span class = "n" > copy< / span > < span class = "o" > .< / span > < span class = "n" > deepcopy< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > make_dataclass< / span > < span class = "p" > (< / span > < span class = "n" > cls_name< / span > < span class = "p" > ,< / span > < span class = "n" > fields< / span > < span class = "p" > ,< / span > < span class = "o" > *< / span > < span class = "p" > ,< / span > < span class = "n" > bases< / span > < span class = "o" > =< / span > < span class = "p" > (),< / span > < span class = "n" > namespace< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span > < span class = "p" > ,< / span > < span class = "n" > init< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span >
< span class = "nb" > repr< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "n" > eq< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "n" > order< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "n" > unsafe_hash< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span >
< span class = "n" > frozen< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "n" > match_args< / span > < span class = "o" > =< / span > < span class = "kc" > True< / span > < span class = "p" > ,< / span > < span class = "n" > kw_only< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "n" > slots< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span >
< span class = "n" > weakref_slot< / span > < span class = "o" > =< / span > < span class = "kc" > False< / span > < span class = "p" > ,< / span > < span class = "n" > module< / span > < span class = "o" > =< / span > < span class = "kc" > None< / span > < span class = "p" > ):< / span >
< span class = "w" > < / span > < span class = "sd" > " " " Return a new dynamically created dataclass.< / span >
< span class = "sd" > The dataclass name will be ' cls_name' . ' fields' is an iterable< / span >
< span class = "sd" > of either (name), (name, type) or (name, type, Field) objects. If type is< / span >
< span class = "sd" > omitted, use the string ' typing.Any' . Field objects are created by< / span >
< span class = "sd" > the equivalent of calling ' field(name, type [, Field-info])' .::< / span >
< span class = "sd" > C = make_dataclass(' C' , [' x' , (' y' , int), (' z' , int, field(init=False))], bases=(Base,))< / span >
< span class = "sd" > is equivalent to::< / span >
< span class = "sd" > @dataclass< / span >
< span class = "sd" > class C(Base):< / span >
< span class = "sd" > x: ' typing.Any' < / span >
< span class = "sd" > y: int< / span >
< span class = "sd" > z: int = field(init=False)< / span >
< span class = "sd" > For the bases and namespace parameters, see the builtin type() function.< / span >
< span class = "sd" > The parameters init, repr, eq, order, unsafe_hash, frozen, match_args, kw_only,< / span >
< span class = "sd" > slots, and weakref_slot are passed to dataclass().< / span >
< span class = "sd" > If module parameter is defined, the ' __module__' attribute of the dataclass is< / span >
< span class = "sd" > set to that value.< / span >
< span class = "sd" > " " " < / span >
< span class = "k" > if< / span > < span class = "n" > namespace< / span > < span class = "ow" > is< / span > < span class = "kc" > None< / span > < span class = "p" > :< / span >
< span class = "n" > namespace< / span > < span class = "o" > =< / span > < span class = "p" > {}< / span >
< span class = "c1" > # While we' re looking through the field names, validate that they< / span >
< span class = "c1" > # are identifiers, are not keywords, and not duplicates.< / span >
< span class = "n" > seen< / span > < span class = "o" > =< / span > < span class = "nb" > set< / span > < span class = "p" > ()< / span >
< span class = "n" > annotations< / span > < span class = "o" > =< / span > < span class = "p" > {}< / span >
< span class = "n" > defaults< / span > < span class = "o" > =< / span > < span class = "p" > {}< / span >
< span class = "k" > for< / span > < span class = "n" > item< / span > < span class = "ow" > in< / span > < span class = "n" > fields< / span > < span class = "p" > :< / span >
< span class = "k" > if< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "n" > item< / span > < span class = "p" > ,< / span > < span class = "nb" > str< / span > < span class = "p" > ):< / span >
< span class = "n" > name< / span > < span class = "o" > =< / span > < span class = "n" > item< / span >
< span class = "n" > tp< / span > < span class = "o" > =< / span > < span class = "s1" > ' typing.Any' < / span >
< span class = "k" > elif< / span > < span class = "nb" > len< / span > < span class = "p" > (< / span > < span class = "n" > item< / span > < span class = "p" > )< / span > < span class = "o" > ==< / span > < span class = "mi" > 2< / span > < span class = "p" > :< / span >
< span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > tp< / span > < span class = "p" > ,< / span > < span class = "o" > =< / span > < span class = "n" > item< / span >
< span class = "k" > elif< / span > < span class = "nb" > len< / span > < span class = "p" > (< / span > < span class = "n" > item< / span > < span class = "p" > )< / span > < span class = "o" > ==< / span > < span class = "mi" > 3< / span > < span class = "p" > :< / span >
< span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "n" > tp< / span > < span class = "p" > ,< / span > < span class = "n" > spec< / span > < span class = "o" > =< / span > < span class = "n" > item< / span >
< span class = "n" > defaults< / span > < span class = "p" > [< / span > < span class = "n" > name< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "n" > spec< / span >
< span class = "k" > else< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' Invalid field: < / span > < span class = "si" > {< / span > < span class = "n" > item< / span > < span class = "si" > !r}< / span > < span class = "s1" > ' < / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "ow" > not< / span > < span class = "nb" > isinstance< / span > < span class = "p" > (< / span > < span class = "n" > name< / span > < span class = "p" > ,< / span > < span class = "nb" > str< / span > < span class = "p" > )< / span > < span class = "ow" > or< / span > < span class = "ow" > not< / span > < span class = "n" > name< / span > < span class = "o" > .< / span > < span class = "n" > isidentifier< / span > < span class = "p" > ():< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' Field names must be valid identifiers: < / span > < span class = "si" > {< / span > < span class = "n" > name< / span > < span class = "si" > !r}< / span > < span class = "s1" > ' < / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > keyword< / span > < span class = "o" > .< / span > < span class = "n" > iskeyword< / span > < span class = "p" > (< / span > < span class = "n" > name< / span > < span class = "p" > ):< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' Field names must not be keywords: < / span > < span class = "si" > {< / span > < span class = "n" > name< / span > < span class = "si" > !r}< / span > < span class = "s1" > ' < / span > < span class = "p" > )< / span >
< span class = "k" > if< / span > < span class = "n" > name< / span > < span class = "ow" > in< / span > < span class = "n" > seen< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' Field name duplicated: < / span > < span class = "si" > {< / span > < span class = "n" > name< / span > < span class = "si" > !r}< / span > < span class = "s1" > ' < / span > < span class = "p" > )< / span >
< span class = "n" > seen< / span > < span class = "o" > .< / span > < span class = "n" > add< / span > < span class = "p" > (< / span > < span class = "n" > name< / span > < span class = "p" > )< / span >
< span class = "n" > annotations< / span > < span class = "p" > [< / span > < span class = "n" > name< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "n" > tp< / span >
< span class = "c1" > # Update ' ns' with the user-supplied namespace plus our calculated values.< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > exec_body_callback< / span > < span class = "p" > (< / span > < span class = "n" > ns< / span > < span class = "p" > ):< / span >
< span class = "n" > ns< / span > < span class = "o" > .< / span > < span class = "n" > update< / span > < span class = "p" > (< / span > < span class = "n" > namespace< / span > < span class = "p" > )< / span >
< span class = "n" > ns< / span > < span class = "o" > .< / span > < span class = "n" > update< / span > < span class = "p" > (< / span > < span class = "n" > defaults< / span > < span class = "p" > )< / span >
< span class = "n" > ns< / span > < span class = "p" > [< / span > < span class = "s1" > ' __annotations__' < / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "n" > annotations< / span >
< span class = "c1" > # We use `types.new_class()` instead of simply `type()` to allow dynamic creation< / span >
< span class = "c1" > # of generic dataclasses.< / span >
< span class = "bp" > cls< / span > < span class = "o" > =< / span > < span class = "n" > types< / span > < span class = "o" > .< / span > < span class = "n" > new_class< / span > < span class = "p" > (< / span > < span class = "n" > cls_name< / span > < span class = "p" > ,< / span > < span class = "n" > bases< / span > < span class = "p" > ,< / span > < span class = "p" > {},< / span > < span class = "n" > exec_body_callback< / span > < span class = "p" > )< / span >
< span class = "c1" > # For pickling to work, the __module__ variable needs to be set to the frame< / span >
< span class = "c1" > # where the dataclass is created.< / span >
< span class = "k" > if< / span > < span class = "n" > module< / span > < span class = "ow" > is< / span > < span class = "kc" > None< / span > < span class = "p" > :< / span >
< span class = "k" > try< / span > < span class = "p" > :< / span >
< span class = "n" > module< / span > < span class = "o" > =< / span > < span class = "n" > sys< / span > < span class = "o" > .< / span > < span class = "n" > _getframemodulename< / span > < span class = "p" > (< / span > < span class = "mi" > 1< / span > < span class = "p" > )< / span > < span class = "ow" > or< / span > < span class = "s1" > ' __main__' < / span >
< span class = "k" > except< / span > < span class = "ne" > AttributeError< / span > < span class = "p" > :< / span >
< span class = "k" > try< / span > < span class = "p" > :< / span >
< span class = "n" > module< / span > < span class = "o" > =< / span > < span class = "n" > sys< / span > < span class = "o" > .< / span > < span class = "n" > _getframe< / span > < span class = "p" > (< / span > < span class = "mi" > 1< / span > < span class = "p" > )< / span > < span class = "o" > .< / span > < span class = "n" > f_globals< / span > < span class = "o" > .< / span > < span class = "n" > get< / span > < span class = "p" > (< / span > < span class = "s1" > ' __name__' < / span > < span class = "p" > ,< / span > < span class = "s1" > ' __main__' < / span > < span class = "p" > )< / span >
< span class = "k" > except< / span > < span class = "p" > (< / span > < span class = "ne" > AttributeError< / span > < span class = "p" > ,< / span > < span class = "ne" > ValueError< / span > < span class = "p" > ):< / span >
< span class = "k" > pass< / span >
< span class = "k" > if< / span > < span class = "n" > module< / span > < span class = "ow" > is< / span > < span class = "ow" > not< / span > < span class = "kc" > None< / span > < span class = "p" > :< / span >
< span class = "bp" > cls< / span > < span class = "o" > .< / span > < span class = "vm" > __module__< / span > < span class = "o" > =< / span > < span class = "n" > module< / span >
< span class = "c1" > # Apply the normal decorator.< / span >
< span class = "k" > return< / span > < span class = "n" > dataclass< / span > < span class = "p" > (< / span > < span class = "bp" > cls< / span > < span class = "p" > ,< / span > < span class = "n" > init< / span > < span class = "o" > =< / span > < span class = "n" > init< / span > < span class = "p" > ,< / span > < span class = "nb" > repr< / span > < span class = "o" > =< / span > < span class = "nb" > repr< / span > < span class = "p" > ,< / span > < span class = "n" > eq< / span > < span class = "o" > =< / span > < span class = "n" > eq< / span > < span class = "p" > ,< / span > < span class = "n" > order< / span > < span class = "o" > =< / span > < span class = "n" > order< / span > < span class = "p" > ,< / span >
< span class = "n" > unsafe_hash< / span > < span class = "o" > =< / span > < span class = "n" > unsafe_hash< / span > < span class = "p" > ,< / span > < span class = "n" > frozen< / span > < span class = "o" > =< / span > < span class = "n" > frozen< / span > < span class = "p" > ,< / span >
< span class = "n" > match_args< / span > < span class = "o" > =< / span > < span class = "n" > match_args< / span > < span class = "p" > ,< / span > < span class = "n" > kw_only< / span > < span class = "o" > =< / span > < span class = "n" > kw_only< / span > < span class = "p" > ,< / span > < span class = "n" > slots< / span > < span class = "o" > =< / span > < span class = "n" > slots< / span > < span class = "p" > ,< / span >
< span class = "n" > weakref_slot< / span > < span class = "o" > =< / span > < span class = "n" > weakref_slot< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > replace< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "o" > /< / span > < span class = "p" > ,< / span > < span class = "o" > **< / span > < span class = "n" > changes< / span > < span class = "p" > ):< / span >
< span class = "w" > < / span > < span class = "sd" > " " " Return a new object replacing specified fields with new values.< / span >
< span class = "sd" > This is especially useful for frozen classes. Example usage::< / span >
< span class = "sd" > @dataclass(frozen=True)< / span >
< span class = "sd" > class C:< / span >
< span class = "sd" > x: int< / span >
< span class = "sd" > y: int< / span >
< span class = "sd" > c = C(1, 2)< / span >
< span class = "sd" > c1 = replace(c, x=3)< / span >
< span class = "sd" > assert c1.x == 3 and c1.y == 2< / span >
< span class = "sd" > " " " < / span >
< span class = "k" > if< / span > < span class = "ow" > not< / span > < span class = "n" > _is_dataclass_instance< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ):< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "s2" > " replace() should be called on dataclass instances" < / span > < span class = "p" > )< / span >
< span class = "k" > return< / span > < span class = "n" > _replace< / span > < span class = "p" > (< / span > < span class = "n" > obj< / span > < span class = "p" > ,< / span > < span class = "o" > **< / span > < span class = "n" > changes< / span > < span class = "p" > )< / span >
< span class = "k" > def< / span > < span class = "w" > < / span > < span class = "nf" > _replace< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "o" > /< / span > < span class = "p" > ,< / span > < span class = "o" > **< / span > < span class = "n" > changes< / span > < span class = "p" > ):< / span >
< span class = "c1" > # We' re going to mutate ' changes' , but that' s okay because it' s a< / span >
< span class = "c1" > # new dict, even if called with ' replace(self, **my_changes)' .< / span >
< span class = "c1" > # It' s an error to have init=False fields in ' changes' .< / span >
< span class = "c1" > # If a field is not in ' changes' , read its value from the provided ' self' .< / span >
< span class = "k" > for< / span > < span class = "n" > f< / span > < span class = "ow" > in< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "n" > _FIELDS< / span > < span class = "p" > )< / span > < span class = "o" > .< / span > < span class = "n" > values< / span > < span class = "p" > ():< / span >
< span class = "c1" > # Only consider normal fields or InitVars.< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "ow" > is< / span > < span class = "n" > _FIELD_CLASSVAR< / span > < span class = "p" > :< / span >
< span class = "k" > continue< / span >
< span class = "k" > if< / span > < span class = "ow" > not< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > init< / span > < span class = "p" > :< / span >
< span class = "c1" > # Error if this field is specified in changes.< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "ow" > in< / span > < span class = "n" > changes< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s1" > ' field < / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > }< / span > < span class = "s1" > is declared with ' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' init=False, it cannot be specified with ' < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' replace()' < / span > < span class = "p" > )< / span >
< span class = "k" > continue< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "ow" > not< / span > < span class = "ow" > in< / span > < span class = "n" > changes< / span > < span class = "p" > :< / span >
< span class = "k" > if< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > _field_type< / span > < span class = "ow" > is< / span > < span class = "n" > _FIELD_INITVAR< / span > < span class = "ow" > and< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > default< / span > < span class = "ow" > is< / span > < span class = "n" > MISSING< / span > < span class = "p" > :< / span >
< span class = "k" > raise< / span > < span class = "ne" > TypeError< / span > < span class = "p" > (< / span > < span class = "sa" > f< / span > < span class = "s2" > " InitVar < / span > < span class = "si" > {< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "si" > !r}< / span > < span class = "s2" > " < / span >
< span class = "sa" > f< / span > < span class = "s1" > ' must be specified with replace()' < / span > < span class = "p" > )< / span >
< span class = "n" > changes< / span > < span class = "p" > [< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > ]< / span > < span class = "o" > =< / span > < span class = "nb" > getattr< / span > < span class = "p" > (< / span > < span class = "bp" > self< / span > < span class = "p" > ,< / span > < span class = "n" > f< / span > < span class = "o" > .< / span > < span class = "n" > name< / span > < span class = "p" > )< / span >
< span class = "c1" > # Create the new object, which calls __init__() and< / span >
< span class = "c1" > # __post_init__() (if defined), using all of the init fields we' ve< / span >
< span class = "c1" > # added and/or left in ' changes' . If there are values supplied in< / span >
< span class = "c1" > # changes that aren' t fields, this will correctly raise a< / span >
< span class = "c1" > # TypeError.< / span >
< span class = "k" > return< / span > < span class = "bp" > self< / span > < span class = "o" > .< / span > < span class = "vm" > __class__< / span > < span class = "p" > (< / span > < span class = "o" > **< / span > < span class = "n" > changes< / span > < span class = "p" > )< / span >
< / pre > < / div >
< div class = "clearer" > < / div >
< / div >
< / div >
< / div >
< div class = "sphinxsidebar" role = "navigation" aria-label = "Main" >
< div class = "sphinxsidebarwrapper" >
< p class = "logo" > < a href = "../index.html" >
< img class = "logo" src = "../_static/evennia_logo.png" alt = "Logo of Evennia" / >
< / a > < / p >
< search id = "searchbox" style = "display: none" role = "search" >
< h3 id = "searchlabel" > Quick search< / h3 >
< div class = "searchformwrapper" >
< form class = "search" action = "../search.html" method = "get" >
< input type = "text" name = "q" aria-labelledby = "searchlabel" autocomplete = "off" autocorrect = "off" autocapitalize = "off" spellcheck = "false" / >
< input type = "submit" value = "Go" / >
< / form >
< / div >
< / search >
< script > document . getElementById ( 'searchbox' ) . style . display = "block" < / script > < h3 > Links< / h3 >
< ul >
< li > < a href = "https://www.evennia.com/docs/latest/index.html" > Documentation Top< / a > < / li >
< li > < a href = "https://www.evennia.com" > Evennia Home< / a > < / li >
< li > < a href = "https://github.com/evennia/evennia" > Github< / a > < / li >
< li > < a href = "http://games.evennia.com" > Game Index< / a > < / li >
< li >
< a href = "https://discord.gg/AJJpcRUhtF" > Discord< / a > -
< a href = "https://github.com/evennia/evennia/discussions" > Discussions< / a > -
< a href = "https://evennia.blogspot.com/" > Blog< / a >
< / li >
< / ul >
< h3 > Doc Versions< / h3 >
< ul >
< li >
< a href = "https://www.evennia.com/docs/latest/index.html" > latest (main branch)< / a >
< / li >
2026-02-15 18:13:08 +00:00
< li >
< a href = "https://www.evennia.com/docs/6.x/index.html" > v6.0.0 branch (outdated)< / a >
< / li >
2025-08-15 18:14:21 +00:00
< li >
< a href = "https://www.evennia.com/docs/5.x/index.html" > v5.0.0 branch (outdated)< / a >
< / li >
< li >
< a href = "https://www.evennia.com/docs/4.x/index.html" > v4.0.0 branch (outdated)< / a >
< / li >
< li >
< a href = "https://www.evennia.com/docs/3.x/index.html" > v3.0.0 branch (outdated)< / a >
< / li >
< li >
< a href = "https://www.evennia.com/docs/2.x/index.html" > v2.0.0 branch (outdated)< / a >
< / li >
< li >
< a href = "https://www.evennia.com/docs/1.x/index.html" > v1.0.0 branch (outdated)< / a >
< / li >
< li >
< a href = "https://www.evennia.com/docs/0.x/index.html" > v0.9.5 branch (outdated)< / a >
< / li >
< / ul >
< / div >
< / div >
< div class = "clearer" > < / div >
< / div >
< div class = "related" role = "navigation" aria-label = "Related" >
< h3 > Navigation< / h3 >
< ul >
< li class = "right" style = "margin-right: 10px" >
< a href = "../genindex.html" title = "General Index"
>index< / a > < / li >
< li class = "right" >
< a href = "../py-modindex.html" title = "Python Module Index"
>modules< / a > |< / li >
< li class = "nav-item nav-item-0" > < a href = "../index.html" > Evennia< / a > » < / li >
< li class = "nav-item nav-item-1" > < a href = "index.html" > Module code< / a > » < / li >
< li class = "nav-item nav-item-this" > < a href = "" > dataclasses< / a > < / li >
< / ul >
< / div >
< div class = "footer" role = "contentinfo" >
© Copyright 2024, The Evennia developer community.
Created using < a href = "https://www.sphinx-doc.org/" > Sphinx< / a > 8.2.3.
< / div >
< / body >
< / html >