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

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

39 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 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): 

47 r""" 

48 A class decorator that adds :term:`dunder methods` according to 

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

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

51 

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

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

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

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

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

57 

58 Args: 

59 slots (bool): 

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

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

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

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

64 classes>`. 

65 

66 auto_detect (bool): 

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

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

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

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

71 class). 

72 

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

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

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

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

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

78 

79 Passing :data:`True` or :data:`False` to *init*, *repr*, *eq*, or *hash* 

80 overrides whatever *auto_detect* would determine. 

81 

82 auto_exc (bool): 

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

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

85 like a well-behaved Python exception class: 

86 

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

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

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

90 default value are additionally available as a tuple in the 

91 ``args`` attribute, 

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

93 classes. 

94 

95 .. [#] 

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

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

98 ones. 

99 

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

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

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

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

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

105 modified, and the new value. 

106 

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

108 of the callable. 

109 

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

111 an `attrs.setters.pipe`. 

112 

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

114 validators whenever an attribute is set. 

115 

116 init (bool): 

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

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

119 unless an alias is set on the attribute. 

120 

121 .. seealso:: 

122 `init` shows advanced ways to customize the generated 

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

124 

125 repr(bool): 

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

127 of *attrs* attributes. 

128 

129 str (bool): 

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

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

132 

133 eq (bool | None): 

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

135 that check two instances for equality. 

136 

137 .. seealso:: 

138 `comparison` describes how to customize the comparison behavior 

139 going as far comparing NumPy arrays. 

140 

141 order (bool | None): 

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

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

144 ordered. 

145 

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

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

148 *identical*. 

149 

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

151 

152 .. seealso:: `comparison` 

153 

154 unsafe_hash (bool | None): 

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

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

157 

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

159 you. 

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

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

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

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

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

165 hashing. 

166 

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

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

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

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

171 carefully. 

172 

173 .. seealso:: 

174 

175 - Our documentation on `hashing`, 

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

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

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

179 details. 

180 

181 hash (bool | None): 

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

183 

184 cache_hash (bool): 

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

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

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

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

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

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

191 object's hash code is undefined. 

192 

193 frozen (bool): 

194 Make instances immutable after initialization. If someone attempts 

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

196 is raised. 

197 

198 .. note:: 

199 

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

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

202 

203 2. True immutability is impossible in Python. 

204 

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

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

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

208 

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

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

211 can circumvent that limitation by using 

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

213 

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

215 

216 kw_only (bool): 

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

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

219 

220 weakref_slot (bool): 

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

222 *slots* is True. 

223 

224 field_transformer (~typing.Callable | None): 

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

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

227 for example, to automatically add converters or validators to 

228 fields based on their types. 

229 

230 .. seealso:: `transform-fields` 

231 

232 match_args (bool): 

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

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

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

236 later. Ignored on older Python versions. 

237 

238 collect_by_mro (bool): 

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

240 according to the `method resolution order 

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

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

243 

244 See also `issue #428 

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

246 

247 getstate_setstate (bool | None): 

248 .. note:: 

249 

250 This is usually only interesting for slotted classes and you 

251 should probably just set *auto_detect* to True. 

252 

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

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

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

256 and False for dict classes. 

257 

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

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

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

261 (this is usually what you want). 

262 

263 auto_attribs (bool | None): 

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

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

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

267 

268 If left None, it will guess: 

269 

270 1. If any attributes are annotated and no unannotated 

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

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

273 `attrs.field`\ s. 

274 

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

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

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

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

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

280 type. 

281 

282 .. warning:: 

283 

284 For features that use the attribute name to create decorators 

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

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

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

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

289 

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

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

292 

293 these (dict[str, object]): 

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

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

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

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

298 

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

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

301 

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

303 *these*. 

304 

305 Arguably, this is a rather obscure feature. 

306 

307 .. versionadded:: 20.1.0 

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

309 .. versionadded:: 22.2.0 

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

311 .. versionchanged:: 24.1.0 

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

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

314 uncomparable values like `math.nan`. 

315 .. versionadded:: 24.1.0 

316 If a class has an *inherited* classmethod called 

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

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

319 .. versionadded:: 24.3.0 

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

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

322 

323 .. note:: 

324 

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

326 

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

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

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

330 if *frozen* is `False`. 

331 - *slots=True* 

332 

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

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

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

336 

337 - *auto_exc=True* 

338 - *auto_detect=True* 

339 - *order=False* 

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

341 for backwards-compatibility have been removed. 

342 

343 """ 

344 

345 def do_it(cls, auto_attribs): 

346 return attrs( 

347 maybe_cls=cls, 

348 these=these, 

349 repr=repr, 

350 hash=hash, 

351 unsafe_hash=unsafe_hash, 

352 init=init, 

353 slots=slots, 

354 frozen=frozen, 

355 weakref_slot=weakref_slot, 

356 str=str, 

357 auto_attribs=auto_attribs, 

358 kw_only=kw_only, 

359 cache_hash=cache_hash, 

360 auto_exc=auto_exc, 

361 eq=eq, 

362 order=order, 

363 auto_detect=auto_detect, 

364 collect_by_mro=True, 

365 getstate_setstate=getstate_setstate, 

366 on_setattr=on_setattr, 

367 field_transformer=field_transformer, 

368 match_args=match_args, 

369 ) 

