49643
|
1 import sys
|
|
2
|
|
3 from typing import (
|
|
4 Any,
|
|
5 Callable,
|
|
6 ClassVar,
|
|
7 Dict,
|
|
8 Generic,
|
|
9 List,
|
|
10 Mapping,
|
|
11 Optional,
|
|
12 Protocol,
|
|
13 Sequence,
|
|
14 Tuple,
|
|
15 Type,
|
|
16 TypeVar,
|
|
17 Union,
|
|
18 overload,
|
|
19 )
|
|
20
|
|
21 # `import X as X` is required to make these public
|
|
22 from . import converters as converters
|
|
23 from . import exceptions as exceptions
|
|
24 from . import filters as filters
|
|
25 from . import setters as setters
|
|
26 from . import validators as validators
|
|
27 from ._cmp import cmp_using as cmp_using
|
|
28 from ._version_info import VersionInfo
|
|
29
|
|
30 __version__: str
|
|
31 __version_info__: VersionInfo
|
|
32 __title__: str
|
|
33 __description__: str
|
|
34 __url__: str
|
|
35 __uri__: str
|
|
36 __author__: str
|
|
37 __email__: str
|
|
38 __license__: str
|
|
39 __copyright__: str
|
|
40
|
|
41 _T = TypeVar("_T")
|
|
42 _C = TypeVar("_C", bound=type)
|
|
43
|
|
44 _EqOrderType = Union[bool, Callable[[Any], Any]]
|
|
45 _ValidatorType = Callable[[Any, Attribute[_T], _T], Any]
|
|
46 _ConverterType = Callable[[Any], Any]
|
|
47 _FilterType = Callable[[Attribute[_T], _T], bool]
|
|
48 _ReprType = Callable[[Any], str]
|
|
49 _ReprArgType = Union[bool, _ReprType]
|
|
50 _OnSetAttrType = Callable[[Any, Attribute[Any], Any], Any]
|
|
51 _OnSetAttrArgType = Union[
|
|
52 _OnSetAttrType, List[_OnSetAttrType], setters._NoOpType
|
|
53 ]
|
|
54 _FieldTransformer = Callable[
|
|
55 [type, List[Attribute[Any]]], List[Attribute[Any]]
|
|
56 ]
|
|
57 # FIXME: in reality, if multiple validators are passed they must be in a list
|
|
58 # or tuple, but those are invariant and so would prevent subtypes of
|
|
59 # _ValidatorType from working when passed in a list or tuple.
|
|
60 _ValidatorArgType = Union[_ValidatorType[_T], Sequence[_ValidatorType[_T]]]
|
|
61
|
|
62 # A protocol to be able to statically accept an attrs class.
|
|
63 class AttrsInstance(Protocol):
|
|
64 __attrs_attrs__: ClassVar[Any]
|
|
65
|
|
66 # _make --
|
|
67
|
|
68 NOTHING: object
|
|
69
|
|
70 # NOTE: Factory lies about its return type to make this possible:
|
|
71 # `x: List[int] # = Factory(list)`
|
|
72 # Work around mypy issue #4554 in the common case by using an overload.
|
|
73 if sys.version_info >= (3, 8):
|
|
74 from typing import Literal
|
|
75 @overload
|
|
76 def Factory(factory: Callable[[], _T]) -> _T: ...
|
|
77 @overload
|
|
78 def Factory(
|
|
79 factory: Callable[[Any], _T],
|
|
80 takes_self: Literal[True],
|
|
81 ) -> _T: ...
|
|
82 @overload
|
|
83 def Factory(
|
|
84 factory: Callable[[], _T],
|
|
85 takes_self: Literal[False],
|
|
86 ) -> _T: ...
|
|
87
|
|
88 else:
|
|
89 @overload
|
|
90 def Factory(factory: Callable[[], _T]) -> _T: ...
|
|
91 @overload
|
|
92 def Factory(
|
|
93 factory: Union[Callable[[Any], _T], Callable[[], _T]],
|
|
94 takes_self: bool = ...,
|
|
95 ) -> _T: ...
|
|
96
|
|
97 # Static type inference support via __dataclass_transform__ implemented as per:
|
|
98 # https://github.com/microsoft/pyright/blob/1.1.135/specs/dataclass_transforms.md
|
|
99 # This annotation must be applied to all overloads of "define" and "attrs"
|
|
100 #
|
|
101 # NOTE: This is a typing construct and does not exist at runtime. Extensions
|
|
102 # wrapping attrs decorators should declare a separate __dataclass_transform__
|
|
103 # signature in the extension module using the specification linked above to
|
|
104 # provide pyright support.
|
|
105 def __dataclass_transform__(
|
|
106 *,
|
|
107 eq_default: bool = True,
|
|
108 order_default: bool = False,
|
|
109 kw_only_default: bool = False,
|
|
110 field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()),
|
|
111 ) -> Callable[[_T], _T]: ...
|
|
112
|
|
113 class Attribute(Generic[_T]):
|
|
114 name: str
|
|
115 default: Optional[_T]
|
|
116 validator: Optional[_ValidatorType[_T]]
|
|
117 repr: _ReprArgType
|
|
118 cmp: _EqOrderType
|
|
119 eq: _EqOrderType
|
|
120 order: _EqOrderType
|
|
121 hash: Optional[bool]
|
|
122 init: bool
|
|
123 converter: Optional[_ConverterType]
|
|
124 metadata: Dict[Any, Any]
|
|
125 type: Optional[Type[_T]]
|
|
126 kw_only: bool
|
|
127 on_setattr: _OnSetAttrType
|
|
128 def evolve(self, **changes: Any) -> "Attribute[Any]": ...
|
|
129
|
|
130 # NOTE: We had several choices for the annotation to use for type arg:
|
|
131 # 1) Type[_T]
|
|
132 # - Pros: Handles simple cases correctly
|
|
133 # - Cons: Might produce less informative errors in the case of conflicting
|
|
134 # TypeVars e.g. `attr.ib(default='bad', type=int)`
|
|
135 # 2) Callable[..., _T]
|
|
136 # - Pros: Better error messages than #1 for conflicting TypeVars
|
|
137 # - Cons: Terrible error messages for validator checks.
|
|
138 # e.g. attr.ib(type=int, validator=validate_str)
|
|
139 # -> error: Cannot infer function type argument
|
|
140 # 3) type (and do all of the work in the mypy plugin)
|
|
141 # - Pros: Simple here, and we could customize the plugin with our own errors.
|
|
142 # - Cons: Would need to write mypy plugin code to handle all the cases.
|
|
143 # We chose option #1.
|
|
144
|
|
145 # `attr` lies about its return type to make the following possible:
|
|
146 # attr() -> Any
|
|
147 # attr(8) -> int
|
|
148 # attr(validator=<some callable>) -> Whatever the callable expects.
|
|
149 # This makes this type of assignments possible:
|
|
150 # x: int = attr(8)
|
|
151 #
|
|
152 # This form catches explicit None or no default but with no other arguments
|
|
153 # returns Any.
|
|
154 @overload
|
|
155 def attrib(
|
|
156 default: None = ...,
|
|
157 validator: None = ...,
|
|
158 repr: _ReprArgType = ...,
|
|
159 cmp: Optional[_EqOrderType] = ...,
|
|
160 hash: Optional[bool] = ...,
|
|
161 init: bool = ...,
|
|
162 metadata: Optional[Mapping[Any, Any]] = ...,
|
|
163 type: None = ...,
|
|
164 converter: None = ...,
|
|
165 factory: None = ...,
|
|
166 kw_only: bool = ...,
|
|
167 eq: Optional[_EqOrderType] = ...,
|
|
168 order: Optional[_EqOrderType] = ...,
|
|
169 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
170 ) -> Any: ...
|
|
171
|
|
172 # This form catches an explicit None or no default and infers the type from the
|
|
173 # other arguments.
|
|
174 @overload
|
|
175 def attrib(
|
|
176 default: None = ...,
|
|
177 validator: Optional[_ValidatorArgType[_T]] = ...,
|
|
178 repr: _ReprArgType = ...,
|
|
179 cmp: Optional[_EqOrderType] = ...,
|
|
180 hash: Optional[bool] = ...,
|
|
181 init: bool = ...,
|
|
182 metadata: Optional[Mapping[Any, Any]] = ...,
|
|
183 type: Optional[Type[_T]] = ...,
|
|
184 converter: Optional[_ConverterType] = ...,
|
|
185 factory: Optional[Callable[[], _T]] = ...,
|
|
186 kw_only: bool = ...,
|
|
187 eq: Optional[_EqOrderType] = ...,
|
|
188 order: Optional[_EqOrderType] = ...,
|
|
189 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
190 ) -> _T: ...
|
|
191
|
|
192 # This form catches an explicit default argument.
|
|
193 @overload
|
|
194 def attrib(
|
|
195 default: _T,
|
|
196 validator: Optional[_ValidatorArgType[_T]] = ...,
|
|
197 repr: _ReprArgType = ...,
|
|
198 cmp: Optional[_EqOrderType] = ...,
|
|
199 hash: Optional[bool] = ...,
|
|
200 init: bool = ...,
|
|
201 metadata: Optional[Mapping[Any, Any]] = ...,
|
|
202 type: Optional[Type[_T]] = ...,
|
|
203 converter: Optional[_ConverterType] = ...,
|
|
204 factory: Optional[Callable[[], _T]] = ...,
|
|
205 kw_only: bool = ...,
|
|
206 eq: Optional[_EqOrderType] = ...,
|
|
207 order: Optional[_EqOrderType] = ...,
|
|
208 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
209 ) -> _T: ...
|
|
210
|
|
211 # This form covers type=non-Type: e.g. forward references (str), Any
|
|
212 @overload
|
|
213 def attrib(
|
|
214 default: Optional[_T] = ...,
|
|
215 validator: Optional[_ValidatorArgType[_T]] = ...,
|
|
216 repr: _ReprArgType = ...,
|
|
217 cmp: Optional[_EqOrderType] = ...,
|
|
218 hash: Optional[bool] = ...,
|
|
219 init: bool = ...,
|
|
220 metadata: Optional[Mapping[Any, Any]] = ...,
|
|
221 type: object = ...,
|
|
222 converter: Optional[_ConverterType] = ...,
|
|
223 factory: Optional[Callable[[], _T]] = ...,
|
|
224 kw_only: bool = ...,
|
|
225 eq: Optional[_EqOrderType] = ...,
|
|
226 order: Optional[_EqOrderType] = ...,
|
|
227 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
228 ) -> Any: ...
|
|
229 @overload
|
|
230 def field(
|
|
231 *,
|
|
232 default: None = ...,
|
|
233 validator: None = ...,
|
|
234 repr: _ReprArgType = ...,
|
|
235 hash: Optional[bool] = ...,
|
|
236 init: bool = ...,
|
|
237 metadata: Optional[Mapping[Any, Any]] = ...,
|
|
238 converter: None = ...,
|
|
239 factory: None = ...,
|
|
240 kw_only: bool = ...,
|
|
241 eq: Optional[bool] = ...,
|
|
242 order: Optional[bool] = ...,
|
|
243 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
244 ) -> Any: ...
|
|
245
|
|
246 # This form catches an explicit None or no default and infers the type from the
|
|
247 # other arguments.
|
|
248 @overload
|
|
249 def field(
|
|
250 *,
|
|
251 default: None = ...,
|
|
252 validator: Optional[_ValidatorArgType[_T]] = ...,
|
|
253 repr: _ReprArgType = ...,
|
|
254 hash: Optional[bool] = ...,
|
|
255 init: bool = ...,
|
|
256 metadata: Optional[Mapping[Any, Any]] = ...,
|
|
257 converter: Optional[_ConverterType] = ...,
|
|
258 factory: Optional[Callable[[], _T]] = ...,
|
|
259 kw_only: bool = ...,
|
|
260 eq: Optional[_EqOrderType] = ...,
|
|
261 order: Optional[_EqOrderType] = ...,
|
|
262 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
263 ) -> _T: ...
|
|
264
|
|
265 # This form catches an explicit default argument.
|
|
266 @overload
|
|
267 def field(
|
|
268 *,
|
|
269 default: _T,
|
|
270 validator: Optional[_ValidatorArgType[_T]] = ...,
|
|
271 repr: _ReprArgType = ...,
|
|
272 hash: Optional[bool] = ...,
|
|
273 init: bool = ...,
|
|
274 metadata: Optional[Mapping[Any, Any]] = ...,
|
|
275 converter: Optional[_ConverterType] = ...,
|
|
276 factory: Optional[Callable[[], _T]] = ...,
|
|
277 kw_only: bool = ...,
|
|
278 eq: Optional[_EqOrderType] = ...,
|
|
279 order: Optional[_EqOrderType] = ...,
|
|
280 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
281 ) -> _T: ...
|
|
282
|
|
283 # This form covers type=non-Type: e.g. forward references (str), Any
|
|
284 @overload
|
|
285 def field(
|
|
286 *,
|
|
287 default: Optional[_T] = ...,
|
|
288 validator: Optional[_ValidatorArgType[_T]] = ...,
|
|
289 repr: _ReprArgType = ...,
|
|
290 hash: Optional[bool] = ...,
|
|
291 init: bool = ...,
|
|
292 metadata: Optional[Mapping[Any, Any]] = ...,
|
|
293 converter: Optional[_ConverterType] = ...,
|
|
294 factory: Optional[Callable[[], _T]] = ...,
|
|
295 kw_only: bool = ...,
|
|
296 eq: Optional[_EqOrderType] = ...,
|
|
297 order: Optional[_EqOrderType] = ...,
|
|
298 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
299 ) -> Any: ...
|
|
300 @overload
|
|
301 @__dataclass_transform__(order_default=True, field_descriptors=(attrib, field))
|
|
302 def attrs(
|
|
303 maybe_cls: _C,
|
|
304 these: Optional[Dict[str, Any]] = ...,
|
|
305 repr_ns: Optional[str] = ...,
|
|
306 repr: bool = ...,
|
|
307 cmp: Optional[_EqOrderType] = ...,
|
|
308 hash: Optional[bool] = ...,
|
|
309 init: bool = ...,
|
|
310 slots: bool = ...,
|
|
311 frozen: bool = ...,
|
|
312 weakref_slot: bool = ...,
|
|
313 str: bool = ...,
|
|
314 auto_attribs: bool = ...,
|
|
315 kw_only: bool = ...,
|
|
316 cache_hash: bool = ...,
|
|
317 auto_exc: bool = ...,
|
|
318 eq: Optional[_EqOrderType] = ...,
|
|
319 order: Optional[_EqOrderType] = ...,
|
|
320 auto_detect: bool = ...,
|
|
321 collect_by_mro: bool = ...,
|
|
322 getstate_setstate: Optional[bool] = ...,
|
|
323 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
324 field_transformer: Optional[_FieldTransformer] = ...,
|
|
325 match_args: bool = ...,
|
|
326 ) -> _C: ...
|
|
327 @overload
|
|
328 @__dataclass_transform__(order_default=True, field_descriptors=(attrib, field))
|
|
329 def attrs(
|
|
330 maybe_cls: None = ...,
|
|
331 these: Optional[Dict[str, Any]] = ...,
|
|
332 repr_ns: Optional[str] = ...,
|
|
333 repr: bool = ...,
|
|
334 cmp: Optional[_EqOrderType] = ...,
|
|
335 hash: Optional[bool] = ...,
|
|
336 init: bool = ...,
|
|
337 slots: bool = ...,
|
|
338 frozen: bool = ...,
|
|
339 weakref_slot: bool = ...,
|
|
340 str: bool = ...,
|
|
341 auto_attribs: bool = ...,
|
|
342 kw_only: bool = ...,
|
|
343 cache_hash: bool = ...,
|
|
344 auto_exc: bool = ...,
|
|
345 eq: Optional[_EqOrderType] = ...,
|
|
346 order: Optional[_EqOrderType] = ...,
|
|
347 auto_detect: bool = ...,
|
|
348 collect_by_mro: bool = ...,
|
|
349 getstate_setstate: Optional[bool] = ...,
|
|
350 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
351 field_transformer: Optional[_FieldTransformer] = ...,
|
|
352 match_args: bool = ...,
|
|
353 ) -> Callable[[_C], _C]: ...
|
|
354 @overload
|
|
355 @__dataclass_transform__(field_descriptors=(attrib, field))
|
|
356 def define(
|
|
357 maybe_cls: _C,
|
|
358 *,
|
|
359 these: Optional[Dict[str, Any]] = ...,
|
|
360 repr: bool = ...,
|
|
361 hash: Optional[bool] = ...,
|
|
362 init: bool = ...,
|
|
363 slots: bool = ...,
|
|
364 frozen: bool = ...,
|
|
365 weakref_slot: bool = ...,
|
|
366 str: bool = ...,
|
|
367 auto_attribs: bool = ...,
|
|
368 kw_only: bool = ...,
|
|
369 cache_hash: bool = ...,
|
|
370 auto_exc: bool = ...,
|
|
371 eq: Optional[bool] = ...,
|
|
372 order: Optional[bool] = ...,
|
|
373 auto_detect: bool = ...,
|
|
374 getstate_setstate: Optional[bool] = ...,
|
|
375 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
376 field_transformer: Optional[_FieldTransformer] = ...,
|
|
377 match_args: bool = ...,
|
|
378 ) -> _C: ...
|
|
379 @overload
|
|
380 @__dataclass_transform__(field_descriptors=(attrib, field))
|
|
381 def define(
|
|
382 maybe_cls: None = ...,
|
|
383 *,
|
|
384 these: Optional[Dict[str, Any]] = ...,
|
|
385 repr: bool = ...,
|
|
386 hash: Optional[bool] = ...,
|
|
387 init: bool = ...,
|
|
388 slots: bool = ...,
|
|
389 frozen: bool = ...,
|
|
390 weakref_slot: bool = ...,
|
|
391 str: bool = ...,
|
|
392 auto_attribs: bool = ...,
|
|
393 kw_only: bool = ...,
|
|
394 cache_hash: bool = ...,
|
|
395 auto_exc: bool = ...,
|
|
396 eq: Optional[bool] = ...,
|
|
397 order: Optional[bool] = ...,
|
|
398 auto_detect: bool = ...,
|
|
399 getstate_setstate: Optional[bool] = ...,
|
|
400 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
401 field_transformer: Optional[_FieldTransformer] = ...,
|
|
402 match_args: bool = ...,
|
|
403 ) -> Callable[[_C], _C]: ...
|
|
404
|
|
405 mutable = define
|
|
406 frozen = define # they differ only in their defaults
|
|
407
|
|
408 def fields(cls: Type[AttrsInstance]) -> Any: ...
|
|
409 def fields_dict(cls: Type[AttrsInstance]) -> Dict[str, Attribute[Any]]: ...
|
|
410 def validate(inst: AttrsInstance) -> None: ...
|
|
411 def resolve_types(
|
|
412 cls: _C,
|
|
413 globalns: Optional[Dict[str, Any]] = ...,
|
|
414 localns: Optional[Dict[str, Any]] = ...,
|
|
415 attribs: Optional[List[Attribute[Any]]] = ...,
|
|
416 ) -> _C: ...
|
|
417
|
|
418 # TODO: add support for returning a proper attrs class from the mypy plugin
|
|
419 # we use Any instead of _CountingAttr so that e.g. `make_class('Foo',
|
|
420 # [attr.ib()])` is valid
|
|
421 def make_class(
|
|
422 name: str,
|
|
423 attrs: Union[List[str], Tuple[str, ...], Dict[str, Any]],
|
|
424 bases: Tuple[type, ...] = ...,
|
|
425 repr_ns: Optional[str] = ...,
|
|
426 repr: bool = ...,
|
|
427 cmp: Optional[_EqOrderType] = ...,
|
|
428 hash: Optional[bool] = ...,
|
|
429 init: bool = ...,
|
|
430 slots: bool = ...,
|
|
431 frozen: bool = ...,
|
|
432 weakref_slot: bool = ...,
|
|
433 str: bool = ...,
|
|
434 auto_attribs: bool = ...,
|
|
435 kw_only: bool = ...,
|
|
436 cache_hash: bool = ...,
|
|
437 auto_exc: bool = ...,
|
|
438 eq: Optional[_EqOrderType] = ...,
|
|
439 order: Optional[_EqOrderType] = ...,
|
|
440 collect_by_mro: bool = ...,
|
|
441 on_setattr: Optional[_OnSetAttrArgType] = ...,
|
|
442 field_transformer: Optional[_FieldTransformer] = ...,
|
|
443 ) -> type: ...
|
|
444
|
|
445 # _funcs --
|
|
446
|
|
447 # TODO: add support for returning TypedDict from the mypy plugin
|
|
448 # FIXME: asdict/astuple do not honor their factory args. Waiting on one of
|
|
449 # these:
|
|
450 # https://github.com/python/mypy/issues/4236
|
|
451 # https://github.com/python/typing/issues/253
|
|
452 # XXX: remember to fix attrs.asdict/astuple too!
|
|
453 def asdict(
|
|
454 inst: AttrsInstance,
|
|
455 recurse: bool = ...,
|
|
456 filter: Optional[_FilterType[Any]] = ...,
|
|
457 dict_factory: Type[Mapping[Any, Any]] = ...,
|
|
458 retain_collection_types: bool = ...,
|
|
459 value_serializer: Optional[
|
|
460 Callable[[type, Attribute[Any], Any], Any]
|
|
461 ] = ...,
|
|
462 tuple_keys: Optional[bool] = ...,
|
|
463 ) -> Dict[str, Any]: ...
|
|
464
|
|
465 # TODO: add support for returning NamedTuple from the mypy plugin
|
|
466 def astuple(
|
|
467 inst: AttrsInstance,
|
|
468 recurse: bool = ...,
|
|
469 filter: Optional[_FilterType[Any]] = ...,
|
|
470 tuple_factory: Type[Sequence[Any]] = ...,
|
|
471 retain_collection_types: bool = ...,
|
|
472 ) -> Tuple[Any, ...]: ...
|
|
473 def has(cls: type) -> bool: ...
|
|
474 def assoc(inst: _T, **changes: Any) -> _T: ...
|
|
475 def evolve(inst: _T, **changes: Any) -> _T: ...
|
|
476
|
|
477 # _config --
|
|
478
|
|
479 def set_run_validators(run: bool) -> None: ...
|
|
480 def get_run_validators() -> bool: ...
|
|
481
|
|
482 # aliases --
|
|
483
|
|
484 s = attributes = attrs
|
|
485 ib = attr = attrib
|
|
486 dataclass = attrs # Technically, partial(attrs, auto_attribs=True) ;)
|