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

38 statements  

1# SPDX-License-Identifier: MIT 

2 

3""" 

4These are keyword-only APIs that call `attr.s` and `attr.ib` with different 

5default values. 

6""" 

7 

8 

9from functools import partial 

10 

11from . import setters 

12from ._funcs import asdict as _asdict 

13from ._funcs import astuple as _astuple 

14from ._make import ( 

15 _DEFAULT_ON_SETATTR, 

16 NOTHING, 

17 _frozen_setattrs, 

18 attrib, 

19 attrs, 

20) 

21from .exceptions import UnannotatedAttributeError 

22 

23 

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 A class decorator that adds :term:`dunder methods` according to 

50 :term:`fields <field>` specified using :doc:`type annotations <types>`, 

51 `field()` calls, or the *these* argument. 

52 

53 Since *attrs* patches or replaces an existing class, you cannot use 

54 `object.__init_subclass__` with *attrs* classes, because it runs too early. 

55 As a replacement, you can define ``__attrs_init_subclass__`` on your class. 

56 It will be called by *attrs* classes that subclass it after they're 

57 created. See also :ref:`init-subclass`. 

58 

59 Args: 

60 slots (bool): 

61 Create a :term:`slotted class <slotted classes>` that's more 

62 memory-efficient. Slotted classes are generally superior to the 

63 default dict classes, but have some gotchas you should know about, 

64 so we encourage you to read the :term:`glossary entry <slotted 

65 classes>`. 

66 

67 auto_detect (bool): 

68 Instead of setting the *init*, *repr*, *eq*, and *hash* arguments 

69 explicitly, assume they are set to True **unless any** of the 

70 involved methods for one of the arguments is implemented in the 

71 *current* class (meaning, it is *not* inherited from some base 

72 class). 

73 

74 So, for example by implementing ``__eq__`` on a class yourself, 

75 *attrs* will deduce ``eq=False`` and will create *neither* 

76 ``__eq__`` *nor* ``__ne__`` (but Python classes come with a 

77 sensible ``__ne__`` by default, so it *should* be enough to only 

78 implement ``__eq__`` in most cases). 

79 

80 Passing True or False` to *init*, *repr*, *eq*, *cmp*, or *hash* 

81 overrides whatever *auto_detect* would determine. 

82 

83 auto_exc (bool): 

84 If the class subclasses `BaseException` (which implicitly includes 

85 any subclass of any exception), the following happens to behave 

86 like a well-behaved Python exception class: 

87 

88 - the values for *eq*, *order*, and *hash* are ignored and the 

89 instances compare and hash by the instance's ids [#]_ , 

90 - all attributes that are either passed into ``__init__`` or have a 

91 default value are additionally available as a tuple in the 

92 ``args`` attribute, 

93 - the value of *str* is ignored leaving ``__str__`` to base 

94 classes. 

95 

96 .. [#] 

97 Note that *attrs* will *not* remove existing implementations of 

98 ``__hash__`` or the equality methods. It just won't add own 

99 ones. 

100 

101 on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]): 

102 A callable that is run whenever the user attempts to set an 

103 attribute (either by assignment like ``i.x = 42`` or by using 

104 `setattr` like ``setattr(i, "x", 42)``). It receives the same 

105 arguments as validators: the instance, the attribute that is being 

106 modified, and the new value. 

107 

108 If no exception is raised, the attribute is set to the return value 

109 of the callable. 

110 

111 If a list of callables is passed, they're automatically wrapped in 

112 an `attrs.setters.pipe`. 

113 

114 If left None, the default behavior is to run converters and 

115 validators whenever an attribute is set. 

116 

117 init (bool): 

118 Create a ``__init__`` method that initializes the *attrs* 

119 attributes. Leading underscores are stripped for the argument name, 

120 unless an alias is set on the attribute. 

121 

122 .. seealso:: 

123 `init` shows advanced ways to customize the generated 

124 ``__init__`` method, including executing code before and after. 

125 

126 repr(bool): 

127 Create a ``__repr__`` method with a human readable representation 

128 of *attrs* attributes. 

129 

130 str (bool): 

131 Create a ``__str__`` method that is identical to ``__repr__``. This 

132 is usually not necessary except for `Exception`\ s. 

133 

134 eq (bool | None): 

135 If True or None (default), add ``__eq__`` and ``__ne__`` methods 

136 that check two instances for equality. 

137 

138 .. seealso:: 

139 `comparison` describes how to customize the comparison behavior 

140 going as far comparing NumPy arrays. 

141 

142 order (bool | None): 

143 If True, add ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` 

