# SPDX-License-Identifier: MIT"""These are keyword-only APIs that call `attr.s` and `attr.ib` with differentdefault values."""fromfunctoolsimportpartialfrom.importsettersfrom._funcsimportasdictas_asdictfrom._funcsimportastupleas_astuplefrom._makeimport(NOTHING,_frozen_setattrs,_ng_default_on_setattr,attrib,attrs,)from.exceptionsimportUnannotatedAttributeError
[docs]defdefine(maybe_cls=None,*,these=None,repr=None,unsafe_hash=None,hash=None,init=None,slots=True,frozen=False,weakref_slot=True,str=False,auto_attribs=None,kw_only=False,cache_hash=False,auto_exc=True,eq=None,order=False,auto_detect=True,getstate_setstate=None,on_setattr=None,field_transformer=None,match_args=True,):r""" Define an *attrs* class. Differences to the classic `attr.s` that it uses underneath: - Automatically detect whether or not *auto_attribs* should be `True` (c.f. *auto_attribs* parameter). - Converters and validators run when attributes are set by default -- if *frozen* is `False`. - *slots=True* .. caution:: Usually this has only upsides and few visible effects in everyday programming. But it *can* lead to some surprising behaviors, so please make sure to read :term:`slotted classes`. - *auto_exc=True* - *auto_detect=True* - *order=False* - Some options that were only relevant on Python 2 or were kept around for backwards-compatibility have been removed. Please note that these are all defaults and you can change them as you wish. :param Optional[bool] auto_attribs: If set to `True` or `False`, it behaves exactly like `attr.s`. If left `None`, `attr.s` will try to guess: 1. If any attributes are annotated and no unannotated `attrs.fields`\ s are found, it assumes *auto_attribs=True*. 2. Otherwise it assumes *auto_attribs=False* and tries to collect `attrs.fields`\ s. For now, please refer to `attr.s` for the rest of the parameters. .. versionadded:: 20.1.0 .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``. .. versionadded:: 22.2.0 *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance). """defdo_it(cls,auto_attribs):returnattrs(maybe_cls=cls,these=these,repr=repr,hash=hash,unsafe_hash=unsafe_hash,init=init,slots=slots,frozen=frozen,weakref_slot=weakref_slot,str=str,auto_attribs=auto_attribs,kw_only=kw_only,cache_hash=cache_hash,auto_exc=auto_exc,eq=eq,order=order,auto_detect=auto_detect,collect_by_mro=True,getstate_setstate=getstate_setstate,on_setattr=on_setattr,field_transformer=field_transformer,match_args=match_args,)defwrap(cls):""" Making this a wrapper ensures this code runs during class creation. We also ensure that frozen-ness of classes is inherited. """nonlocalfrozen,on_setattrhad_on_setattr=on_setattrnotin(None,setters.NO_OP)# By default, mutable classes convert & validate on setattr.iffrozenisFalseandon_setattrisNone:on_setattr=_ng_default_on_setattr# However, if we subclass a frozen class, we inherit the immutability# and disable on_setattr.forbase_clsincls.__bases__:ifbase_cls.__setattr__is_frozen_setattrs:ifhad_on_setattr:msg="Frozen classes can't use on_setattr (frozen-ness was inherited)."raiseValueError(msg)on_setattr=setters.NO_OPbreakifauto_attribsisnotNone:returndo_it(cls,auto_attribs)try:returndo_it(cls,True)exceptUnannotatedAttributeError:returndo_it(cls,False)# maybe_cls's type depends on the usage of the decorator. It's a class# if it's used as `@attrs` but ``None`` if used as `@attrs()`.ifmaybe_clsisNone:returnwrapreturnwrap(maybe_cls)
[docs]deffield(*,default=NOTHING,validator=None,repr=True,hash=None,init=True,metadata=None,type=None,converter=None,factory=None,kw_only=False,eq=None,order=None,on_setattr=None,alias=None,):""" Identical to `attr.ib`, except keyword-only and with some arguments removed. .. versionadded:: 23.1.0 The *type* parameter has been re-added; mostly for `attrs.make_class`. Please note that type checkers ignore this metadata. .. versionadded:: 20.1.0 """returnattrib(default=default,validator=validator,repr=repr,hash=hash,init=init,metadata=metadata,type=type,converter=converter,factory=factory,kw_only=kw_only,eq=eq,order=order,on_setattr=on_setattr,alias=alias,)
[docs]defasdict(inst,*,recurse=True,filter=None,value_serializer=None):""" Same as `attr.asdict`, except that collections types are always retained and dict is always used as *dict_factory*. .. versionadded:: 21.3.0 """return_asdict(inst=inst,recurse=recurse,filter=filter,value_serializer=value_serializer,retain_collection_types=True,)
[docs]defastuple(inst,*,recurse=True,filter=None):""" Same as `attr.astuple`, except that collections types are always retained and `tuple` is always used as the *tuple_factory*. .. versionadded:: 21.3.0 """return_astuple(inst=inst,recurse=recurse,filter=filter,retain_collection_types=True)