Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/attr/_next_gen.py: 69%

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

45 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 

8from functools import partial 

9 

10from . import setters 

11from ._funcs import asdict as _asdict 

12from ._funcs import astuple as _astuple 

13from ._make import ( 

14 _DEFAULT_ON_SETATTR, 

15 NOTHING, 

16 _frozen_setattrs, 

17 attrib, 

18 attrs, 

19) 

20from .exceptions import NotAnAttrsClassError, UnannotatedAttributeError 

21 

22 

23def define( 

24 maybe_cls=None, 

25 *, 

26 these=None, 

27 repr=None, 

28 unsafe_hash=None, 

29 hash=None, 

30 init=None, 

31 slots=True, 

32 frozen=False, 

33 weakref_slot=True, 

34 str=False, 

35 auto_attribs=None, 

36 kw_only=False, 

37 cache_hash=False, 

38 auto_exc=True, 

39 eq=None, 

40 order=False, 

41 auto_detect=True, 

42 getstate_setstate=None, 

43 on_setattr=None, 

44 field_transformer=None, 

45 match_args=True, 

46 force_kw_only=False, 

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 :data:`True` or :data:`False` to *init*, *repr*, *eq*, 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 unsafe_hash (bool | None): 

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

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

158 

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

160 you. 

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

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

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

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

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

166 hashing. 

167 

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

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

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

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

172 carefully. 

173 

174 .. seealso:: 

175 

176 - Our documentation on `hashing`, 

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

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

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

180 details. 

181 

182 hash (bool | None): 

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

184 

185 cache_hash (bool): 

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

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

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

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

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

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

192 object's hash code is undefined. 

193 

194 frozen (bool): 

195 Make instances immutable after initialization. If someone attempts 

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

197 is raised. 

198 

199 .. note:: 

200 

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

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

203 

204 2. True immutability is impossible in Python. 

205 

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

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

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

209 

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

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

212 can circumvent that limitation by using 

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

214 

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

216 

217 kw_only (bool): 

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

219 *init* is False, this parameter is ignored). Attributes that 

220 explicitly set ``kw_only=False`` are not affected; base class 

221 attributes are also not affected. 

222 

223 Also see *force_kw_only*. 

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 force_kw_only (bool): 

244 A back-compat flag for restoring pre-25.4.0 behavior. If True and 

245 ``kw_only=True``, all attributes are made keyword-only, including 

246 base class attributes, and those set to ``kw_only=False`` at the 

247 attribute level. Defaults to False. 

248 

249 See also `issue #980 

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

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 .. versionadded:: 24.3.0 

325 Unless already present, a ``__replace__`` method is automatically 

326 created for `copy.replace` (Python 3.13+ only). 

327 .. versionchanged:: 25.4.0 

328 *kw_only* now only applies to attributes defined in the current class, 

329 and respects attribute-level ``kw_only=False`` settings. 

330 .. versionadded:: 25.4.0 

331 Added *force_kw_only* to go back to the previous *kw_only* behavior. 

332 

333 .. note:: 

334 

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

336 

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

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

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

340 if *frozen* is `False`. 

341 - *slots=True* 

342 

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

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

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

346 

347 - *auto_exc=True* 

348 - *auto_detect=True* 

349 - *order=False* 

350 - *force_kw_only=False* 

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

352 for backwards-compatibility have been removed. 

353 

354 """ 

355 

356 def do_it(cls, auto_attribs): 

357 return attrs( 

358 maybe_cls=cls, 

359 these=these, 

360 repr=repr, 

361 hash=hash, 

362 unsafe_hash=unsafe_hash, 

363 init=init, 

364 slots=slots, 

365 frozen=frozen, 

366 weakref_slot=weakref_slot, 

367 str=str, 

368 auto_attribs=auto_attribs, 

369 kw_only=kw_only, 

370 cache_hash=cache_hash, 

371 auto_exc=auto_exc, 

372 eq=eq, 

373 order=order, 

374 auto_detect=auto_detect, 

375 collect_by_mro=True, 

376 getstate_setstate=getstate_setstate, 

377 on_setattr=on_setattr, 

378 field_transformer=field_transformer, 

379 match_args=match_args, 

380 force_kw_only=force_kw_only, 

381 ) 

382 

383 def wrap(cls): 

384 """ 

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

386 

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

388 """ 

389 nonlocal frozen, on_setattr 

390 

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

392 

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

394 if frozen is False and on_setattr is None: 

395 on_setattr = _DEFAULT_ON_SETATTR 

396 

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

398 # and disable on_setattr. 

399 for base_cls in cls.__bases__: 

400 if base_cls.__setattr__ is _frozen_setattrs: 

401 if had_on_setattr: 

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

403 raise ValueError(msg) 

404 

405 on_setattr = setters.NO_OP 

406 break 

407 

408 if auto_attribs is not None: 

409 return do_it(cls, auto_attribs) 

410 

411 try: 

412 return do_it(cls, True) 

413 except UnannotatedAttributeError: 

414 return do_it(cls, False) 

415 

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

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

418 if maybe_cls is None: 

419 return wrap 

420 

421 return wrap(maybe_cls) 

422 

423 

424mutable = define 

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

426 

427 

428def field( 

429 *, 

430 default=NOTHING, 

431 validator=None, 

432 repr=True, 

433 hash=None, 

434 init=True, 

435 metadata=None, 

436 type=None, 

437 converter=None, 

438 factory=None, 

439 kw_only=None, 

440 eq=None, 

441 order=None, 

442 on_setattr=None, 

443 alias=None, 

444): 

445 """ 

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

447 

448 .. warning:: 

449 

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

451 `attrs.define` (or similar)! 

452 

453 Args: 

454 default: 

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

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

457 excluded using ``init=False``. 

458 

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

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

461 like lists or dicts). 

462 

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

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

465 `TypeError` will be raised. 

466 

467 .. seealso:: `defaults` 

468 

469 factory (~typing.Callable): 

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

471 

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

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

474 after the instance has been initialized. They receive the 

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

476 value. 

477 

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

479 an exception itself. 

480 

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

482 all pass. 

483 

484 Validators can be globally disabled and re-enabled using 

485 `attrs.validators.get_disabled` / `attrs.validators.set_disabled`. 

486 

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

488 below. 

489 

490 .. seealso:: :ref:`validators` 

491 

492 repr (bool | ~typing.Callable): 

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

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

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

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

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

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

499 ``repr()`` (the default). 

500 

501 eq (bool | ~typing.Callable): 

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

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

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

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

506 compared. 

507 

508 .. seealso:: `comparison` 

509 

510 order (bool | ~typing.Callable): 

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

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

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

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

515 

516 .. seealso:: `comparison` 

517 

518 hash (bool | None): 

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

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

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

522 than None is *discouraged*. 

523 

524 .. seealso:: `hashing` 

525 

526 init (bool): 

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

528 

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

530 that case this attributed is unconditionally initialized with the 

531 specified default value or factory. 

532 

533 .. seealso:: `init` 

534 

535 converter (typing.Callable | Converter): 

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

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

538 

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

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

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

542 

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

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

545 validator, if any. 

546 

547 .. seealso:: :ref:`converters` 

548 

549 metadata (dict | None): 

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

551 

552 .. seealso:: `extending-metadata`. 

553 

554 type (type): 

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

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

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

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

559 be stored on ``Attribute.type``. 

560 

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

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

563 checking <types>`. 