144 methods that behave like *eq* above and allow instances to be 

145 ordered. 

146 

147 They compare the instances as if they were tuples of their *attrs* 

148 attributes if and only if the types of both classes are 

149 *identical*. 

150 

151 If `None` mirror value of *eq*. 

152 

153 .. seealso:: `comparison` 

154 

155 cmp (bool | None): 

156 Setting *cmp* is equivalent to setting *eq* and *order* to the same 

157 value. Must not be mixed with *eq* or *order*. 

158 

159 unsafe_hash (bool | None): 

160 If None (default), the ``__hash__`` method is generated according 

161 how *eq* and *frozen* are set. 

162 

163 1. If *both* are True, *attrs* will generate a ``__hash__`` for 

164 you. 

165 2. If *eq* is True and *frozen* is False, ``__hash__`` will be set 

166 to None, marking it unhashable (which it is). 

167 3. If *eq* is False, ``__hash__`` will be left untouched meaning 

168 the ``__hash__`` method of the base class will be used. If the 

169 base class is `object`, this means it will fall back to id-based 

170 hashing. 

171 

172 Although not recommended, you can decide for yourself and force 

173 *attrs* to create one (for example, if the class is immutable even 

174 though you didn't freeze it programmatically) by passing True or 

175 not. Both of these cases are rather special and should be used 

176 carefully. 

177 

178 .. seealso:: 

179 

180 - Our documentation on `hashing`, 

181 - Python's documentation on `object.__hash__`, 

182 - and the `GitHub issue that led to the default \ behavior 

183 <https://github.com/python-attrs/attrs/issues/136>`_ for more 

184 details. 

185 

186 hash (bool | None): 

187 Deprecated alias for *unsafe_hash*. *unsafe_hash* takes precedence. 

188 

189 cache_hash (bool): 

190 Ensure that the object's hash code is computed only once and stored 

191 on the object. If this is set to True, hashing must be either 

192 explicitly or implicitly enabled for this class. If the hash code 

193 is cached, avoid any reassignments of fields involved in hash code 

194 computation or mutations of the objects those fields point to after 

195 object creation. If such changes occur, the behavior of the 

196 object's hash code is undefined. 

197 

198 frozen (bool): 

199 Make instances immutable after initialization. If someone attempts 

200 to modify a frozen instance, `attrs.exceptions.FrozenInstanceError` 

201 is raised. 

202 

203 .. note:: 

204 

205 1. This is achieved by installing a custom ``__setattr__`` 

206 method on your class, so you can't implement your own. 

207 

208 2. True immutability is impossible in Python. 

209 

210 3. This *does* have a minor a runtime performance `impact 

211 <how-frozen>` when initializing new instances. In other 

212 words: ``__init__`` is slightly slower with ``frozen=True``. 

213 

214 4. If a class is frozen, you cannot modify ``self`` in 

215 ``__attrs_post_init__`` or a self-written ``__init__``. You 

216 can circumvent that limitation by using 

217 ``object.__setattr__(self, "attribute_name", value)``. 

218 

219 5. Subclasses of a frozen class are frozen too. 

220 

221 kw_only (bool): 

222 Make all attributes keyword-only in the generated ``__init__`` (if 

223 *init* is False, this parameter is ignored). 

224 

225 weakref_slot (bool): 

226 Make instances weak-referenceable. This has no effect unless 

227 *slots* is True. 

228 

229 field_transformer (~typing.Callable | None): 

230 A function that is called with the original class object and all 

231 fields right before *attrs* finalizes the class. You can use this, 

232 for example, to automatically add converters or validators to 

233 fields based on their types. 

234 

235 .. seealso:: `transform-fields` 

236 

237 match_args (bool): 

238 If True (default), set ``__match_args__`` on the class to support 

239 :pep:`634` (*Structural Pattern Matching*). It is a tuple of all 

240 non-keyword-only ``__init__`` parameter names on Python 3.10 and 

241 later. Ignored on older Python versions. 

242 

243 collect_by_mro (bool): 

244 If True, *attrs* collects attributes from base classes correctly 

245 according to the `method resolution order 

246 <https://docs.python.org/3/howto/mro.html>`_. If False, *attrs* 

247 will mimic the (wrong) behavior of `dataclasses` and :pep:`681`. 

248 

249 See also `issue #428 

250 <https://github.com/python-attrs/attrs/issues/428>`_. 

251 

252 getstate_setstate (bool | None): 

253 .. note:: 

254 

255 This is usually only interesting for slotted classes and you 

256 should probably just set *auto_detect* to True. 

257 

258 If True, ``__getstate__`` and ``__setstate__`` are generated and 

259 attached to the class. This is necessary for slotted classes to be 

260 pickleable. If left None, it's True by default for slotted classes 

261 and False for dict classes. 

262 

263 If *auto_detect* is True, and *getstate_setstate* is left None, and 

264 **either** ``__getstate__`` or ``__setstate__`` is detected 

265 directly on the class (meaning: not inherited), it is set to False 

266 (this is usually what you want). 

267 

268 auto_attribs (bool | None): 

269 If True, look at type annotations to determine which attributes to 

270 use, like `dataclasses`. If False, it will only look for explicit 

271 :func:`field` class attributes, like classic *attrs*. 

272 

273 If left None, it will guess: 

274 

275 1. If any attributes are annotated and no unannotated 

276 `attrs.field`\ s are found, it assumes *auto_attribs=True*. 

277 2. Otherwise it assumes *auto_attribs=False* and tries to collect 

278 `attrs.field`\ s. 

279 

280 If *attrs* decides to look at type annotations, **all** fields 

281 **must** be annotated. If *attrs* encounters a field that is set to 

282 a :func:`field` / `attr.ib` but lacks a type annotation, an 

283 `attrs.exceptions.UnannotatedAttributeError` is raised. Use 

284 ``field_name: typing.Any = field(...)`` if you don't want to set a 

285 type. 

286 

287 .. warning:: 

288 

289 For features that use the attribute name to create decorators 

290 (for example, :ref:`validators <validators>`), you still *must* 

291 assign :func:`field` / `attr.ib` to them. Otherwise Python will 

292 either not find the name or try to use the default value to 

293 call, for example, ``validator`` on it. 

294 

295 Attributes annotated as `typing.ClassVar`, and attributes that are 

296 neither annotated nor set to an `field()` are **ignored**. 

297 

298 these (dict[str, object]): 

299 A dictionary of name to the (private) return value of `field()` 

300 mappings. This is useful to avoid the definition of your attributes 

301 within the class body because you can't (for example, if you want 

302 to add ``__repr__`` methods to Django models) or don't want to. 

