ant-ray-nightly 3.0.0.dev20251006__cp312-cp312-macosx_14_0_arm64.whl → 3.0.0.dev20251015__cp312-cp312-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.

Files changed (103) hide show
  1. {ant_ray_nightly-3.0.0.dev20251006.dist-info → ant_ray_nightly-3.0.0.dev20251015.dist-info}/METADATA +105 -105
  2. {ant_ray_nightly-3.0.0.dev20251006.dist-info → ant_ray_nightly-3.0.0.dev20251015.dist-info}/RECORD +100 -100
  3. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/.hash/_cparser.pxd.hash +1 -1
  4. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/.hash/_find_header.pxd.hash +1 -1
  5. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/.hash/_http_parser.pyx.hash +1 -1
  6. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/.hash/_http_writer.pyx.hash +1 -1
  7. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/.hash/hdrs.py.hash +1 -1
  8. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/__init__.py +1 -1
  9. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_cookie_helpers.py +2 -6
  10. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_http_parser.cpython-312-darwin.so +0 -0
  11. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_http_parser.pyx +1 -3
  12. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_http_writer.cpython-312-darwin.so +0 -0
  13. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_http_writer.pyx +9 -7
  14. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_websocket/.hash/mask.pxd.hash +1 -1
  15. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_websocket/.hash/mask.pyx.hash +1 -1
  16. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_websocket/.hash/reader_c.pxd.hash +1 -1
  17. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_websocket/mask.cpython-312-darwin.so +0 -0
  18. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/_websocket/reader_c.cpython-312-darwin.so +0 -0
  19. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/abc.py +1 -1
  20. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/client_reqrep.py +13 -4
  21. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/compression_utils.py +31 -0
  22. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/formdata.py +1 -1
  23. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/http_parser.py +18 -3
  24. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/multipart.py +4 -0
  25. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/streams.py +8 -0
  26. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/web_fileresponse.py +4 -4
  27. ray/_private/runtime_env/agent/thirdparty_files/aiohttp/web_urldispatcher.py +3 -1
  28. ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/METADATA +24 -12
  29. ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/RECORD +33 -33
  30. ray/_private/runtime_env/agent/thirdparty_files/attr/__init__.pyi +4 -4
  31. ray/_private/runtime_env/agent/thirdparty_files/attr/_compat.py +8 -3
  32. ray/_private/runtime_env/agent/thirdparty_files/attr/_funcs.py +45 -16
  33. ray/_private/runtime_env/agent/thirdparty_files/attr/_make.py +334 -95
  34. ray/_private/runtime_env/agent/thirdparty_files/attr/_next_gen.py +58 -7
  35. ray/_private/runtime_env/agent/thirdparty_files/attr/_version_info.py +3 -0
  36. ray/_private/runtime_env/agent/thirdparty_files/attr/validators.py +51 -13
  37. ray/_private/runtime_env/agent/thirdparty_files/attr/validators.pyi +59 -5
  38. ray/_private/runtime_env/agent/thirdparty_files/attrs/__init__.py +4 -1
  39. ray/_private/runtime_env/agent/thirdparty_files/attrs/__init__.pyi +58 -7
  40. ray/_private/runtime_env/agent/thirdparty_files/{attrs-25.3.0.dist-info → attrs-25.4.0.dist-info}/METADATA +63 -60
  41. ray/_private/runtime_env/agent/thirdparty_files/{attrs-25.3.0.dist-info → attrs-25.4.0.dist-info}/RECORD +15 -15
  42. ray/_private/runtime_env/agent/thirdparty_files/frozenlist/__init__.py +1 -1
  43. ray/_private/runtime_env/agent/thirdparty_files/frozenlist/_frozenlist.cpython-312-darwin.so +0 -0
  44. ray/_private/runtime_env/agent/thirdparty_files/{frozenlist-1.7.0.dist-info → frozenlist-1.8.0.dist-info}/METADATA +47 -1
  45. ray/_private/runtime_env/agent/thirdparty_files/frozenlist-1.8.0.dist-info/RECORD +12 -0
  46. ray/_private/runtime_env/agent/thirdparty_files/idna/codec.py +1 -1
  47. ray/_private/runtime_env/agent/thirdparty_files/idna/core.py +1 -1
  48. ray/_private/runtime_env/agent/thirdparty_files/idna/idnadata.py +72 -6
  49. ray/_private/runtime_env/agent/thirdparty_files/idna/package_data.py +1 -1
  50. ray/_private/runtime_env/agent/thirdparty_files/idna/uts46data.py +891 -731
  51. ray/_private/runtime_env/agent/thirdparty_files/{idna-3.10.dist-info → idna-3.11.dist-info}/METADATA +37 -78
  52. ray/_private/runtime_env/agent/thirdparty_files/idna-3.11.dist-info/RECORD +22 -0
  53. ray/_private/runtime_env/agent/thirdparty_files/{idna-3.10.dist-info → idna-3.11.dist-info}/WHEEL +1 -1
  54. ray/_private/runtime_env/agent/thirdparty_files/{idna-3.10.dist-info → idna-3.11.dist-info/licenses}/LICENSE.md +1 -1
  55. ray/_private/runtime_env/agent/thirdparty_files/multidict/__init__.py +9 -8
  56. ray/_private/runtime_env/agent/thirdparty_files/multidict/_multidict.cpython-312-darwin.so +0 -0
  57. ray/_private/runtime_env/agent/thirdparty_files/{multidict-6.6.4.dist-info → multidict-6.7.0.dist-info}/METADATA +2 -1
  58. ray/_private/runtime_env/agent/thirdparty_files/{multidict-6.6.4.dist-info → multidict-6.7.0.dist-info}/RECORD +8 -8
  59. ray/_private/runtime_env/agent/thirdparty_files/propcache/__init__.py +1 -1
  60. ray/_private/runtime_env/agent/thirdparty_files/propcache/_helpers_c.cpython-312-darwin.so +0 -0
  61. ray/_private/runtime_env/agent/thirdparty_files/propcache/_helpers_c.pyx +4 -5
  62. ray/_private/runtime_env/agent/thirdparty_files/{propcache-0.4.0.dist-info → propcache-0.4.1.dist-info}/METADATA +31 -1
  63. ray/_private/runtime_env/agent/thirdparty_files/propcache-0.4.1.dist-info/RECORD +18 -0
  64. ray/_private/runtime_env/agent/thirdparty_files/yarl/__init__.py +1 -1
  65. ray/_private/runtime_env/agent/thirdparty_files/yarl/_quoting_c.cpython-312-darwin.so +0 -0
  66. ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/METADATA +20 -1
  67. ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/RECORD +9 -9
  68. ray/thirdparty_files/setproctitle-1.2.2.dist-info/RECORD +1 -1
  69. ray/thirdparty_files/setproctitle.cpython-312-darwin.so +0 -0
  70. ray/_private/runtime_env/agent/thirdparty_files/frozenlist-1.7.0.dist-info/RECORD +0 -12
  71. ray/_private/runtime_env/agent/thirdparty_files/idna-3.10.dist-info/RECORD +0 -22
  72. ray/_private/runtime_env/agent/thirdparty_files/propcache-0.4.0.dist-info/RECORD +0 -18
  73. {ant_ray_nightly-3.0.0.dev20251006.dist-info → ant_ray_nightly-3.0.0.dev20251015.dist-info}/WHEEL +0 -0
  74. {ant_ray_nightly-3.0.0.dev20251006.dist-info → ant_ray_nightly-3.0.0.dev20251015.dist-info}/entry_points.txt +0 -0
  75. {ant_ray_nightly-3.0.0.dev20251006.dist-info → ant_ray_nightly-3.0.0.dev20251015.dist-info}/top_level.txt +0 -0
  76. /ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/INSTALLER +0 -0
  77. /ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/REQUESTED +0 -0
  78. /ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/WHEEL +0 -0
  79. /ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/licenses/LICENSE.txt +0 -0
  80. /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
  81. /ray/_private/runtime_env/agent/thirdparty_files/{aiohttp-3.12.15.dist-info → aiohttp-3.13.0.dist-info}/top_level.txt +0 -0
  82. /ray/_private/runtime_env/agent/thirdparty_files/{attrs-25.3.0.dist-info → attrs-25.4.0.dist-info}/INSTALLER +0 -0
  83. /ray/_private/runtime_env/agent/thirdparty_files/{attrs-25.3.0.dist-info → attrs-25.4.0.dist-info}/WHEEL +0 -0
  84. /ray/_private/runtime_env/agent/thirdparty_files/{attrs-25.3.0.dist-info → attrs-25.4.0.dist-info}/licenses/LICENSE +0 -0
  85. /ray/_private/runtime_env/agent/thirdparty_files/{frozenlist-1.7.0.dist-info → frozenlist-1.8.0.dist-info}/INSTALLER +0 -0
  86. /ray/_private/runtime_env/agent/thirdparty_files/{frozenlist-1.7.0.dist-info → frozenlist-1.8.0.dist-info}/WHEEL +0 -0
  87. /ray/_private/runtime_env/agent/thirdparty_files/{frozenlist-1.7.0.dist-info → frozenlist-1.8.0.dist-info}/licenses/LICENSE +0 -0
  88. /ray/_private/runtime_env/agent/thirdparty_files/{frozenlist-1.7.0.dist-info → frozenlist-1.8.0.dist-info}/top_level.txt +0 -0
  89. /ray/_private/runtime_env/agent/thirdparty_files/{idna-3.10.dist-info → idna-3.11.dist-info}/INSTALLER +0 -0
  90. /ray/_private/runtime_env/agent/thirdparty_files/{multidict-6.6.4.dist-info → multidict-6.7.0.dist-info}/INSTALLER +0 -0
  91. /ray/_private/runtime_env/agent/thirdparty_files/{multidict-6.6.4.dist-info → multidict-6.7.0.dist-info}/WHEEL +0 -0
  92. /ray/_private/runtime_env/agent/thirdparty_files/{multidict-6.6.4.dist-info → multidict-6.7.0.dist-info}/licenses/LICENSE +0 -0
  93. /ray/_private/runtime_env/agent/thirdparty_files/{multidict-6.6.4.dist-info → multidict-6.7.0.dist-info}/top_level.txt +0 -0
  94. /ray/_private/runtime_env/agent/thirdparty_files/{propcache-0.4.0.dist-info → propcache-0.4.1.dist-info}/INSTALLER +0 -0
  95. /ray/_private/runtime_env/agent/thirdparty_files/{propcache-0.4.0.dist-info → propcache-0.4.1.dist-info}/WHEEL +0 -0
  96. /ray/_private/runtime_env/agent/thirdparty_files/{propcache-0.4.0.dist-info → propcache-0.4.1.dist-info}/licenses/LICENSE +0 -0
  97. /ray/_private/runtime_env/agent/thirdparty_files/{propcache-0.4.0.dist-info → propcache-0.4.1.dist-info}/licenses/NOTICE +0 -0
  98. /ray/_private/runtime_env/agent/thirdparty_files/{propcache-0.4.0.dist-info → propcache-0.4.1.dist-info}/top_level.txt +0 -0
  99. /ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/INSTALLER +0 -0
  100. /ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/WHEEL +0 -0
  101. /ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/licenses/LICENSE +0 -0
  102. /ray/_private/runtime_env/agent/thirdparty_files/{yarl-1.21.0.dist-info → yarl-1.22.0.dist-info}/licenses/NOTICE +0 -0
  103. /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=False,
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, these, auto_attribs, kw_only, collect_by_mro, field_transformer
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(attr_name, ca, anns.get(attr_name)) for attr_name, ca in ca_list
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
- slots,
655
- frozen,
656
- weakref_slot,
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
- collect_by_mro,
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 slots else {}
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 = slots
683
- self._frozen = frozen
684
- self._weakref_slot = weakref_slot
685
- self._cache_hash = 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 = is_exc
697
- self._on_setattr = 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 frozen:
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 on_setattr in (
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
- on_setattr == _DEFAULT_ON_SETATTR
735
+ self._on_setattr == _DEFAULT_ON_SETATTR
726
736
  and not (has_validator or has_converter)
727
737
  )
728
- or (on_setattr == setters.validate and not has_validator)
729
- or (on_setattr == setters.convert and not has_converter)
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 getstate_setstate:
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
- builder = _ClassBuilder(
1427
- cls,
1428
- these,
1429
- slots,
1430
- is_frozen,
1431
- weakref_slot,
1432
- _determine_whether_to_implement(
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
- auto_attribs,
1440
- kw_only,
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 _determine_whether_to_implement(
1450
- cls, repr, auto_detect, ("__repr__",)
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 str is True:
1536
+ if props.added_str:
1455
1537
  builder.add_str()
1456
1538
 
1457
- eq = _determine_whether_to_implement(
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 not is_exc and _determine_whether_to_implement(
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
- nonlocal hash
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
- else:
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 _determine_whether_to_implement(
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
- kw_only_args = []
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 = 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 same arguments as `__init__`.
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(cls, name: str, ca: _CountingAttr, type=None):
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.