564 

565 kw_only (bool | None): 

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

567 *init* is False, this parameter is ignored). If None (default), 

568 mirror the setting from `attrs.define`. 

569 

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

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

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

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

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

575 

576 alias (str | None): 

577 Override this attribute's parameter name in the generated 

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

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

580 

581 .. versionadded:: 20.1.0 

582 .. versionchanged:: 21.1.0 

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

584 .. versionadded:: 22.2.0 *alias* 

585 .. versionadded:: 23.1.0 

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

587 Please note that type checkers ignore this metadata. 

588 .. versionchanged:: 25.4.0 

589 *kw_only* can now be None, and its default is also changed from False to 

590 None. 

591 

592 .. seealso:: 

593 

594 `attr.ib` 

595 """ 

596 return attrib( 

597 default=default, 

598 validator=validator, 

599 repr=repr, 

600 hash=hash, 

601 init=init, 

602 metadata=metadata, 

603 type=type, 

604 converter=converter, 

605 factory=factory, 

606 kw_only=kw_only, 

607 eq=eq, 

608 order=order, 

609 on_setattr=on_setattr, 

610 alias=alias, 

611 ) 

612 

613 

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

615 """ 

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

617 and dict is always used as *dict_factory*. 

618 

619 .. versionadded:: 21.3.0 

620 """ 

621 return _asdict( 

622 inst=inst, 

623 recurse=recurse, 

624 filter=filter, 

625 value_serializer=value_serializer, 

626 retain_collection_types=True, 

627 ) 

628 

629 

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

631 """ 

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

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

634 

635 .. versionadded:: 21.3.0 

636 """ 

637 return _astuple( 

638 inst=inst, recurse=recurse, filter=filter, retain_collection_types=True 

639 ) 

640 

641 

642def inspect(cls): 

643 """ 

644 Inspect the class and return its effective build parameters. 

645 

646 Warning: 

647 This feature is currently **experimental** and is not covered by our 

648 strict backwards-compatibility guarantees. 

649 

650 Args: 

651 cls: The *attrs*-decorated class to inspect. 

652 

653 Returns: 

654 The effective build parameters of the class. 

655 

656 Raises: 

657 NotAnAttrsClassError: If the class is not an *attrs*-decorated class. 

658 

659 .. versionadded:: 25.4.0 

660 """ 

661 try: 

662 return cls.__dict__["__attrs_props__"] 

663 except KeyError: 

664 msg = f"{cls!r} is not an attrs-decorated class." 

665 raise NotAnAttrsClassError(msg) from None