303 

304 If *these* is not `None`, *attrs* will *not* search the class body 

305 for attributes and will *not* remove any attributes from it. 

306 

307 The order is deduced from the order of the attributes inside 

308 *these*. 

309 

310 Arguably, this is a rather obscure feature. 

311 

312 .. versionadded:: 20.1.0 

313 .. versionchanged:: 21.3.0 Converters are also run ``on_setattr``. 

314 .. versionadded:: 22.2.0 

315 *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance). 

316 .. versionchanged:: 24.1.0 

317 Instances are not compared as tuples of attributes anymore, but using a 

318 big ``and`` condition. This is faster and has more correct behavior for 

319 uncomparable values like `math.nan`. 

320 .. versionadded:: 24.1.0 

321 If a class has an *inherited* classmethod called 

322 ``__attrs_init_subclass__``, it is executed after the class is created. 

323 .. deprecated:: 24.1.0 *hash* is deprecated in favor of *unsafe_hash*. 

324 

325 .. note:: 

326 

327 The main differences to the classic `attr.s` are: 

328 

329 - Automatically detect whether or not *auto_attribs* should be `True` 

330 (c.f. *auto_attribs* parameter). 

331 - Converters and validators run when attributes are set by default -- 

332 if *frozen* is `False`. 

333 - *slots=True* 

334 

335 Usually, this has only upsides and few visible effects in everyday 

336 programming. But it *can* lead to some surprising behaviors, so 

337 please make sure to read :term:`slotted classes`. 

338 

339 - *auto_exc=True* 

340 - *auto_detect=True* 

341 - *order=False* 

342 - Some options that were only relevant on Python 2 or were kept around 

343 for backwards-compatibility have been removed. 

344 

345 """ 

346 

347 def do_it(cls, auto_attribs): 

348 return attrs( 

349 maybe_cls=cls, 

350 these=these, 

351 repr=repr, 

352 hash=hash, 

353 unsafe_hash=unsafe_hash, 

354 init=init, 

355 slots=slots, 

356 frozen=frozen, 

357 weakref_slot=weakref_slot, 

358 str=str, 

359 auto_attribs=auto_attribs, 

360 kw_only=kw_only, 

361 cache_hash=cache_hash, 

362 auto_exc=auto_exc, 

363 eq=eq, 

364 order=order, 

365 auto_detect=auto_detect, 

366 collect_by_mro=True, 

367 getstate_setstate=getstate_setstate, 

368 on_setattr=on_setattr, 

369 field_transformer=field_transformer, 

370 match_args=match_args, 

371 ) 

372 

373 def wrap(cls): 

374 """ 

