Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/attr/_next_gen.py: 89%
37 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
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 - If *frozen* is `False`, run converters and validators when setting an
56 attribute by default.
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 suprising 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 raise ValueError(
135 "Frozen classes can't use on_setattr "
136 "(frozen-ness was inherited)."
137 )
139 on_setattr = setters.NO_OP
140 break
142 if auto_attribs is not None:
143 return do_it(cls, auto_attribs)
145 try:
146 return do_it(cls, True)
147 except UnannotatedAttributeError:
148 return do_it(cls, False)
150 # maybe_cls's type depends on the usage of the decorator. It's a class
151 # if it's used as `@attrs` but ``None`` if used as `@attrs()`.
152 if maybe_cls is None:
153 return wrap
154 else:
155 return wrap(maybe_cls)
158mutable = define
159frozen = partial(define, frozen=True, on_setattr=None)
162def field(
163 *,
164 default=NOTHING,
165 validator=None,
166 repr=True,
167 hash=None,
168 init=True,
169 metadata=None,
170 type=None,
171 converter=None,
172 factory=None,
173 kw_only=False,
174 eq=None,
175 order=None,
176 on_setattr=None,
177 alias=None,
178):
179 """
180 Identical to `attr.ib`, except keyword-only and with some arguments
181 removed.
183 .. versionadded:: 23.1.0
184 The *type* parameter has been re-added; mostly for
185 {func}`attrs.make_class`. Please note that type checkers ignore this
186 metadata.
187 .. versionadded:: 20.1.0
188 """
189 return attrib(
190 default=default,
191 validator=validator,
192 repr=repr,
193 hash=hash,
194 init=init,
195 metadata=metadata,
196 type=type,
197 converter=converter,
198 factory=factory,
199 kw_only=kw_only,
200 eq=eq,
201 order=order,
202 on_setattr=on_setattr,
203 alias=alias,
204 )
207def asdict(inst, *, recurse=True, filter=None, value_serializer=None):
208 """
209 Same as `attr.asdict`, except that collections types are always retained
210 and dict is always used as *dict_factory*.
212 .. versionadded:: 21.3.0
213 """
214 return _asdict(
215 inst=inst,
216 recurse=recurse,
217 filter=filter,
218 value_serializer=value_serializer,
219 retain_collection_types=True,
220 )
223def astuple(inst, *, recurse=True, filter=None):
224 """
225 Same as `attr.astuple`, except that collections types are always retained
226 and `tuple` is always used as the *tuple_factory*.
228 .. versionadded:: 21.3.0
229 """
230 return _astuple(
231 inst=inst, recurse=recurse, filter=filter, retain_collection_types=True
232 )