370 

371 def wrap(cls): 

372 """ 

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

374 

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

376 """ 

377 nonlocal frozen, on_setattr 

378 

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

380 

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

382 if frozen is False and on_setattr is None: 

383 on_setattr = _DEFAULT_ON_SETATTR 

384 

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

386 # and disable on_setattr. 

387 for base_cls in cls.__bases__: 

388 if base_cls.__setattr__ is _frozen_setattrs: 

389 if had_on_setattr: 

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

391 raise ValueError(msg) 

392 

393 on_setattr = setters.NO_OP 

394 break 

395 

396 if auto_attribs is not None: 

397 return do_it(cls, auto_attribs) 

398 

399 try: 

400 return do_it(cls, True) 

401 except UnannotatedAttributeError: 

402 return do_it(cls, False) 

403 

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

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

406 if maybe_cls is None: 

407 return wrap 

408 

409 return wrap(maybe_cls) 

410 

411 

412mutable = define 

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

414 

415 

416def field( 

417 *, 

418 default=NOTHING, 

419 validator=None, 

420 repr=True, 

421 hash=None, 

422 init=True, 

423 metadata=None, 

424 type=None, 

425 converter=None, 

426 factory=None, 

427 kw_only=False, 

428 eq=None, 

429 order=None, 

430 on_setattr=None, 

431 alias=None, 

432): 

433 """ 

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

435 

436 .. warning:: 

437 

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

439 `attrs.define` (or similar)! 

440 

441 Args: 

442 default: 

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

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

445 excluded using ``init=False``. 

446 

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

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

449 like lists or dicts). 

450 

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

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

453 `TypeError` will be raised. 

454 

455 .. seealso:: `defaults` 

456 

457 factory (~typing.Callable): 

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

459 

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

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

462 after the instance has been initialized. They receive the 

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

464 value. 

465 

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

467 an exception itself. 

468 

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

470 all pass. 

471 

472 Validators can be globally disabled and re-enabled using 

473 `attrs.validators.get_disabled` / `attrs.validators.set_disabled`. 

474 

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

476 below. 

477 

478 .. seealso:: :ref:`validators` 

479 

480 repr (bool | ~typing.Callable): 

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

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

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

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

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

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

487 ``repr()`` (the default). 

488 

489 eq (bool | ~typing.Callable): 

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

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

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

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

494 compared. 

495 

496 .. seealso:: `comparison` 

497 

498 order (bool | ~typing.Callable): 

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

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

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

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

503 

504 .. seealso:: `comparison` 

505 

506 hash (bool | None): 

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

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

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

510 than None is *discouraged*. 

511 

512 .. seealso:: `hashing` 

513 

514 init (bool): 

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

516 

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

518 that case this attributed is unconditionally initialized with the 

519 specified default value or factory. 

520 

521 .. seealso:: `init` 

522 

523 converter (typing.Callable | Converter): 

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

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

526 

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

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

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

530 

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

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

533 validator, if any. 

534 

535 .. seealso:: :ref:`converters` 

536 

537 metadata (dict | None): 

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

539 

540 .. seealso:: `extending-metadata`. 

541 

542 type (type): 

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

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

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

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

547 be stored on ``Attribute.type``. 

548 

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

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

551 checking <types>`. 

552 

553 kw_only (bool): 

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

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

556 

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

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

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

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

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

562 

563 alias (str | None): 

564 Override this attribute's parameter name in the generated 

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

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

567 

568 .. versionadded:: 20.1.0 

569 .. versionchanged:: 21.1.0 

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

571 .. versionadded:: 22.2.0 *alias* 

572 .. versionadded:: 23.1.0 

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

574 Please note that type checkers ignore this metadata. 

575 

576 .. seealso:: 

577 

578 `attr.ib` 

579 """ 

580 return attrib( 

581 default=default, 

582 validator=validator, 

583 repr=repr, 

584 hash=hash, 

585 init=init, 

586 metadata=metadata, 

587 type=type, 

588 converter=converter, 

589 factory=factory, 

590 kw_only=kw_only, 

591 eq=eq, 

592 order=order, 

593 on_setattr=on_setattr, 

594 alias=alias, 

595 ) 

596 

597 

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

599 """ 

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

601 and dict is always used as *dict_factory*. 

602 

603 .. versionadded:: 21.3.0 

604 """ 

605 return _asdict( 

606 inst=inst, 

607 recurse=recurse, 

608 filter=filter, 

609 value_serializer=value_serializer, 

610 retain_collection_types=True, 

611 ) 

612 

613 

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

615 """ 

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

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

618 

619 .. versionadded:: 21.3.0 

620 """ 

621 return _astuple( 

622 inst=inst, recurse=recurse, filter=filter, retain_collection_types=True 

623 )