ant-ray-nightly 3.0.0.dev20251006__cp311-cp311-macosx_14_0_arm64.whl → 3.0.0.dev20251015__cp311-cp311-macosx_14_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ant-ray-nightly might be problematic. Click here for more details.
- {ant_ray_nightly-3.0.0.dev20251006.dist-info → ant_ray_nightly-3.0.0.dev20251015.dist-info}/METADATA +82 -82
- {ant_ray_nightly-3.0.0.dev20251006.dist-info → ant_ray_nightly-3.0.0.dev20251015.dist-info}/RECORD +101 -101
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/.hash/_cparser.pxd.hash +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/.hash/_find_header.pxd.hash +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/.hash/_http_parser.pyx.hash +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/.hash/_http_writer.pyx.hash +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/.hash/hdrs.py.hash +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/__init__.py +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_cookie_helpers.py +2 -6
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_http_parser.cpython-311-darwin.so +0 -0
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_http_parser.pyx +1 -3
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_http_writer.cpython-311-darwin.so +0 -0
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_http_writer.pyx +9 -7
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_websocket/.hash/mask.pxd.hash +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_websocket/.hash/mask.pyx.hash +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_websocket/.hash/reader_c.pxd.hash +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_websocket/mask.cpython-311-darwin.so +0 -0
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_websocket/reader_c.cpython-311-darwin.so +0 -0
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/abc.py +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/client_reqrep.py +13 -4
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/compression_utils.py +31 -0
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/formdata.py +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/http_parser.py +18 -3
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/multipart.py +4 -0
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/streams.py +8 -0
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/web_fileresponse.py +4 -4
- ray/_private/runtime_env/agent/thirdparty_files/aiohttp/web_urldispatcher.py +3 -1
- ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/METADATA +24 -12
- ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/RECORD +33 -33
- ray/_private/runtime_env/agent/thirdparty_files/attr/__init__.pyi +4 -4
- ray/_private/runtime_env/agent/thirdparty_files/attr/_compat.py +8 -3
- ray/_private/runtime_env/agent/thirdparty_files/attr/_funcs.py +45 -16
- ray/_private/runtime_env/agent/thirdparty_files/attr/_make.py +334 -95
- ray/_private/runtime_env/agent/thirdparty_files/attr/_next_gen.py +58 -7
- ray/_private/runtime_env/agent/thirdparty_files/attr/_version_info.py +3 -0
- ray/_private/runtime_env/agent/thirdparty_files/attr/validators.py +51 -13
- ray/_private/runtime_env/agent/thirdparty_files/attr/validators.pyi +59 -5
- ray/_private/runtime_env/agent/thirdparty_files/attrs/__init__.py +4 -1
- ray/_private/runtime_env/agent/thirdparty_files/attrs/__init__.pyi +58 -7
- ray/_private/runtime_env/agent/thirdparty_files/{attrs-25.3.0.dist-info → attrs-25.4.0.dist-info}/METADATA +63 -60
- ray/_private/runtime_env/agent/thirdparty_files/{attrs-25.3.0.dist-info → attrs-25.4.0.dist-info}/RECORD +15 -15
- ray/_private/runtime_env/agent/thirdparty_files/frozenlist/__init__.py +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/frozenlist/_frozenlist.cpython-311-darwin.so +0 -0
- ray/_private/runtime_env/agent/thirdparty_files/{frozenlist-1.7.0.dist-info → frozenlist-1.8.0.dist-info}/METADATA +47 -1
- ray/_private/runtime_env/agent/thirdparty_files/frozenlist-1.8.0.dist-info/RECORD +12 -0
- ray/_private/runtime_env/agent/thirdparty_files/idna/codec.py +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/idna/core.py +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/idna/idnadata.py +72 -6
- ray/_private/runtime_env/agent/thirdparty_files/idna/package_data.py +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/idna/uts46data.py +891 -731
- ray/_private/runtime_env/agent/thirdparty_files/{idna-3.10.dist-info → idna-3.11.dist-info}/METADATA +37 -78
- ray/_private/runtime_env/agent/thirdparty_files/idna-3.11.dist-info/RECORD +22 -0
- ray/_private/runtime_env/agent/thirdparty_files/{idna-3.10.dist-info → idna-3.11.dist-info}/WHEEL +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/{idna-3.10.dist-info → idna-3.11.dist-info/licenses}/LICENSE.md +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/multidict/__init__.py +9 -8
- ray/_private/runtime_env/agent/thirdparty_files/multidict/_multidict.cpython-311-darwin.so +0 -0
- ray/_private/runtime_env/agent/thirdparty_files/{multidict-6.6.4.dist-info → multidict-6.7.0.dist-info}/METADATA +2 -1
- ray/_private/runtime_env/agent/thirdparty_files/{multidict-6.6.4.dist-info → multidict-6.7.0.dist-info}/RECORD +8 -8
- ray/_private/runtime_env/agent/thirdparty_files/propcache/__init__.py +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/propcache/_helpers_c.cpython-311-darwin.so +0 -0
- ray/_private/runtime_env/agent/thirdparty_files/propcache/_helpers_c.pyx +4 -5
- ray/_private/runtime_env/agent/thirdparty_files/{propcache-0.4.0.dist-info → propcache-0.4.1.dist-info}/METADATA +31 -1
- ray/_private/runtime_env/agent/thirdparty_files/propcache-0.4.1.dist-info/RECORD +18 -0
- ray/_private/runtime_env/agent/thirdparty_files/yarl/__init__.py +1 -1
- ray/_private/runtime_env/agent/thirdparty_files/yarl/_quoting_c.cpython-311-darwin.so +0 -0
- ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/METADATA +20 -1
- ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/RECORD +9 -9
- ray/core/src/ray/gcs/gcs_server +0 -0
- ray/thirdparty_files/setproctitle-1.2.2.dist-info/RECORD +1 -1
- ray/thirdparty_files/setproctitle.cpython-311-darwin.so +0 -0
- ray/_private/runtime_env/agent/thirdparty_files/frozenlist-1.7.0.dist-info/RECORD +0 -12
- ray/_private/runtime_env/agent/thirdparty_files/idna-3.10.dist-info/RECORD +0 -22
- ray/_private/runtime_env/agent/thirdparty_files/propcache-0.4.0.dist-info/RECORD +0 -18
- {ant_ray_nightly-3.0.0.dev20251006.dist-info → ant_ray_nightly-3.0.0.dev20251015.dist-info}/WHEEL +0 -0
- {ant_ray_nightly-3.0.0.dev20251006.dist-info → ant_ray_nightly-3.0.0.dev20251015.dist-info}/entry_points.txt +0 -0
- {ant_ray_nightly-3.0.0.dev20251006.dist-info → ant_ray_nightly-3.0.0.dev20251015.dist-info}/top_level.txt +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/INSTALLER +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/REQUESTED +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/WHEEL +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/licenses/LICENSE.txt +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/licenses/vendor/llhttp/LICENSE +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/top_level.txt +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{attrs-25.3.0.dist-info → attrs-25.4.0.dist-info}/INSTALLER +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{attrs-25.3.0.dist-info → attrs-25.4.0.dist-info}/WHEEL +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{attrs-25.3.0.dist-info → attrs-25.4.0.dist-info}/licenses/LICENSE +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{frozenlist-1.7.0.dist-info → frozenlist-1.8.0.dist-info}/INSTALLER +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{frozenlist-1.7.0.dist-info → frozenlist-1.8.0.dist-info}/WHEEL +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{frozenlist-1.7.0.dist-info → frozenlist-1.8.0.dist-info}/licenses/LICENSE +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{frozenlist-1.7.0.dist-info → frozenlist-1.8.0.dist-info}/top_level.txt +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{idna-3.10.dist-info → idna-3.11.dist-info}/INSTALLER +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{multidict-6.6.4.dist-info → multidict-6.7.0.dist-info}/INSTALLER +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{multidict-6.6.4.dist-info → multidict-6.7.0.dist-info}/WHEEL +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{multidict-6.6.4.dist-info → multidict-6.7.0.dist-info}/licenses/LICENSE +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{multidict-6.6.4.dist-info → multidict-6.7.0.dist-info}/top_level.txt +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{propcache-0.4.0.dist-info → propcache-0.4.1.dist-info}/INSTALLER +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{propcache-0.4.0.dist-info → propcache-0.4.1.dist-info}/WHEEL +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{propcache-0.4.0.dist-info → propcache-0.4.1.dist-info}/licenses/LICENSE +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{propcache-0.4.0.dist-info → propcache-0.4.1.dist-info}/licenses/NOTICE +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{propcache-0.4.0.dist-info → propcache-0.4.1.dist-info}/top_level.txt +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/INSTALLER +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/WHEEL +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/licenses/LICENSE +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/licenses/NOTICE +0 -0
- /ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/top_level.txt +0 -0
|
@@ -12,6 +12,7 @@ import linecache
|
|
|
12
12
|
import sys
|
|
13
13
|
import types
|
|
14
14
|
import unicodedata
|
|
15
|
+
import weakref
|
|
15
16
|
|
|
16
17
|
from collections.abc import Callable, Mapping
|
|
17
18
|
from functools import cached_property
|
|
@@ -113,7 +114,7 @@ def attrib(
|
|
|
113
114
|
type=None,
|
|
114
115
|
converter=None,
|
|
115
116
|
factory=None,
|
|
116
|
-
kw_only=
|
|
117
|
+
kw_only=None,
|
|
117
118
|
eq=None,
|
|
118
119
|
order=None,
|
|
119
120
|
on_setattr=None,
|
|
@@ -156,6 +157,9 @@ def attrib(
|
|
|
156
157
|
*eq*, *order*, and *cmp* also accept a custom callable
|
|
157
158
|
.. versionchanged:: 21.1.0 *cmp* undeprecated
|
|
158
159
|
.. versionadded:: 22.2.0 *alias*
|
|
160
|
+
.. versionchanged:: 25.4.0
|
|
161
|
+
*kw_only* can now be None, and its default is also changed from False to
|
|
162
|
+
None.
|
|
159
163
|
"""
|
|
160
164
|
eq, eq_key, order, order_key = _determine_attrib_eq_order(
|
|
161
165
|
cmp, eq, order, True
|
|
@@ -373,7 +377,12 @@ def _collect_base_attrs_broken(cls, taken_attr_names):
|
|
|
373
377
|
|
|
374
378
|
|
|
375
379
|
def _transform_attrs(
|
|
376
|
-
cls,
|
|
380
|
+
cls,
|
|
381
|
+
these,
|
|
382
|
+
auto_attribs,
|
|
383
|
+
kw_only,
|
|
384
|
+
collect_by_mro,
|
|
385
|
+
field_transformer,
|
|
377
386
|
) -> _Attributes:
|
|
378
387
|
"""
|
|
379
388
|
Transform all `_CountingAttr`s on a class into `Attribute`s.
|
|
@@ -428,8 +437,15 @@ def _transform_attrs(
|
|
|
428
437
|
)
|
|
429
438
|
|
|
430
439
|
fca = Attribute.from_counting_attr
|
|
440
|
+
no = ClassProps.KeywordOnly.NO
|
|
431
441
|
own_attrs = [
|
|
432
|
-
fca(
|
|
442
|
+
fca(
|
|
443
|
+
attr_name,
|
|
444
|
+
ca,
|
|
445
|
+
kw_only is not no,
|
|
446
|
+
anns.get(attr_name),
|
|
447
|
+
)
|
|
448
|
+
for attr_name, ca in ca_list
|
|
433
449
|
]
|
|
434
450
|
|
|
435
451
|
if collect_by_mro:
|
|
@@ -441,7 +457,7 @@ def _transform_attrs(
|
|
|
441
457
|
cls, {a.name for a in own_attrs}
|
|
442
458
|
)
|
|
443
459
|
|
|
444
|
-
if kw_only:
|
|
460
|
+
if kw_only is ClassProps.KeywordOnly.FORCE:
|
|
445
461
|
own_attrs = [a.evolve(kw_only=True) for a in own_attrs]
|
|
446
462
|
base_attrs = [a.evolve(kw_only=True) for a in base_attrs]
|
|
447
463
|
|
|
@@ -651,38 +667,31 @@ class _ClassBuilder:
|
|
|
651
667
|
self,
|
|
652
668
|
cls: type,
|
|
653
669
|
these,
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
getstate_setstate,
|
|
658
|
-
auto_attribs,
|
|
659
|
-
kw_only,
|
|
660
|
-
cache_hash,
|
|
661
|
-
is_exc,
|
|
662
|
-
collect_by_mro,
|
|
663
|
-
on_setattr,
|
|
664
|
-
has_custom_setattr,
|
|
665
|
-
field_transformer,
|
|
670
|
+
auto_attribs: bool,
|
|
671
|
+
props: ClassProps,
|
|
672
|
+
has_custom_setattr: bool,
|
|
666
673
|
):
|
|
667
674
|
attrs, base_attrs, base_map = _transform_attrs(
|
|
668
675
|
cls,
|
|
669
676
|
these,
|
|
670
677
|
auto_attribs,
|
|
671
|
-
kw_only,
|
|
672
|
-
|
|
673
|
-
field_transformer,
|
|
678
|
+
props.kw_only,
|
|
679
|
+
props.collected_fields_by_mro,
|
|
680
|
+
props.field_transformer,
|
|
674
681
|
)
|
|
675
682
|
|
|
676
683
|
self._cls = cls
|
|
677
|
-
self._cls_dict = dict(cls.__dict__) if
|
|
684
|
+
self._cls_dict = dict(cls.__dict__) if props.is_slotted else {}
|
|
678
685
|
self._attrs = attrs
|
|
679
686
|
self._base_names = {a.name for a in base_attrs}
|
|
680
687
|
self._base_attr_map = base_map
|
|
681
688
|
self._attr_names = tuple(a.name for a in attrs)
|
|
682
|
-
self._slots =
|
|
683
|
-
self._frozen =
|
|
684
|
-
self._weakref_slot =
|
|
685
|
-
self._cache_hash =
|
|
689
|
+
self._slots = props.is_slotted
|
|
690
|
+
self._frozen = props.is_frozen
|
|
691
|
+
self._weakref_slot = props.has_weakref_slot
|
|
692
|
+
self._cache_hash = (
|
|
693
|
+
props.hashability is ClassProps.Hashability.HASHABLE_CACHED
|
|
694
|
+
)
|
|
686
695
|
self._has_pre_init = bool(getattr(cls, "__attrs_pre_init__", False))
|
|
687
696
|
self._pre_init_has_args = False
|
|
688
697
|
if self._has_pre_init:
|
|
@@ -693,20 +702,21 @@ class _ClassBuilder:
|
|
|
693
702
|
self._pre_init_has_args = len(pre_init_signature.parameters) > 1
|
|
694
703
|
self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False))
|
|
695
704
|
self._delete_attribs = not bool(these)
|
|
696
|
-
self._is_exc =
|
|
697
|
-
self._on_setattr =
|
|
705
|
+
self._is_exc = props.is_exception
|
|
706
|
+
self._on_setattr = props.on_setattr_hook
|
|
698
707
|
|
|
699
708
|
self._has_custom_setattr = has_custom_setattr
|
|
700
709
|
self._wrote_own_setattr = False
|
|
701
710
|
|
|
702
711
|
self._cls_dict["__attrs_attrs__"] = self._attrs
|
|
712
|
+
self._cls_dict["__attrs_props__"] = props
|
|
703
713
|
|
|
704
|
-
if
|
|
714
|
+
if props.is_frozen:
|
|
705
715
|
self._cls_dict["__setattr__"] = _frozen_setattrs
|
|
706
716
|
self._cls_dict["__delattr__"] = _frozen_delattrs
|
|
707
717
|
|
|
708
718
|
self._wrote_own_setattr = True
|
|
709
|
-
elif
|
|
719
|
+
elif self._on_setattr in (
|
|
710
720
|
_DEFAULT_ON_SETATTR,
|
|
711
721
|
setters.validate,
|
|
712
722
|
setters.convert,
|
|
@@ -722,18 +732,18 @@ class _ClassBuilder:
|
|
|
722
732
|
break
|
|
723
733
|
if (
|
|
724
734
|
(
|
|
725
|
-
|
|
735
|
+
self._on_setattr == _DEFAULT_ON_SETATTR
|
|
726
736
|
and not (has_validator or has_converter)
|
|
727
737
|
)
|
|
728
|
-
or (
|
|
729
|
-
or (
|
|
738
|
+
or (self._on_setattr == setters.validate and not has_validator)
|
|
739
|
+
or (self._on_setattr == setters.convert and not has_converter)
|
|
730
740
|
):
|
|
731
741
|
# If class-level on_setattr is set to convert + validate, but
|
|
732
742
|
# there's no field to convert or validate, pretend like there's
|
|
733
743
|
# no on_setattr.
|
|
734
744
|
self._on_setattr = None
|
|
735
745
|
|
|
736
|
-
if
|
|
746
|
+
if props.added_pickling:
|
|
737
747
|
(
|
|
738
748
|
self._cls_dict["__getstate__"],
|
|
739
749
|
self._cls_dict["__setstate__"],
|
|
@@ -784,6 +794,7 @@ class _ClassBuilder:
|
|
|
784
794
|
self._eval_snippets()
|
|
785
795
|
if self._slots is True:
|
|
786
796
|
cls = self._create_slots_class()
|
|
797
|
+
self._cls.__attrs_base_of_slotted__ = weakref.ref(cls)
|
|
787
798
|
else:
|
|
788
799
|
cls = self._patch_original_class()
|
|
789
800
|
if PY_3_10_PLUS:
|
|
@@ -845,6 +856,10 @@ class _ClassBuilder:
|
|
|
845
856
|
if k not in (*tuple(self._attr_names), "__dict__", "__weakref__")
|
|
846
857
|
}
|
|
847
858
|
|
|
859
|
+
# 3.14.0rc2+
|
|
860
|
+
if hasattr(sys, "_clear_type_descriptors"):
|
|
861
|
+
sys._clear_type_descriptors(self._cls)
|
|
862
|
+
|
|
848
863
|
# If our class doesn't have its own implementation of __setattr__
|
|
849
864
|
# (either from the user or by us), check the bases, if one of them has
|
|
850
865
|
# an attrs-made __setattr__, that needs to be reset. We don't walk the
|
|
@@ -1326,6 +1341,7 @@ def attrs(
|
|
|
1326
1341
|
field_transformer=None,
|
|
1327
1342
|
match_args=True,
|
|
1328
1343
|
unsafe_hash=None,
|
|
1344
|
+
force_kw_only=True,
|
|
1329
1345
|
):
|
|
1330
1346
|
r"""
|
|
1331
1347
|
A class decorator that adds :term:`dunder methods` according to the
|
|
@@ -1392,6 +1408,10 @@ def attrs(
|
|
|
1392
1408
|
If a class has an *inherited* classmethod called
|
|
1393
1409
|
``__attrs_init_subclass__``, it is executed after the class is created.
|
|
1394
1410
|
.. deprecated:: 24.1.0 *hash* is deprecated in favor of *unsafe_hash*.
|
|
1411
|
+
.. versionchanged:: 25.4.0
|
|
1412
|
+
*kw_only* now only applies to attributes defined in the current class,
|
|
1413
|
+
and respects attribute-level ``kw_only=False`` settings.
|
|
1414
|
+
.. versionadded:: 25.4.0 *force_kw_only*
|
|
1395
1415
|
"""
|
|
1396
1416
|
if repr_ns is not None:
|
|
1397
1417
|
import warnings
|
|
@@ -1413,6 +1433,7 @@ def attrs(
|
|
|
1413
1433
|
on_setattr = setters.pipe(*on_setattr)
|
|
1414
1434
|
|
|
1415
1435
|
def wrap(cls):
|
|
1436
|
+
nonlocal hash
|
|
1416
1437
|
is_frozen = frozen or _has_frozen_base_class(cls)
|
|
1417
1438
|
is_exc = auto_exc is True and issubclass(cls, BaseException)
|
|
1418
1439
|
has_own_setattr = auto_detect and _has_own_attribute(
|
|
@@ -1423,84 +1444,112 @@ def attrs(
|
|
|
1423
1444
|
msg = "Can't freeze a class with a custom __setattr__."
|
|
1424
1445
|
raise ValueError(msg)
|
|
1425
1446
|
|
|
1426
|
-
|
|
1427
|
-
cls,
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1447
|
+
eq = not is_exc and _determine_whether_to_implement(
|
|
1448
|
+
cls, eq_, auto_detect, ("__eq__", "__ne__")
|
|
1449
|
+
)
|
|
1450
|
+
|
|
1451
|
+
Hashability = ClassProps.Hashability
|
|
1452
|
+
|
|
1453
|
+
if is_exc:
|
|
1454
|
+
hashability = Hashability.LEAVE_ALONE
|
|
1455
|
+
elif hash is True:
|
|
1456
|
+
hashability = (
|
|
1457
|
+
Hashability.HASHABLE_CACHED
|
|
1458
|
+
if cache_hash
|
|
1459
|
+
else Hashability.HASHABLE
|
|
1460
|
+
)
|
|
1461
|
+
elif hash is False:
|
|
1462
|
+
hashability = Hashability.LEAVE_ALONE
|
|
1463
|
+
elif hash is None:
|
|
1464
|
+
if auto_detect is True and _has_own_attribute(cls, "__hash__"):
|
|
1465
|
+
hashability = Hashability.LEAVE_ALONE
|
|
1466
|
+
elif eq is True and is_frozen is True:
|
|
1467
|
+
hashability = (
|
|
1468
|
+
Hashability.HASHABLE_CACHED
|
|
1469
|
+
if cache_hash
|
|
1470
|
+
else Hashability.HASHABLE
|
|
1471
|
+
)
|
|
1472
|
+
elif eq is False:
|
|
1473
|
+
hashability = Hashability.LEAVE_ALONE
|
|
1474
|
+
else:
|
|
1475
|
+
hashability = Hashability.UNHASHABLE
|
|
1476
|
+
else:
|
|
1477
|
+
msg = "Invalid value for hash. Must be True, False, or None."
|
|
1478
|
+
raise TypeError(msg)
|
|
1479
|
+
|
|
1480
|
+
KeywordOnly = ClassProps.KeywordOnly
|
|
1481
|
+
if kw_only:
|
|
1482
|
+
kwo = KeywordOnly.FORCE if force_kw_only else KeywordOnly.YES
|
|
1483
|
+
else:
|
|
1484
|
+
kwo = KeywordOnly.NO
|
|
1485
|
+
|
|
1486
|
+
props = ClassProps(
|
|
1487
|
+
is_exception=is_exc,
|
|
1488
|
+
is_frozen=is_frozen,
|
|
1489
|
+
is_slotted=slots,
|
|
1490
|
+
collected_fields_by_mro=collect_by_mro,
|
|
1491
|
+
added_init=_determine_whether_to_implement(
|
|
1492
|
+
cls, init, auto_detect, ("__init__",)
|
|
1493
|
+
),
|
|
1494
|
+
added_repr=_determine_whether_to_implement(
|
|
1495
|
+
cls, repr, auto_detect, ("__repr__",)
|
|
1496
|
+
),
|
|
1497
|
+
added_eq=eq,
|
|
1498
|
+
added_ordering=not is_exc
|
|
1499
|
+
and _determine_whether_to_implement(
|
|
1500
|
+
cls,
|
|
1501
|
+
order_,
|
|
1502
|
+
auto_detect,
|
|
1503
|
+
("__lt__", "__le__", "__gt__", "__ge__"),
|
|
1504
|
+
),
|
|
1505
|
+
hashability=hashability,
|
|
1506
|
+
added_match_args=match_args,
|
|
1507
|
+
kw_only=kwo,
|
|
1508
|
+
has_weakref_slot=weakref_slot,
|
|
1509
|
+
added_str=str,
|
|
1510
|
+
added_pickling=_determine_whether_to_implement(
|
|
1433
1511
|
cls,
|
|
1434
1512
|
getstate_setstate,
|
|
1435
1513
|
auto_detect,
|
|
1436
1514
|
("__getstate__", "__setstate__"),
|
|
1437
1515
|
default=slots,
|
|
1438
1516
|
),
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
cache_hash,
|
|
1442
|
-
is_exc,
|
|
1443
|
-
collect_by_mro,
|
|
1444
|
-
on_setattr,
|
|
1445
|
-
has_own_setattr,
|
|
1446
|
-
field_transformer,
|
|
1517
|
+
on_setattr_hook=on_setattr,
|
|
1518
|
+
field_transformer=field_transformer,
|
|
1447
1519
|
)
|
|
1448
1520
|
|
|
1449
|
-
if
|
|
1450
|
-
|
|
1451
|
-
|
|
1521
|
+
if not props.is_hashable and cache_hash:
|
|
1522
|
+
msg = "Invalid value for cache_hash. To use hash caching, hashing must be either explicitly or implicitly enabled."
|
|
1523
|
+
raise TypeError(msg)
|
|
1524
|
+
|
|
1525
|
+
builder = _ClassBuilder(
|
|
1526
|
+
cls,
|
|
1527
|
+
these,
|
|
1528
|
+
auto_attribs=auto_attribs,
|
|
1529
|
+
props=props,
|
|
1530
|
+
has_custom_setattr=has_own_setattr,
|
|
1531
|
+
)
|
|
1532
|
+
|
|
1533
|
+
if props.added_repr:
|
|
1452
1534
|
builder.add_repr(repr_ns)
|
|
1453
1535
|
|
|
1454
|
-
if
|
|
1536
|
+
if props.added_str:
|
|
1455
1537
|
builder.add_str()
|
|
1456
1538
|
|
|
1457
|
-
|
|
1458
|
-
cls, eq_, auto_detect, ("__eq__", "__ne__")
|
|
1459
|
-
)
|
|
1460
|
-
if not is_exc and eq is True:
|
|
1539
|
+
if props.added_eq:
|
|
1461
1540
|
builder.add_eq()
|
|
1462
|
-
if
|
|
1463
|
-
cls, order_, auto_detect, ("__lt__", "__le__", "__gt__", "__ge__")
|
|
1464
|
-
):
|
|
1541
|
+
if props.added_ordering:
|
|
1465
1542
|
builder.add_order()
|
|
1466
1543
|
|
|
1467
1544
|
if not frozen:
|
|
1468
1545
|
builder.add_setattr()
|
|
1469
1546
|
|
|
1470
|
-
|
|
1471
|
-
if (
|
|
1472
|
-
hash is None
|
|
1473
|
-
and auto_detect is True
|
|
1474
|
-
and _has_own_attribute(cls, "__hash__")
|
|
1475
|
-
):
|
|
1476
|
-
hash = False
|
|
1477
|
-
|
|
1478
|
-
if hash is not True and hash is not False and hash is not None:
|
|
1479
|
-
# Can't use `hash in` because 1 == True for example.
|
|
1480
|
-
msg = "Invalid value for hash. Must be True, False, or None."
|
|
1481
|
-
raise TypeError(msg)
|
|
1482
|
-
|
|
1483
|
-
if hash is False or (hash is None and eq is False) or is_exc:
|
|
1484
|
-
# Don't do anything. Should fall back to __object__'s __hash__
|
|
1485
|
-
# which is by id.
|
|
1486
|
-
if cache_hash:
|
|
1487
|
-
msg = "Invalid value for cache_hash. To use hash caching, hashing must be either explicitly or implicitly enabled."
|
|
1488
|
-
raise TypeError(msg)
|
|
1489
|
-
elif hash is True or (
|
|
1490
|
-
hash is None and eq is True and is_frozen is True
|
|
1491
|
-
):
|
|
1492
|
-
# Build a __hash__ if told so, or if it's safe.
|
|
1547
|
+
if props.is_hashable:
|
|
1493
1548
|
builder.add_hash()
|
|
1494
|
-
|
|
1495
|
-
# Raise TypeError on attempts to hash.
|
|
1496
|
-
if cache_hash:
|
|
1497
|
-
msg = "Invalid value for cache_hash. To use hash caching, hashing must be either explicitly or implicitly enabled."
|
|
1498
|
-
raise TypeError(msg)
|
|
1549
|
+
elif props.hashability is Hashability.UNHASHABLE:
|
|
1499
1550
|
builder.make_unhashable()
|
|
1500
1551
|
|
|
1501
|
-
if
|
|
1502
|
-
cls, init, auto_detect, ("__init__",)
|
|
1503
|
-
):
|
|
1552
|
+
if props.added_init:
|
|
1504
1553
|
builder.add_init()
|
|
1505
1554
|
else:
|
|
1506
1555
|
builder.add_attrs_init()
|
|
@@ -2126,8 +2175,9 @@ def _attrs_to_init_script(
|
|
|
2126
2175
|
)
|
|
2127
2176
|
lines.extend(extra_lines)
|
|
2128
2177
|
|
|
2129
|
-
args = []
|
|
2130
|
-
|
|
2178
|
+
args = [] # Parameters in the definition of __init__
|
|
2179
|
+
pre_init_args = [] # Parameters in the call to __attrs_pre_init__
|
|
2180
|
+
kw_only_args = [] # Used for both 'args' and 'pre_init_args' above
|
|
2131
2181
|
attrs_to_validate = []
|
|
2132
2182
|
|
|
2133
2183
|
# This is a dictionary of names to validator and converter callables.
|
|
@@ -2205,6 +2255,7 @@ def _attrs_to_init_script(
|
|
|
2205
2255
|
kw_only_args.append(arg)
|
|
2206
2256
|
else:
|
|
2207
2257
|
args.append(arg)
|
|
2258
|
+
pre_init_args.append(arg_name)
|
|
2208
2259
|
|
|
2209
2260
|
if converter is not None:
|
|
2210
2261
|
lines.append(
|
|
@@ -2224,6 +2275,7 @@ def _attrs_to_init_script(
|
|
|
2224
2275
|
kw_only_args.append(arg)
|
|
2225
2276
|
else:
|
|
2226
2277
|
args.append(arg)
|
|
2278
|
+
pre_init_args.append(arg_name)
|
|
2227
2279
|
lines.append(f"if {arg_name} is not NOTHING:")
|
|
2228
2280
|
|
|
2229
2281
|
init_factory_name = _INIT_FACTORY_PAT % (a.name,)
|
|
@@ -2266,6 +2318,7 @@ def _attrs_to_init_script(
|
|
|
2266
2318
|
kw_only_args.append(arg_name)
|
|
2267
2319
|
else:
|
|
2268
2320
|
args.append(arg_name)
|
|
2321
|
+
pre_init_args.append(arg_name)
|
|
2269
2322
|
|
|
2270
2323
|
if converter is not None:
|
|
2271
2324
|
lines.append(
|
|
@@ -2322,7 +2375,7 @@ def _attrs_to_init_script(
|
|
|
2322
2375
|
lines.append(f"BaseException.__init__(self, {vals})")
|
|
2323
2376
|
|
|
2324
2377
|
args = ", ".join(args)
|
|
2325
|
-
pre_init_args =
|
|
2378
|
+
pre_init_args = ", ".join(pre_init_args)
|
|
2326
2379
|
if kw_only_args:
|
|
2327
2380
|
# leading comma & kw_only args
|
|
2328
2381
|
args += f"{', ' if args else ''}*, {', '.join(kw_only_args)}"
|
|
@@ -2337,7 +2390,7 @@ def _attrs_to_init_script(
|
|
|
2337
2390
|
pre_init_args += pre_init_kw_only_args
|
|
2338
2391
|
|
|
2339
2392
|
if call_pre_init and pre_init_has_args:
|
|
2340
|
-
# If pre init method has arguments, pass
|
|
2393
|
+
# If pre init method has arguments, pass the values given to __init__.
|
|
2341
2394
|
lines[0] = f"self.__attrs_pre_init__({pre_init_args})"
|
|
2342
2395
|
|
|
2343
2396
|
# Python <3.12 doesn't allow backslashes in f-strings.
|
|
@@ -2486,7 +2539,11 @@ class Attribute:
|
|
|
2486
2539
|
raise FrozenInstanceError
|
|
2487
2540
|
|
|
2488
2541
|
@classmethod
|
|
2489
|
-
def from_counting_attr(
|
|
2542
|
+
def from_counting_attr(
|
|
2543
|
+
cls, name: str, ca: _CountingAttr, kw_only: bool, type=None
|
|
2544
|
+
):
|
|
2545
|
+
# The 'kw_only' argument is the class-level setting, and is used if the
|
|
2546
|
+
# attribute itself does not explicitly set 'kw_only'.
|
|
2490
2547
|
# type holds the annotated value. deal with conflicts:
|
|
2491
2548
|
if type is None:
|
|
2492
2549
|
type = ca.type
|
|
@@ -2505,7 +2562,7 @@ class Attribute:
|
|
|
2505
2562
|
ca.metadata,
|
|
2506
2563
|
type,
|
|
2507
2564
|
ca.converter,
|
|
2508
|
-
ca.kw_only,
|
|
2565
|
+
kw_only if ca.kw_only is None else ca.kw_only,
|
|
2509
2566
|
ca.eq,
|
|
2510
2567
|
ca.eq_key,
|
|
2511
2568
|
ca.order,
|
|
@@ -2741,6 +2798,188 @@ class _CountingAttr:
|
|
|
2741
2798
|
_CountingAttr = _add_eq(_add_repr(_CountingAttr))
|
|
2742
2799
|
|
|
2743
2800
|
|
|
2801
|
+
class ClassProps:
|
|
2802
|
+
"""
|
|
2803
|
+
Effective class properties as derived from parameters to `attr.s()` or
|
|
2804
|
+
`define()` decorators.
|
|
2805
|
+
|
|
2806
|
+
This is the same data structure that *attrs* uses internally to decide how
|
|
2807
|
+
to construct the final class.
|
|
2808
|
+
|
|
2809
|
+
Warning:
|
|
2810
|
+
|
|
2811
|
+
This feature is currently **experimental** and is not covered by our
|
|
2812
|
+
strict backwards-compatibility guarantees.
|
|
2813
|
+
|
|
2814
|
+
|
|
2815
|
+
Attributes:
|
|
2816
|
+
is_exception (bool):
|
|
2817
|
+
Whether the class is treated as an exception class.
|
|
2818
|
+
|
|
2819
|
+
is_slotted (bool):
|
|
2820
|
+
Whether the class is `slotted <slotted classes>`.
|
|
2821
|
+
|
|
2822
|
+
has_weakref_slot (bool):
|
|
2823
|
+
Whether the class has a slot for weak references.
|
|
2824
|
+
|
|
2825
|
+
is_frozen (bool):
|
|
2826
|
+
Whether the class is frozen.
|
|
2827
|
+
|
|
2828
|
+
kw_only (KeywordOnly):
|
|
2829
|
+
Whether / how the class enforces keyword-only arguments on the
|
|
2830
|
+
``__init__`` method.
|
|
2831
|
+
|
|
2832
|
+
collected_fields_by_mro (bool):
|
|
2833
|
+
Whether the class fields were collected by method resolution order.
|
|
2834
|
+
That is, correctly but unlike `dataclasses`.
|
|
2835
|
+
|
|
2836
|
+
added_init (bool):
|
|
2837
|
+
Whether the class has an *attrs*-generated ``__init__`` method.
|
|
2838
|
+
|
|
2839
|
+
added_repr (bool):
|
|
2840
|
+
Whether the class has an *attrs*-generated ``__repr__`` method.
|
|
2841
|
+
|
|
2842
|
+
added_eq (bool):
|
|
2843
|
+
Whether the class has *attrs*-generated equality methods.
|
|
2844
|
+
|
|
2845
|
+
added_ordering (bool):
|
|
2846
|
+
Whether the class has *attrs*-generated ordering methods.
|
|
2847
|
+
|
|
2848
|
+
hashability (Hashability): How `hashable <hashing>` the class is.
|
|
2849
|
+
|
|
2850
|
+
added_match_args (bool):
|
|
2851
|
+
Whether the class supports positional `match <match>` over its
|
|
2852
|
+
fields.
|
|
2853
|
+
|
|
2854
|
+
added_str (bool):
|
|
2855
|
+
Whether the class has an *attrs*-generated ``__str__`` method.
|
|
2856
|
+
|
|
2857
|
+
added_pickling (bool):
|
|
2858
|
+
Whether the class has *attrs*-generated ``__getstate__`` and
|
|
2859
|
+
``__setstate__`` methods for `pickle`.
|
|
2860
|
+
|
|
2861
|
+
on_setattr_hook (Callable[[Any, Attribute[Any], Any], Any] | None):
|
|
2862
|
+
The class's ``__setattr__`` hook.
|
|
2863
|
+
|
|
2864
|
+
field_transformer (Callable[[Attribute[Any]], Attribute[Any]] | None):
|
|
2865
|
+
The class's `field transformers <transform-fields>`.
|
|
2866
|
+
|
|
2867
|
+
.. versionadded:: 25.4.0
|
|
2868
|
+
"""
|
|
2869
|
+
|
|
2870
|
+
class Hashability(enum.Enum):
|
|
2871
|
+
"""
|
|
2872
|
+
The hashability of a class.
|
|
2873
|
+
|
|
2874
|
+
.. versionadded:: 25.4.0
|
|
2875
|
+
"""
|
|
2876
|
+
|
|
2877
|
+
HASHABLE = "hashable"
|
|
2878
|
+
"""Write a ``__hash__``."""
|
|
2879
|
+
HASHABLE_CACHED = "hashable_cache"
|
|
2880
|
+
"""Write a ``__hash__`` and cache the hash."""
|
|
2881
|
+
UNHASHABLE = "unhashable"
|
|
2882
|
+
"""Set ``__hash__`` to ``None``."""
|
|
2883
|
+
LEAVE_ALONE = "leave_alone"
|
|
2884
|
+
"""Don't touch ``__hash__``."""
|
|
2885
|
+
|
|
2886
|
+
class KeywordOnly(enum.Enum):
|
|
2887
|
+
"""
|
|
2888
|
+
How attributes should be treated regarding keyword-only parameters.
|
|
2889
|
+
|
|
2890
|
+
.. versionadded:: 25.4.0
|
|
2891
|
+
"""
|
|
2892
|
+
|
|
2893
|
+
NO = "no"
|
|
2894
|
+
"""Attributes are not keyword-only."""
|
|
2895
|
+
YES = "yes"
|
|
2896
|
+
"""Attributes in current class without kw_only=False are keyword-only."""
|
|
2897
|
+
FORCE = "force"
|
|
2898
|
+
"""All attributes are keyword-only."""
|
|
2899
|
+
|
|
2900
|
+
__slots__ = ( # noqa: RUF023 -- order matters for __init__
|
|
2901
|
+
"is_exception",
|
|
2902
|
+
"is_slotted",
|
|
2903
|
+
"has_weakref_slot",
|
|
2904
|
+
"is_frozen",
|
|
2905
|
+
"kw_only",
|
|
2906
|
+
"collected_fields_by_mro",
|
|
2907
|
+
"added_init",
|
|
2908
|
+
"added_repr",
|
|
2909
|
+
"added_eq",
|
|
2910
|
+
"added_ordering",
|
|
2911
|
+
"hashability",
|
|
2912
|
+
"added_match_args",
|
|
2913
|
+
"added_str",
|
|
2914
|
+
"added_pickling",
|
|
2915
|
+
"on_setattr_hook",
|
|
2916
|
+
"field_transformer",
|
|
2917
|
+
)
|
|
2918
|
+
|
|
2919
|
+
def __init__(
|
|
2920
|
+
self,
|
|
2921
|
+
is_exception,
|
|
2922
|
+
is_slotted,
|
|
2923
|
+
has_weakref_slot,
|
|
2924
|
+
is_frozen,
|
|
2925
|
+
kw_only,
|
|
2926
|
+
collected_fields_by_mro,
|
|
2927
|
+
added_init,
|
|
2928
|
+
added_repr,
|
|
2929
|
+
added_eq,
|
|
2930
|
+
added_ordering,
|
|
2931
|
+
hashability,
|
|
2932
|
+
added_match_args,
|
|
2933
|
+
added_str,
|
|
2934
|
+
added_pickling,
|
|
2935
|
+
on_setattr_hook,
|
|
2936
|
+
field_transformer,
|
|
2937
|
+
):
|
|
2938
|
+
self.is_exception = is_exception
|
|
2939
|
+
self.is_slotted = is_slotted
|
|
2940
|
+
self.has_weakref_slot = has_weakref_slot
|
|
2941
|
+
self.is_frozen = is_frozen
|
|
2942
|
+
self.kw_only = kw_only
|
|
2943
|
+
self.collected_fields_by_mro = collected_fields_by_mro
|
|
2944
|
+
self.added_init = added_init
|
|
2945
|
+
self.added_repr = added_repr
|
|
2946
|
+
self.added_eq = added_eq
|
|
2947
|
+
self.added_ordering = added_ordering
|
|
2948
|
+
self.hashability = hashability
|
|
2949
|
+
self.added_match_args = added_match_args
|
|
2950
|
+
self.added_str = added_str
|
|
2951
|
+
self.added_pickling = added_pickling
|
|
2952
|
+
self.on_setattr_hook = on_setattr_hook
|
|
2953
|
+
self.field_transformer = field_transformer
|
|
2954
|
+
|
|
2955
|
+
@property
|
|
2956
|
+
def is_hashable(self):
|
|
2957
|
+
return (
|
|
2958
|
+
self.hashability is ClassProps.Hashability.HASHABLE
|
|
2959
|
+
or self.hashability is ClassProps.Hashability.HASHABLE_CACHED
|
|
2960
|
+
)
|
|
2961
|
+
|
|
2962
|
+
|
|
2963
|
+
_cas = [
|
|
2964
|
+
Attribute(
|
|
2965
|
+
name=name,
|
|
2966
|
+
default=NOTHING,
|
|
2967
|
+
validator=None,
|
|
2968
|
+
repr=True,
|
|
2969
|
+
cmp=None,
|
|
2970
|
+
eq=True,
|
|
2971
|
+
order=False,
|
|
2972
|
+
hash=True,
|
|
2973
|
+
init=True,
|
|
2974
|
+
inherited=False,
|
|
2975
|
+
alias=_default_init_alias_for(name),
|
|
2976
|
+
)
|
|
2977
|
+
for name in ClassProps.__slots__
|
|
2978
|
+
]
|
|
2979
|
+
|
|
2980
|
+
ClassProps = _add_eq(_add_repr(ClassProps, attrs=_cas), attrs=_cas)
|
|
2981
|
+
|
|
2982
|
+
|
|
2744
2983
|
class Factory:
|
|
2745
2984
|
"""
|
|
2746
2985
|
Stores a factory callable.
|