375 Making this a wrapper ensures this code runs during class creation. 

376 

377 We also ensure that frozen-ness of classes is inherited. 

378 """ 

379 nonlocal frozen, on_setattr 

380 

381 had_on_setattr = on_setattr not in (None, setters.NO_OP) 

382 

383 # By default, mutable classes convert & validate on setattr. 

384 if frozen is False and on_setattr is None: 

385 on_setattr = _DEFAULT_ON_SETATTR 

386 

387 # However, if we subclass a frozen class, we inherit the immutability 

388 # and disable on_setattr. 

389 for base_cls in cls.__bases__: 

390 if base_cls.__setattr__ is _frozen_setattrs: 

391 if had_on_setattr: 

392 msg = "Frozen classes can't use on_setattr (frozen-ness was inherited)." 

393 raise ValueError(msg) 

394 

395 on_setattr = setters.NO_OP 

396 break 

397 

398 if auto_attribs is not None: 

399 return do_it(cls, auto_attribs) 

400 

401 try: 

402 return do_it(cls, True) 

403 except UnannotatedAttributeError: 

404 return do_it(cls, False) 

405 

406 # maybe_cls's type depends on the usage of the decorator. It's a class 

407 # if it's used as `@attrs` but `None` if used as `@attrs()`. 

408 if maybe_cls is None: 

409 return wrap 

410 

411 return wrap(maybe_cls) 

412 

413 

414mutable = define 

415frozen = partial(define, frozen=True, on_setattr=None) 

416 

417 

418def field( 

419 *, 

420 default=NOTHING, 

421 validator=None, 

422 repr=True, 

423 hash=None, 

424 init=True, 

425 metadata=None, 

426 type=None, 

427 converter=None, 

428 factory=None, 

429 kw_only=False, 

430 eq=None, 

431 order=None, 

432 on_setattr=None, 

433 alias=None, 

434): 

435 """ 

436 Create a new :term:`field` / :term:`attribute` on a class. 

437 

438 .. warning:: 

439 

440 Does **nothing** unless the class is also decorated with 

441 `attrs.define` (or similar)! 

442 

443 Args: 

444 default: 

445 A value that is used if an *attrs*-generated ``__init__`` is used 

446 and no value is passed while instantiating or the attribute is 

447 excluded using ``init=False``. 

448 

449 If the value is an instance of `attrs.Factory`, its callable will 

450 be used to construct a new value (useful for mutable data types 

451 like lists or dicts). 

452 

453 If a default is not set (or set manually to `attrs.NOTHING`), a 

454 value *must* be supplied when instantiating; otherwise a 

455 `TypeError` will be raised. 

456 

457 .. seealso:: `defaults` 

458 

459 factory (~typing.Callable): 

460 Syntactic sugar for ``default=attr.Factory(factory)``. 

461 

462 validator (~typing.Callable | list[~typing.Callable]): 

463 Callable that is called by *attrs*-generated ``__init__`` methods 

464 after the instance has been initialized. They receive the 

465 initialized instance, the :func:`~attrs.Attribute`, and the passed 

466 value. 

467 

468 The return value is *not* inspected so the validator has to throw 

469 an exception itself. 

470 

471 If a `list` is passed, its items are treated as validators and must 

472 all pass. 

473 

474 Validators can be globally disabled and re-enabled using 

475 `attrs.validators.get_disabled` / `attrs.validators.set_disabled`. 

476 

477 The validator can also be set using decorator notation as shown 

478 below. 

479 

480 .. seealso:: :ref:`validators` 

481 

482 repr (bool | ~typing.Callable): 

483 Include this attribute in the generated ``__repr__`` method. If 

484 True, include the attribute; if False, omit it. By default, the 

485 built-in ``repr()`` function is used. To override how the attribute 

486 value is formatted, pass a ``callable`` that takes a single value 

487 and returns a string. Note that the resulting string is used as-is, 

488 which means it will be used directly *instead* of calling 

489 ``repr()`` (the default). 

490 

491 eq (bool | ~typing.Callable): 

492 If True (default), include this attribute in the generated 

493 ``__eq__`` and ``__ne__`` methods that check two instances for 

494 equality. To override how the attribute value is compared, pass a 

495 callable that takes a single value and returns the value to be 

496 compared. 

497 

498 .. seealso:: `comparison` 

499 

500 order (bool | ~typing.Callable): 

501 If True (default), include this attributes in the generated 

502 ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. To 

503 override how the attribute value is ordered, pass a callable that 

504 takes a single value and returns the value to be ordered. 

