Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/attr/_next_gen.py: 87%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# SPDX-License-Identifier: MIT
3"""
4These are keyword-only APIs that call `attr.s` and `attr.ib` with different
5default values.
6"""
9from functools import partial
11from . import setters
12from ._funcs import asdict as _asdict
13from ._funcs import astuple as _astuple
14from ._make import (
15 NOTHING,
16 _frozen_setattrs,
17 _ng_default_on_setattr,
18 attrib,
19 attrs,
20)
21from .exceptions import UnannotatedAttributeError
24def define(
25 maybe_cls=None,
26 *,
27 these=None,
28 repr=None,
29 unsafe_hash=None,
30 hash=None,
31 init=None,
32 slots=True,
33 frozen=False,
34 weakref_slot=True,
35 str=False,
36 auto_attribs=None,
37 kw_only=False,
38 cache_hash=False,
39 auto_exc=True,
40 eq=None,
41 order=False,
42 auto_detect=True,
43 getstate_setstate=None,
44 on_setattr=None,
45 field_transformer=None,
46 match_args=True,
47):
48 r"""
49 Define an *attrs* class.
51 Differences to the classic `attr.s` that it uses underneath:
53 - Automatically detect whether or not *auto_attribs* should be `True` (c.f.
54 *auto_attribs* parameter).
55 - Converters and validators run when attributes are set by default -- if
56 *frozen* is `False`.
57 - *slots=True*
59 .. caution::
61 Usually this has only upsides and few visible effects in everyday
62 programming. But it *can* lead to some surprising behaviors, so please
63 make sure to read :term:`slotted classes`.
64 - *auto_exc=True*
65 - *auto_detect=True*
66 - *order=False*
67 - Some options that were only relevant on Python 2 or were kept around for
68 backwards-compatibility have been removed.
70 Please note that these are all defaults and you can change them as you
71 wish.
73 :param Optional[bool] auto_attribs: If set to `True` or `False`, it behaves
74 exactly like `attr.s`. If left `None`, `attr.s` will try to guess:
76 1. If any attributes are annotated and no unannotated `attrs.fields`\ s
77 are found, it assumes *auto_attribs=True*.
78 2. Otherwise it assumes *auto_attribs=False* and tries to collect
79 `attrs.fields`\ s.
81 For now, please refer to `attr.s` for the rest of the parameters.
83 .. versionadded:: 20.1.0
84 .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``.
85 .. versionadded:: 22.2.0
86 *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance).
87 """
89 def do_it(cls, auto_attribs):
90 return attrs(
91 maybe_cls=cls,
92 these=these,
93 repr=repr,
94 hash=hash,
95 unsafe_hash=unsafe_hash,
96 init=init,
97 slots=slots,
98 frozen=frozen,
99 weakref_slot=weakref_slot,
100 str=str,
101 auto_attribs=auto_attribs,
102 kw_only=kw_only,
103 cache_hash=cache_hash,
104 auto_exc=auto_exc,
105 eq=eq,
106 order=order,
107 auto_detect=auto_detect,
108 collect_by_mro=True,
109 getstate_setstate=getstate_setstate,
110 on_setattr=on_setattr,
111 field_transformer=field_transformer,
112 match_args=match_args,
113 )
115 def wrap(cls):
116 """
117 Making this a wrapper ensures this code runs during class creation.
119 We also ensure that frozen-ness of classes is inherited.
120 """
121 nonlocal frozen, on_setattr
123 had_on_setattr = on_setattr not in (None, setters.NO_OP)
125 # By default, mutable classes convert & validate on setattr.
126 if frozen is False and on_setattr is None:
127 on_setattr = _ng_default_on_setattr
129 # However, if we subclass a frozen class, we inherit the immutability
130 # and disable on_setattr.
131 for base_cls in cls.__bases__:
132 if base_cls.__setattr__ is _frozen_setattrs:
133 if had_on_setattr:
134 msg = "Frozen classes can't use on_setattr (frozen-ness was inherited)."
135 raise ValueError(msg)
137 on_setattr = setters.NO_OP
138 break
140 if auto_attribs is not None:
141 return do_it(cls, auto_attribs)
143 try:
144 return do_it(cls, True)
145 except UnannotatedAttributeError:
146 return do_it(cls, False)
148 # maybe_cls's type depends on the usage of the decorator. It's a class
149 # if it's used as `@attrs` but ``None`` if used as `@attrs()`.
150 if maybe_cls is None:
151 return wrap
153 return wrap(maybe_cls)
156mutable = define
157frozen = partial(define, frozen=True, on_setattr=None)
160def field(
161 *,
162 default=NOTHING,
163 validator=None,
164 repr=True,
165 hash=None,
166 init=True,
167 metadata=None,
168 type=None,
169 converter=None,
170 factory=None,
171 kw_only=False,
172 eq=None,
173 order=None,
174 on_setattr=None,
175 alias=None,
176):
177 """
178 Identical to `attr.ib`, except keyword-only and with some arguments
179 removed.
181 .. versionadded:: 23.1.0
182 The *type* parameter has been re-added; mostly for `attrs.make_class`.
183 Please note that type checkers ignore this metadata.
184 .. versionadded:: 20.1.0
185 """
186 return attrib(
187 default=default,
188 validator=validator,
189 repr=repr,
190 hash=hash,
191 init=init,
192 metadata=metadata,
193 type=type,
194 converter=converter,
195 factory=factory,
196 kw_only=kw_only,
197 eq=eq,
198 order=order,
199 on_setattr=on_setattr,
200 alias=alias,
201 )
204def asdict(inst, *, recurse=True, filter=None, value_serializer=None):
205 """
206 Same as `attr.asdict`, except that collections types are always retained
207 and dict is always used as *dict_factory*.
209 .. versionadded:: 21.3.0
210 """
211 return _asdict(
212 inst=inst,
213 recurse=recurse,
214 filter=filter,
215 value_serializer=value_serializer,
216 retain_collection_types=True,
217 )
220def astuple(inst, *, recurse=True, filter=None):
221 """
222 Same as `attr.astuple`, except that collections types are always retained
223 and `tuple` is always used as the *tuple_factory*.
225 .. versionadded:: 21.3.0
226 """
227 return _astuple(
228 inst=inst, recurse=recurse, filter=filter, retain_collection_types=True
229 )