505 

506 .. seealso:: `comparison` 

507 

508 cmp(bool | ~typing.Callable): 

509 Setting *cmp* is equivalent to setting *eq* and *order* to the same 

510 value. Must not be mixed with *eq* or *order*. 

511 

512 .. seealso:: `comparison` 

513 

514 hash (bool | None): 

515 Include this attribute in the generated ``__hash__`` method. If 

516 None (default), mirror *eq*'s value. This is the correct behavior 

517 according the Python spec. Setting this value to anything else 

518 than None is *discouraged*. 

519 

520 .. seealso:: `hashing` 

521 

522 init (bool): 

523 Include this attribute in the generated ``__init__`` method. 

524 

525 It is possible to set this to False and set a default value. In 

526 that case this attributed is unconditionally initialized with the 

527 specified default value or factory. 

528 

529 .. seealso:: `init` 

530 

531 converter (typing.Callable | Converter): 

532 A callable that is called by *attrs*-generated ``__init__`` methods 

533 to convert attribute's value to the desired format. 

534 

535 If a vanilla callable is passed, it is given the passed-in value as 

536 the only positional argument. It is possible to receive additional 

537 arguments by wrapping the callable in a `Converter`. 

538 

539 Either way, the returned value will be used as the new value of the 

540 attribute. The value is converted before being passed to the 

541 validator, if any. 

542 

543 .. seealso:: :ref:`converters` 

544 

545 metadata (dict | None): 

546 An arbitrary mapping, to be used by third-party code. 

547 

548 .. seealso:: `extending-metadata`. 

549 

550 type (type): 

551 The type of the attribute. Nowadays, the preferred method to 

552 specify the type is using a variable annotation (see :pep:`526`). 

553 This argument is provided for backwards-compatibility and for usage 

554 with `make_class`. Regardless of the approach used, the type will 

555 be stored on ``Attribute.type``. 

556 

557 Please note that *attrs* doesn't do anything with this metadata by 

558 itself. You can use it as part of your own code or for `static type 

559 checking <types>`. 

560 

561 kw_only (bool): 

562 Make this attribute keyword-only in the generated ``__init__`` (if 

563 ``init`` is False, this parameter is ignored). 

564 

565 on_setattr (~typing.Callable | list[~typing.Callable] | None | ~typing.Literal[attrs.setters.NO_OP]): 

566 Allows to overwrite the *on_setattr* setting from `attr.s`. If left 

567 None, the *on_setattr* value from `attr.s` is used. Set to 

568 `attrs.setters.NO_OP` to run **no** `setattr` hooks for this 

569 attribute -- regardless of the setting in `define()`. 

570 

571 alias (str | None): 

572 Override this attribute's parameter name in the generated 

573 ``__init__`` method. If left None, default to ``name`` stripped 

574 of leading underscores. See `private-attributes`. 

575 

576 .. versionadded:: 20.1.0 

577 .. versionchanged:: 21.1.0 

578 *eq*, *order*, and *cmp* also accept a custom callable 

579 .. versionadded:: 22.2.0 *alias* 

580 .. versionadded:: 23.1.0 

581 The *type* parameter has been re-added; mostly for `attrs.make_class`. 

582 Please note that type checkers ignore this metadata. 

583 

584 .. seealso:: 

585 

586 `attr.ib` 

587 """ 

588 return attrib( 

589 default=default, 

590 validator=validator, 

591 repr=repr, 

592 hash=hash, 

593 init=init, 

594 metadata=metadata, 

595 type=type, 

596 converter=converter, 

597 factory=factory, 

598 kw_only=kw_only, 

599 eq=eq, 

600 order=order, 

601 on_setattr=on_setattr, 

602 alias=alias, 

603 ) 

604 

605 

606def asdict(inst, *, recurse=True, filter=None, value_serializer=None): 

607 """ 

608 Same as `attr.asdict`, except that collections types are always retained 

609 and dict is always used as *dict_factory*. 

610 

611 .. versionadded:: 21.3.0 

612 """ 

613 return _asdict( 

614 inst=inst, 

615 recurse=recurse, 

616 filter=filter, 

617 value_serializer=value_serializer, 

618 retain_collection_types=True, 

619 ) 

620 

621 

622def astuple(inst, *, recurse=True, filter=None): 

623 """ 

624 Same as `attr.astuple`, except that collections types are always retained 

625 and `tuple` is always used as the *tuple_factory*. 

626 

627 .. versionadded:: 21.3.0 

628 """ 

629 return _astuple( 

630 inst=inst, recurse=recurse, filter=filter, retain_collection_types=True 

631 )