koichi12 commited on
Commit
0333411
·
verified ·
1 Parent(s): 80344bd

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/__init__.py +13 -0
  3. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/__pycache__/__init__.cpython-311.pyc +0 -0
  4. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/__pycache__/_staggered.cpython-311.pyc +0 -0
  5. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/__pycache__/impl.cpython-311.pyc +0 -0
  6. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/__pycache__/types.cpython-311.pyc +0 -0
  7. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/__pycache__/utils.cpython-311.pyc +0 -0
  8. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/_staggered.py +202 -0
  9. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/impl.py +221 -0
  10. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/py.typed +0 -0
  11. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/types.py +12 -0
  12. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/utils.py +97 -0
  13. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiosignal/__pycache__/__init__.cpython-311.pyc +0 -0
  14. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/__init__.pyi +389 -0
  15. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/_cmp.py +160 -0
  16. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/_cmp.pyi +13 -0
  17. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/_make.py +3055 -0
  18. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/_next_gen.py +623 -0
  19. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/_typing_compat.pyi +15 -0
  20. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/_version_info.py +86 -0
  21. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/converters.py +162 -0
  22. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/converters.pyi +19 -0
  23. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/exceptions.py +95 -0
  24. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/filters.py +72 -0
  25. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/filters.pyi +6 -0
  26. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/py.typed +0 -0
  27. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/setters.pyi +20 -0
  28. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/validators.py +710 -0
  29. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/validators.pyi +86 -0
  30. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs-25.1.0.dist-info/INSTALLER +1 -0
  31. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs-25.1.0.dist-info/METADATA +232 -0
  32. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs-25.1.0.dist-info/RECORD +55 -0
  33. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs-25.1.0.dist-info/WHEEL +4 -0
  34. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs-25.1.0.dist-info/licenses/LICENSE +21 -0
  35. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__init__.py +69 -0
  36. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__init__.pyi +263 -0
  37. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__pycache__/__init__.cpython-311.pyc +0 -0
  38. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__pycache__/converters.cpython-311.pyc +0 -0
  39. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__pycache__/exceptions.cpython-311.pyc +0 -0
  40. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__pycache__/filters.cpython-311.pyc +0 -0
  41. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__pycache__/setters.cpython-311.pyc +0 -0
  42. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__pycache__/validators.cpython-311.pyc +0 -0
  43. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/converters.py +3 -0
  44. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/exceptions.py +3 -0
  45. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/filters.py +3 -0
  46. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/py.typed +0 -0
  47. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/setters.py +3 -0
  48. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/validators.py +3 -0
  49. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/frozenlist/__init__.py +98 -0
  50. .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/frozenlist/__init__.pyi +47 -0
.gitattributes CHANGED
@@ -159,3 +159,5 @@ tuning-competition-baseline/.venv/lib/python3.11/site-packages/torch/_inductor/_
159
  .venv/lib/python3.11/site-packages/xgrammar/xgrammar_bindings.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
160
  .venv/lib/python3.11/site-packages/ray/_raylet.so filter=lfs diff=lfs merge=lfs -text
161
  .venv/lib/python3.11/site-packages/ray/core/libjemalloc.so filter=lfs diff=lfs merge=lfs -text
 
 
 
159
  .venv/lib/python3.11/site-packages/xgrammar/xgrammar_bindings.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
160
  .venv/lib/python3.11/site-packages/ray/_raylet.so filter=lfs diff=lfs merge=lfs -text
161
  .venv/lib/python3.11/site-packages/ray/core/libjemalloc.so filter=lfs diff=lfs merge=lfs -text
162
+ .venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/yarl/_quoting_c.cpython-311-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
163
+ .venv/lib/python3.11/site-packages/ray/dag/__pycache__/compiled_dag_node.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/__init__.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __version__ = "2.4.4"
2
+
3
+ from .impl import start_connection
4
+ from .types import AddrInfoType
5
+ from .utils import addr_to_addr_infos, pop_addr_infos_interleave, remove_addr_infos
6
+
7
+ __all__ = (
8
+ "AddrInfoType",
9
+ "addr_to_addr_infos",
10
+ "pop_addr_infos_interleave",
11
+ "remove_addr_infos",
12
+ "start_connection",
13
+ )
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (568 Bytes). View file
 
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/__pycache__/_staggered.cpython-311.pyc ADDED
Binary file (8.89 kB). View file
 
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/__pycache__/impl.cpython-311.pyc ADDED
Binary file (9.98 kB). View file
 
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/__pycache__/types.cpython-311.pyc ADDED
Binary file (562 Bytes). View file
 
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/__pycache__/utils.cpython-311.pyc ADDED
Binary file (4.21 kB). View file
 
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/_staggered.py ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import contextlib
3
+ from typing import (
4
+ TYPE_CHECKING,
5
+ Any,
6
+ Awaitable,
7
+ Callable,
8
+ Iterable,
9
+ List,
10
+ Optional,
11
+ Set,
12
+ Tuple,
13
+ TypeVar,
14
+ Union,
15
+ )
16
+
17
+ _T = TypeVar("_T")
18
+
19
+
20
+ def _set_result(wait_next: "asyncio.Future[None]") -> None:
21
+ """Set the result of a future if it is not already done."""
22
+ if not wait_next.done():
23
+ wait_next.set_result(None)
24
+
25
+
26
+ async def _wait_one(
27
+ futures: "Iterable[asyncio.Future[Any]]",
28
+ loop: asyncio.AbstractEventLoop,
29
+ ) -> _T:
30
+ """Wait for the first future to complete."""
31
+ wait_next = loop.create_future()
32
+
33
+ def _on_completion(fut: "asyncio.Future[Any]") -> None:
34
+ if not wait_next.done():
35
+ wait_next.set_result(fut)
36
+
37
+ for f in futures:
38
+ f.add_done_callback(_on_completion)
39
+
40
+ try:
41
+ return await wait_next
42
+ finally:
43
+ for f in futures:
44
+ f.remove_done_callback(_on_completion)
45
+
46
+
47
+ async def staggered_race(
48
+ coro_fns: Iterable[Callable[[], Awaitable[_T]]],
49
+ delay: Optional[float],
50
+ *,
51
+ loop: Optional[asyncio.AbstractEventLoop] = None,
52
+ ) -> Tuple[Optional[_T], Optional[int], List[Optional[BaseException]]]:
53
+ """
54
+ Run coroutines with staggered start times and take the first to finish.
55
+
56
+ This method takes an iterable of coroutine functions. The first one is
57
+ started immediately. From then on, whenever the immediately preceding one
58
+ fails (raises an exception), or when *delay* seconds has passed, the next
59
+ coroutine is started. This continues until one of the coroutines complete
60
+ successfully, in which case all others are cancelled, or until all
61
+ coroutines fail.
62
+
63
+ The coroutines provided should be well-behaved in the following way:
64
+
65
+ * They should only ``return`` if completed successfully.
66
+
67
+ * They should always raise an exception if they did not complete
68
+ successfully. In particular, if they handle cancellation, they should
69
+ probably reraise, like this::
70
+
71
+ try:
72
+ # do work
73
+ except asyncio.CancelledError:
74
+ # undo partially completed work
75
+ raise
76
+
77
+ Args:
78
+ ----
79
+ coro_fns: an iterable of coroutine functions, i.e. callables that
80
+ return a coroutine object when called. Use ``functools.partial`` or
81
+ lambdas to pass arguments.
82
+
83
+ delay: amount of time, in seconds, between starting coroutines. If
84
+ ``None``, the coroutines will run sequentially.
85
+
86
+ loop: the event loop to use. If ``None``, the running loop is used.
87
+
88
+ Returns:
89
+ -------
90
+ tuple *(winner_result, winner_index, exceptions)* where
91
+
92
+ - *winner_result*: the result of the winning coroutine, or ``None``
93
+ if no coroutines won.
94
+
95
+ - *winner_index*: the index of the winning coroutine in
96
+ ``coro_fns``, or ``None`` if no coroutines won. If the winning
97
+ coroutine may return None on success, *winner_index* can be used
98
+ to definitively determine whether any coroutine won.
99
+
100
+ - *exceptions*: list of exceptions returned by the coroutines.
101
+ ``len(exceptions)`` is equal to the number of coroutines actually
102
+ started, and the order is the same as in ``coro_fns``. The winning
103
+ coroutine's entry is ``None``.
104
+
105
+ """
106
+ loop = loop or asyncio.get_running_loop()
107
+ exceptions: List[Optional[BaseException]] = []
108
+ tasks: Set[asyncio.Task[Optional[Tuple[_T, int]]]] = set()
109
+
110
+ async def run_one_coro(
111
+ coro_fn: Callable[[], Awaitable[_T]],
112
+ this_index: int,
113
+ start_next: "asyncio.Future[None]",
114
+ ) -> Optional[Tuple[_T, int]]:
115
+ """
116
+ Run a single coroutine.
117
+
118
+ If the coroutine fails, set the exception in the exceptions list and
119
+ start the next coroutine by setting the result of the start_next.
120
+
121
+ If the coroutine succeeds, return the result and the index of the
122
+ coroutine in the coro_fns list.
123
+
124
+ If SystemExit or KeyboardInterrupt is raised, re-raise it.
125
+ """
126
+ try:
127
+ result = await coro_fn()
128
+ except (SystemExit, KeyboardInterrupt):
129
+ raise
130
+ except BaseException as e:
131
+ exceptions[this_index] = e
132
+ _set_result(start_next) # Kickstart the next coroutine
133
+ return None
134
+
135
+ return result, this_index
136
+
137
+ start_next_timer: Optional[asyncio.TimerHandle] = None
138
+ start_next: Optional[asyncio.Future[None]]
139
+ task: asyncio.Task[Optional[Tuple[_T, int]]]
140
+ done: Union[asyncio.Future[None], asyncio.Task[Optional[Tuple[_T, int]]]]
141
+ coro_iter = iter(coro_fns)
142
+ this_index = -1
143
+ try:
144
+ while True:
145
+ if coro_fn := next(coro_iter, None):
146
+ this_index += 1
147
+ exceptions.append(None)
148
+ start_next = loop.create_future()
149
+ task = loop.create_task(run_one_coro(coro_fn, this_index, start_next))
150
+ tasks.add(task)
151
+ start_next_timer = (
152
+ loop.call_later(delay, _set_result, start_next) if delay else None
153
+ )
154
+ elif not tasks:
155
+ # We exhausted the coro_fns list and no tasks are running
156
+ # so we have no winner and all coroutines failed.
157
+ break
158
+
159
+ while tasks:
160
+ done = await _wait_one(
161
+ [*tasks, start_next] if start_next else tasks, loop
162
+ )
163
+ if done is start_next:
164
+ # The current task has failed or the timer has expired
165
+ # so we need to start the next task.
166
+ start_next = None
167
+ if start_next_timer:
168
+ start_next_timer.cancel()
169
+ start_next_timer = None
170
+
171
+ # Break out of the task waiting loop to start the next
172
+ # task.
173
+ break
174
+
175
+ if TYPE_CHECKING:
176
+ assert isinstance(done, asyncio.Task)
177
+
178
+ tasks.remove(done)
179
+ if winner := done.result():
180
+ return *winner, exceptions
181
+ finally:
182
+ # We either have:
183
+ # - a winner
184
+ # - all tasks failed
185
+ # - a KeyboardInterrupt or SystemExit.
186
+
187
+ #
188
+ # If the timer is still running, cancel it.
189
+ #
190
+ if start_next_timer:
191
+ start_next_timer.cancel()
192
+
193
+ #
194
+ # If there are any tasks left, cancel them and than
195
+ # wait them so they fill the exceptions list.
196
+ #
197
+ for task in tasks:
198
+ task.cancel()
199
+ with contextlib.suppress(asyncio.CancelledError):
200
+ await task
201
+
202
+ return None, None, exceptions
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/impl.py ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Base implementation."""
2
+
3
+ import asyncio
4
+ import collections
5
+ import functools
6
+ import itertools
7
+ import socket
8
+ import sys
9
+ from typing import List, Optional, Sequence, Union
10
+
11
+ from . import _staggered
12
+ from .types import AddrInfoType
13
+
14
+ if sys.version_info < (3, 8, 2): # noqa: UP036
15
+ # asyncio.staggered is broken in Python 3.8.0 and 3.8.1
16
+ # so it must be patched:
17
+ # https://github.com/aio-libs/aiohttp/issues/8556
18
+ # https://bugs.python.org/issue39129
19
+ # https://github.com/python/cpython/pull/17693
20
+ import asyncio.futures
21
+
22
+ asyncio.futures.TimeoutError = asyncio.TimeoutError # type: ignore[attr-defined]
23
+
24
+
25
+ async def start_connection(
26
+ addr_infos: Sequence[AddrInfoType],
27
+ *,
28
+ local_addr_infos: Optional[Sequence[AddrInfoType]] = None,
29
+ happy_eyeballs_delay: Optional[float] = None,
30
+ interleave: Optional[int] = None,
31
+ loop: Optional[asyncio.AbstractEventLoop] = None,
32
+ ) -> socket.socket:
33
+ """
34
+ Connect to a TCP server.
35
+
36
+ Create a socket connection to a specified destination. The
37
+ destination is specified as a list of AddrInfoType tuples as
38
+ returned from getaddrinfo().
39
+
40
+ The arguments are, in order:
41
+
42
+ * ``family``: the address family, e.g. ``socket.AF_INET`` or
43
+ ``socket.AF_INET6``.
44
+ * ``type``: the socket type, e.g. ``socket.SOCK_STREAM`` or
45
+ ``socket.SOCK_DGRAM``.
46
+ * ``proto``: the protocol, e.g. ``socket.IPPROTO_TCP`` or
47
+ ``socket.IPPROTO_UDP``.
48
+ * ``canonname``: the canonical name of the address, e.g.
49
+ ``"www.python.org"``.
50
+ * ``sockaddr``: the socket address
51
+
52
+ This method is a coroutine which will try to establish the connection
53
+ in the background. When successful, the coroutine returns a
54
+ socket.
55
+
56
+ The expected use case is to use this method in conjunction with
57
+ loop.create_connection() to establish a connection to a server::
58
+
59
+ socket = await start_connection(addr_infos)
60
+ transport, protocol = await loop.create_connection(
61
+ MyProtocol, sock=socket, ...)
62
+ """
63
+ if not (current_loop := loop):
64
+ current_loop = asyncio.get_running_loop()
65
+
66
+ single_addr_info = len(addr_infos) == 1
67
+
68
+ if happy_eyeballs_delay is not None and interleave is None:
69
+ # If using happy eyeballs, default to interleave addresses by family
70
+ interleave = 1
71
+
72
+ if interleave and not single_addr_info:
73
+ addr_infos = _interleave_addrinfos(addr_infos, interleave)
74
+
75
+ sock: Optional[socket.socket] = None
76
+ # uvloop can raise RuntimeError instead of OSError
77
+ exceptions: List[List[Union[OSError, RuntimeError]]] = []
78
+ if happy_eyeballs_delay is None or single_addr_info:
79
+ # not using happy eyeballs
80
+ for addrinfo in addr_infos:
81
+ try:
82
+ sock = await _connect_sock(
83
+ current_loop, exceptions, addrinfo, local_addr_infos
84
+ )
85
+ break
86
+ except (RuntimeError, OSError):
87
+ continue
88
+ else: # using happy eyeballs
89
+ sock, _, _ = await _staggered.staggered_race(
90
+ (
91
+ functools.partial(
92
+ _connect_sock, current_loop, exceptions, addrinfo, local_addr_infos
93
+ )
94
+ for addrinfo in addr_infos
95
+ ),
96
+ happy_eyeballs_delay,
97
+ )
98
+
99
+ if sock is None:
100
+ all_exceptions = [exc for sub in exceptions for exc in sub]
101
+ try:
102
+ first_exception = all_exceptions[0]
103
+ if len(all_exceptions) == 1:
104
+ raise first_exception
105
+ else:
106
+ # If they all have the same str(), raise one.
107
+ model = str(first_exception)
108
+ if all(str(exc) == model for exc in all_exceptions):
109
+ raise first_exception
110
+ # Raise a combined exception so the user can see all
111
+ # the various error messages.
112
+ msg = "Multiple exceptions: {}".format(
113
+ ", ".join(str(exc) for exc in all_exceptions)
114
+ )
115
+ # If the errno is the same for all exceptions, raise
116
+ # an OSError with that errno.
117
+ if isinstance(first_exception, OSError):
118
+ first_errno = first_exception.errno
119
+ if all(
120
+ isinstance(exc, OSError) and exc.errno == first_errno
121
+ for exc in all_exceptions
122
+ ):
123
+ raise OSError(first_errno, msg)
124
+ elif isinstance(first_exception, RuntimeError) and all(
125
+ isinstance(exc, RuntimeError) for exc in all_exceptions
126
+ ):
127
+ raise RuntimeError(msg)
128
+ # We have a mix of OSError and RuntimeError
129
+ # so we have to pick which one to raise.
130
+ # and we raise OSError for compatibility
131
+ raise OSError(msg)
132
+ finally:
133
+ all_exceptions = None # type: ignore[assignment]
134
+ exceptions = None # type: ignore[assignment]
135
+
136
+ return sock
137
+
138
+
139
+ async def _connect_sock(
140
+ loop: asyncio.AbstractEventLoop,
141
+ exceptions: List[List[Union[OSError, RuntimeError]]],
142
+ addr_info: AddrInfoType,
143
+ local_addr_infos: Optional[Sequence[AddrInfoType]] = None,
144
+ ) -> socket.socket:
145
+ """Create, bind and connect one socket."""
146
+ my_exceptions: List[Union[OSError, RuntimeError]] = []
147
+ exceptions.append(my_exceptions)
148
+ family, type_, proto, _, address = addr_info
149
+ sock = None
150
+ try:
151
+ sock = socket.socket(family=family, type=type_, proto=proto)
152
+ sock.setblocking(False)
153
+ if local_addr_infos is not None:
154
+ for lfamily, _, _, _, laddr in local_addr_infos:
155
+ # skip local addresses of different family
156
+ if lfamily != family:
157
+ continue
158
+ try:
159
+ sock.bind(laddr)
160
+ break
161
+ except OSError as exc:
162
+ msg = (
163
+ f"error while attempting to bind on "
164
+ f"address {laddr!r}: "
165
+ f"{exc.strerror.lower()}"
166
+ )
167
+ exc = OSError(exc.errno, msg)
168
+ my_exceptions.append(exc)
169
+ else: # all bind attempts failed
170
+ if my_exceptions:
171
+ raise my_exceptions.pop()
172
+ else:
173
+ raise OSError(f"no matching local address with {family=} found")
174
+ await loop.sock_connect(sock, address)
175
+ return sock
176
+ except (RuntimeError, OSError) as exc:
177
+ my_exceptions.append(exc)
178
+ if sock is not None:
179
+ try:
180
+ sock.close()
181
+ except OSError as e:
182
+ my_exceptions.append(e)
183
+ raise
184
+ raise
185
+ except:
186
+ if sock is not None:
187
+ try:
188
+ sock.close()
189
+ except OSError as e:
190
+ my_exceptions.append(e)
191
+ raise
192
+ raise
193
+ finally:
194
+ exceptions = my_exceptions = None # type: ignore[assignment]
195
+
196
+
197
+ def _interleave_addrinfos(
198
+ addrinfos: Sequence[AddrInfoType], first_address_family_count: int = 1
199
+ ) -> List[AddrInfoType]:
200
+ """Interleave list of addrinfo tuples by family."""
201
+ # Group addresses by family
202
+ addrinfos_by_family: collections.OrderedDict[int, List[AddrInfoType]] = (
203
+ collections.OrderedDict()
204
+ )
205
+ for addr in addrinfos:
206
+ family = addr[0]
207
+ if family not in addrinfos_by_family:
208
+ addrinfos_by_family[family] = []
209
+ addrinfos_by_family[family].append(addr)
210
+ addrinfos_lists = list(addrinfos_by_family.values())
211
+
212
+ reordered: List[AddrInfoType] = []
213
+ if first_address_family_count > 1:
214
+ reordered.extend(addrinfos_lists[0][: first_address_family_count - 1])
215
+ del addrinfos_lists[0][: first_address_family_count - 1]
216
+ reordered.extend(
217
+ a
218
+ for a in itertools.chain.from_iterable(itertools.zip_longest(*addrinfos_lists))
219
+ if a is not None
220
+ )
221
+ return reordered
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/py.typed ADDED
File without changes
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/types.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Types for aiohappyeyeballs."""
2
+
3
+ import socket
4
+ from typing import Tuple, Union
5
+
6
+ AddrInfoType = Tuple[
7
+ Union[int, socket.AddressFamily],
8
+ Union[int, socket.SocketKind],
9
+ int,
10
+ str,
11
+ Tuple, # type: ignore[type-arg]
12
+ ]
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiohappyeyeballs/utils.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Utility functions for aiohappyeyeballs."""
2
+
3
+ import ipaddress
4
+ import socket
5
+ from typing import Dict, List, Optional, Tuple, Union
6
+
7
+ from .types import AddrInfoType
8
+
9
+
10
+ def addr_to_addr_infos(
11
+ addr: Optional[
12
+ Union[Tuple[str, int, int, int], Tuple[str, int, int], Tuple[str, int]]
13
+ ],
14
+ ) -> Optional[List[AddrInfoType]]:
15
+ """Convert an address tuple to a list of addr_info tuples."""
16
+ if addr is None:
17
+ return None
18
+ host = addr[0]
19
+ port = addr[1]
20
+ is_ipv6 = ":" in host
21
+ if is_ipv6:
22
+ flowinfo = 0
23
+ scopeid = 0
24
+ addr_len = len(addr)
25
+ if addr_len >= 4:
26
+ scopeid = addr[3] # type: ignore[misc]
27
+ if addr_len >= 3:
28
+ flowinfo = addr[2] # type: ignore[misc]
29
+ addr = (host, port, flowinfo, scopeid)
30
+ family = socket.AF_INET6
31
+ else:
32
+ addr = (host, port)
33
+ family = socket.AF_INET
34
+ return [(family, socket.SOCK_STREAM, socket.IPPROTO_TCP, "", addr)]
35
+
36
+
37
+ def pop_addr_infos_interleave(
38
+ addr_infos: List[AddrInfoType], interleave: Optional[int] = None
39
+ ) -> None:
40
+ """
41
+ Pop addr_info from the list of addr_infos by family up to interleave times.
42
+
43
+ The interleave parameter is used to know how many addr_infos for
44
+ each family should be popped of the top of the list.
45
+ """
46
+ seen: Dict[int, int] = {}
47
+ if interleave is None:
48
+ interleave = 1
49
+ to_remove: List[AddrInfoType] = []
50
+ for addr_info in addr_infos:
51
+ family = addr_info[0]
52
+ if family not in seen:
53
+ seen[family] = 0
54
+ if seen[family] < interleave:
55
+ to_remove.append(addr_info)
56
+ seen[family] += 1
57
+ for addr_info in to_remove:
58
+ addr_infos.remove(addr_info)
59
+
60
+
61
+ def _addr_tuple_to_ip_address(
62
+ addr: Union[Tuple[str, int], Tuple[str, int, int, int]],
63
+ ) -> Union[
64
+ Tuple[ipaddress.IPv4Address, int], Tuple[ipaddress.IPv6Address, int, int, int]
65
+ ]:
66
+ """Convert an address tuple to an IPv4Address."""
67
+ return (ipaddress.ip_address(addr[0]), *addr[1:])
68
+
69
+
70
+ def remove_addr_infos(
71
+ addr_infos: List[AddrInfoType],
72
+ addr: Union[Tuple[str, int], Tuple[str, int, int, int]],
73
+ ) -> None:
74
+ """
75
+ Remove an address from the list of addr_infos.
76
+
77
+ The addr value is typically the return value of
78
+ sock.getpeername().
79
+ """
80
+ bad_addrs_infos: List[AddrInfoType] = []
81
+ for addr_info in addr_infos:
82
+ if addr_info[-1] == addr:
83
+ bad_addrs_infos.append(addr_info)
84
+ if bad_addrs_infos:
85
+ for bad_addr_info in bad_addrs_infos:
86
+ addr_infos.remove(bad_addr_info)
87
+ return
88
+ # Slow path in case addr is formatted differently
89
+ match_addr = _addr_tuple_to_ip_address(addr)
90
+ for addr_info in addr_infos:
91
+ if match_addr == _addr_tuple_to_ip_address(addr_info[-1]):
92
+ bad_addrs_infos.append(addr_info)
93
+ if bad_addrs_infos:
94
+ for bad_addr_info in bad_addrs_infos:
95
+ addr_infos.remove(bad_addr_info)
96
+ return
97
+ raise ValueError(f"Address {addr} not found in addr_infos")
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/aiosignal/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (1.9 kB). View file
 
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/__init__.pyi ADDED
@@ -0,0 +1,389 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import enum
2
+ import sys
3
+
4
+ from typing import (
5
+ Any,
6
+ Callable,
7
+ Generic,
8
+ Literal,
9
+ Mapping,
10
+ Protocol,
11
+ Sequence,
12
+ TypeVar,
13
+ overload,
14
+ )
15
+
16
+ # `import X as X` is required to make these public
17
+ from . import converters as converters
18
+ from . import exceptions as exceptions
19
+ from . import filters as filters
20
+ from . import setters as setters
21
+ from . import validators as validators
22
+ from ._cmp import cmp_using as cmp_using
23
+ from ._typing_compat import AttrsInstance_
24
+ from ._version_info import VersionInfo
25
+ from attrs import (
26
+ define as define,
27
+ field as field,
28
+ mutable as mutable,
29
+ frozen as frozen,
30
+ _EqOrderType,
31
+ _ValidatorType,
32
+ _ConverterType,
33
+ _ReprArgType,
34
+ _OnSetAttrType,
35
+ _OnSetAttrArgType,
36
+ _FieldTransformer,
37
+ _ValidatorArgType,
38
+ )
39
+
40
+ if sys.version_info >= (3, 10):
41
+ from typing import TypeGuard, TypeAlias
42
+ else:
43
+ from typing_extensions import TypeGuard, TypeAlias
44
+
45
+ if sys.version_info >= (3, 11):
46
+ from typing import dataclass_transform
47
+ else:
48
+ from typing_extensions import dataclass_transform
49
+
50
+ __version__: str
51
+ __version_info__: VersionInfo
52
+ __title__: str
53
+ __description__: str
54
+ __url__: str
55
+ __uri__: str
56
+ __author__: str
57
+ __email__: str
58
+ __license__: str
59
+ __copyright__: str
60
+
61
+ _T = TypeVar("_T")
62
+ _C = TypeVar("_C", bound=type)
63
+
64
+ _FilterType = Callable[["Attribute[_T]", _T], bool]
65
+
66
+ # We subclass this here to keep the protocol's qualified name clean.
67
+ class AttrsInstance(AttrsInstance_, Protocol):
68
+ pass
69
+
70
+ _A = TypeVar("_A", bound=type[AttrsInstance])
71
+
72
+ class _Nothing(enum.Enum):
73
+ NOTHING = enum.auto()
74
+
75
+ NOTHING = _Nothing.NOTHING
76
+ NothingType: TypeAlias = Literal[_Nothing.NOTHING]
77
+
78
+ # NOTE: Factory lies about its return type to make this possible:
79
+ # `x: List[int] # = Factory(list)`
80
+ # Work around mypy issue #4554 in the common case by using an overload.
81
+
82
+ @overload
83
+ def Factory(factory: Callable[[], _T]) -> _T: ...
84
+ @overload
85
+ def Factory(
86
+ factory: Callable[[Any], _T],
87
+ takes_self: Literal[True],
88
+ ) -> _T: ...
89
+ @overload
90
+ def Factory(
91
+ factory: Callable[[], _T],
92
+ takes_self: Literal[False],
93
+ ) -> _T: ...
94
+
95
+ In = TypeVar("In")
96
+ Out = TypeVar("Out")
97
+
98
+ class Converter(Generic[In, Out]):
99
+ @overload
100
+ def __init__(self, converter: Callable[[In], Out]) -> None: ...
101
+ @overload
102
+ def __init__(
103
+ self,
104
+ converter: Callable[[In, AttrsInstance, Attribute], Out],
105
+ *,
106
+ takes_self: Literal[True],
107
+ takes_field: Literal[True],
108
+ ) -> None: ...
109
+ @overload
110
+ def __init__(
111
+ self,
112
+ converter: Callable[[In, Attribute], Out],
113
+ *,
114
+ takes_field: Literal[True],
115
+ ) -> None: ...
116
+ @overload
117
+ def __init__(
118
+ self,
119
+ converter: Callable[[In, AttrsInstance], Out],
120
+ *,
121
+ takes_self: Literal[True],
122
+ ) -> None: ...
123
+
124
+ class Attribute(Generic[_T]):
125
+ name: str
126
+ default: _T | None
127
+ validator: _ValidatorType[_T] | None
128
+ repr: _ReprArgType
129
+ cmp: _EqOrderType
130
+ eq: _EqOrderType
131
+ order: _EqOrderType
132
+ hash: bool | None
133
+ init: bool
134
+ converter: Converter | None
135
+ metadata: dict[Any, Any]
136
+ type: type[_T] | None
137
+ kw_only: bool
138
+ on_setattr: _OnSetAttrType
139
+ alias: str | None
140
+
141
+ def evolve(self, **changes: Any) -> "Attribute[Any]": ...
142
+
143
+ # NOTE: We had several choices for the annotation to use for type arg:
144
+ # 1) Type[_T]
145
+ # - Pros: Handles simple cases correctly
146
+ # - Cons: Might produce less informative errors in the case of conflicting
147
+ # TypeVars e.g. `attr.ib(default='bad', type=int)`
148
+ # 2) Callable[..., _T]
149
+ # - Pros: Better error messages than #1 for conflicting TypeVars
150
+ # - Cons: Terrible error messages for validator checks.
151
+ # e.g. attr.ib(type=int, validator=validate_str)
152
+ # -> error: Cannot infer function type argument
153
+ # 3) type (and do all of the work in the mypy plugin)
154
+ # - Pros: Simple here, and we could customize the plugin with our own errors.
155
+ # - Cons: Would need to write mypy plugin code to handle all the cases.
156
+ # We chose option #1.
157
+
158
+ # `attr` lies about its return type to make the following possible:
159
+ # attr() -> Any
160
+ # attr(8) -> int
161
+ # attr(validator=<some callable>) -> Whatever the callable expects.
162
+ # This makes this type of assignments possible:
163
+ # x: int = attr(8)
164
+ #
165
+ # This form catches explicit None or no default but with no other arguments
166
+ # returns Any.
167
+ @overload
168
+ def attrib(
169
+ default: None = ...,
170
+ validator: None = ...,
171
+ repr: _ReprArgType = ...,
172
+ cmp: _EqOrderType | None = ...,
173
+ hash: bool | None = ...,
174
+ init: bool = ...,
175
+ metadata: Mapping[Any, Any] | None = ...,
176
+ type: None = ...,
177
+ converter: None = ...,
178
+ factory: None = ...,
179
+ kw_only: bool = ...,
180
+ eq: _EqOrderType | None = ...,
181
+ order: _EqOrderType | None = ...,
182
+ on_setattr: _OnSetAttrArgType | None = ...,
183
+ alias: str | None = ...,
184
+ ) -> Any: ...
185
+
186
+ # This form catches an explicit None or no default and infers the type from the
187
+ # other arguments.
188
+ @overload
189
+ def attrib(
190
+ default: None = ...,
191
+ validator: _ValidatorArgType[_T] | None = ...,
192
+ repr: _ReprArgType = ...,
193
+ cmp: _EqOrderType | None = ...,
194
+ hash: bool | None = ...,
195
+ init: bool = ...,
196
+ metadata: Mapping[Any, Any] | None = ...,
197
+ type: type[_T] | None = ...,
198
+ converter: _ConverterType
199
+ | list[_ConverterType]
200
+ | tuple[_ConverterType]
201
+ | None = ...,
202
+ factory: Callable[[], _T] | None = ...,
203
+ kw_only: bool = ...,
204
+ eq: _EqOrderType | None = ...,
205
+ order: _EqOrderType | None = ...,
206
+ on_setattr: _OnSetAttrArgType | None = ...,
207
+ alias: str | None = ...,
208
+ ) -> _T: ...
209
+
210
+ # This form catches an explicit default argument.
211
+ @overload
212
+ def attrib(
213
+ default: _T,
214
+ validator: _ValidatorArgType[_T] | None = ...,
215
+ repr: _ReprArgType = ...,
216
+ cmp: _EqOrderType | None = ...,
217
+ hash: bool | None = ...,
218
+ init: bool = ...,
219
+ metadata: Mapping[Any, Any] | None = ...,
220
+ type: type[_T] | None = ...,
221
+ converter: _ConverterType
222
+ | list[_ConverterType]
223
+ | tuple[_ConverterType]
224
+ | None = ...,
225
+ factory: Callable[[], _T] | None = ...,
226
+ kw_only: bool = ...,
227
+ eq: _EqOrderType | None = ...,
228
+ order: _EqOrderType | None = ...,
229
+ on_setattr: _OnSetAttrArgType | None = ...,
230
+ alias: str | None = ...,
231
+ ) -> _T: ...
232
+
233
+ # This form covers type=non-Type: e.g. forward references (str), Any
234
+ @overload
235
+ def attrib(
236
+ default: _T | None = ...,
237
+ validator: _ValidatorArgType[_T] | None = ...,
238
+ repr: _ReprArgType = ...,
239
+ cmp: _EqOrderType | None = ...,
240
+ hash: bool | None = ...,
241
+ init: bool = ...,
242
+ metadata: Mapping[Any, Any] | None = ...,
243
+ type: object = ...,
244
+ converter: _ConverterType
245
+ | list[_ConverterType]
246
+ | tuple[_ConverterType]
247
+ | None = ...,
248
+ factory: Callable[[], _T] | None = ...,
249
+ kw_only: bool = ...,
250
+ eq: _EqOrderType | None = ...,
251
+ order: _EqOrderType | None = ...,
252
+ on_setattr: _OnSetAttrArgType | None = ...,
253
+ alias: str | None = ...,
254
+ ) -> Any: ...
255
+ @overload
256
+ @dataclass_transform(order_default=True, field_specifiers=(attrib, field))
257
+ def attrs(
258
+ maybe_cls: _C,
259
+ these: dict[str, Any] | None = ...,
260
+ repr_ns: str | None = ...,
261
+ repr: bool = ...,
262
+ cmp: _EqOrderType | None = ...,
263
+ hash: bool | None = ...,
264
+ init: bool = ...,
265
+ slots: bool = ...,
266
+ frozen: bool = ...,
267
+ weakref_slot: bool = ...,
268
+ str: bool = ...,
269
+ auto_attribs: bool = ...,
270
+ kw_only: bool = ...,
271
+ cache_hash: bool = ...,
272
+ auto_exc: bool = ...,
273
+ eq: _EqOrderType | None = ...,
274
+ order: _EqOrderType | None = ...,
275
+ auto_detect: bool = ...,
276
+ collect_by_mro: bool = ...,
277
+ getstate_setstate: bool | None = ...,
278
+ on_setattr: _OnSetAttrArgType | None = ...,
279
+ field_transformer: _FieldTransformer | None = ...,
280
+ match_args: bool = ...,
281
+ unsafe_hash: bool | None = ...,
282
+ ) -> _C: ...
283
+ @overload
284
+ @dataclass_transform(order_default=True, field_specifiers=(attrib, field))
285
+ def attrs(
286
+ maybe_cls: None = ...,
287
+ these: dict[str, Any] | None = ...,
288
+ repr_ns: str | None = ...,
289
+ repr: bool = ...,
290
+ cmp: _EqOrderType | None = ...,
291
+ hash: bool | None = ...,
292
+ init: bool = ...,
293
+ slots: bool = ...,
294
+ frozen: bool = ...,
295
+ weakref_slot: bool = ...,
296
+ str: bool = ...,
297
+ auto_attribs: bool = ...,
298
+ kw_only: bool = ...,
299
+ cache_hash: bool = ...,
300
+ auto_exc: bool = ...,
301
+ eq: _EqOrderType | None = ...,
302
+ order: _EqOrderType | None = ...,
303
+ auto_detect: bool = ...,
304
+ collect_by_mro: bool = ...,
305
+ getstate_setstate: bool | None = ...,
306
+ on_setattr: _OnSetAttrArgType | None = ...,
307
+ field_transformer: _FieldTransformer | None = ...,
308
+ match_args: bool = ...,
309
+ unsafe_hash: bool | None = ...,
310
+ ) -> Callable[[_C], _C]: ...
311
+ def fields(cls: type[AttrsInstance]) -> Any: ...
312
+ def fields_dict(cls: type[AttrsInstance]) -> dict[str, Attribute[Any]]: ...
313
+ def validate(inst: AttrsInstance) -> None: ...
314
+ def resolve_types(
315
+ cls: _A,
316
+ globalns: dict[str, Any] | None = ...,
317
+ localns: dict[str, Any] | None = ...,
318
+ attribs: list[Attribute[Any]] | None = ...,
319
+ include_extras: bool = ...,
320
+ ) -> _A: ...
321
+
322
+ # TODO: add support for returning a proper attrs class from the mypy plugin
323
+ # we use Any instead of _CountingAttr so that e.g. `make_class('Foo',
324
+ # [attr.ib()])` is valid
325
+ def make_class(
326
+ name: str,
327
+ attrs: list[str] | tuple[str, ...] | dict[str, Any],
328
+ bases: tuple[type, ...] = ...,
329
+ class_body: dict[str, Any] | None = ...,
330
+ repr_ns: str | None = ...,
331
+ repr: bool = ...,
332
+ cmp: _EqOrderType | None = ...,
333
+ hash: bool | None = ...,
334
+ init: bool = ...,
335
+ slots: bool = ...,
336
+ frozen: bool = ...,
337
+ weakref_slot: bool = ...,
338
+ str: bool = ...,
339
+ auto_attribs: bool = ...,
340
+ kw_only: bool = ...,
341
+ cache_hash: bool = ...,
342
+ auto_exc: bool = ...,
343
+ eq: _EqOrderType | None = ...,
344
+ order: _EqOrderType | None = ...,
345
+ collect_by_mro: bool = ...,
346
+ on_setattr: _OnSetAttrArgType | None = ...,
347
+ field_transformer: _FieldTransformer | None = ...,
348
+ ) -> type: ...
349
+
350
+ # _funcs --
351
+
352
+ # TODO: add support for returning TypedDict from the mypy plugin
353
+ # FIXME: asdict/astuple do not honor their factory args. Waiting on one of
354
+ # these:
355
+ # https://github.com/python/mypy/issues/4236
356
+ # https://github.com/python/typing/issues/253
357
+ # XXX: remember to fix attrs.asdict/astuple too!
358
+ def asdict(
359
+ inst: AttrsInstance,
360
+ recurse: bool = ...,
361
+ filter: _FilterType[Any] | None = ...,
362
+ dict_factory: type[Mapping[Any, Any]] = ...,
363
+ retain_collection_types: bool = ...,
364
+ value_serializer: Callable[[type, Attribute[Any], Any], Any] | None = ...,
365
+ tuple_keys: bool | None = ...,
366
+ ) -> dict[str, Any]: ...
367
+
368
+ # TODO: add support for returning NamedTuple from the mypy plugin
369
+ def astuple(
370
+ inst: AttrsInstance,
371
+ recurse: bool = ...,
372
+ filter: _FilterType[Any] | None = ...,
373
+ tuple_factory: type[Sequence[Any]] = ...,
374
+ retain_collection_types: bool = ...,
375
+ ) -> tuple[Any, ...]: ...
376
+ def has(cls: type) -> TypeGuard[type[AttrsInstance]]: ...
377
+ def assoc(inst: _T, **changes: Any) -> _T: ...
378
+ def evolve(inst: _T, **changes: Any) -> _T: ...
379
+
380
+ # _config --
381
+
382
+ def set_run_validators(run: bool) -> None: ...
383
+ def get_run_validators() -> bool: ...
384
+
385
+ # aliases --
386
+
387
+ s = attributes = attrs
388
+ ib = attr = attrib
389
+ dataclass = attrs # Technically, partial(attrs, auto_attribs=True) ;)
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/_cmp.py ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+
4
+ import functools
5
+ import types
6
+
7
+ from ._make import _make_ne
8
+
9
+
10
+ _operation_names = {"eq": "==", "lt": "<", "le": "<=", "gt": ">", "ge": ">="}
11
+
12
+
13
+ def cmp_using(
14
+ eq=None,
15
+ lt=None,
16
+ le=None,
17
+ gt=None,
18
+ ge=None,
19
+ require_same_type=True,
20
+ class_name="Comparable",
21
+ ):
22
+ """
23
+ Create a class that can be passed into `attrs.field`'s ``eq``, ``order``,
24
+ and ``cmp`` arguments to customize field comparison.
25
+
26
+ The resulting class will have a full set of ordering methods if at least
27
+ one of ``{lt, le, gt, ge}`` and ``eq`` are provided.
28
+
29
+ Args:
30
+ eq (typing.Callable | None):
31
+ Callable used to evaluate equality of two objects.
32
+
33
+ lt (typing.Callable | None):
34
+ Callable used to evaluate whether one object is less than another
35
+ object.
36
+
37
+ le (typing.Callable | None):
38
+ Callable used to evaluate whether one object is less than or equal
39
+ to another object.
40
+
41
+ gt (typing.Callable | None):
42
+ Callable used to evaluate whether one object is greater than
43
+ another object.
44
+
45
+ ge (typing.Callable | None):
46
+ Callable used to evaluate whether one object is greater than or
47
+ equal to another object.
48
+
49
+ require_same_type (bool):
50
+ When `True`, equality and ordering methods will return
51
+ `NotImplemented` if objects are not of the same type.
52
+
53
+ class_name (str | None): Name of class. Defaults to "Comparable".
54
+
55
+ See `comparison` for more details.
56
+
57
+ .. versionadded:: 21.1.0
58
+ """
59
+
60
+ body = {
61
+ "__slots__": ["value"],
62
+ "__init__": _make_init(),
63
+ "_requirements": [],
64
+ "_is_comparable_to": _is_comparable_to,
65
+ }
66
+
67
+ # Add operations.
68
+ num_order_functions = 0
69
+ has_eq_function = False
70
+
71
+ if eq is not None:
72
+ has_eq_function = True
73
+ body["__eq__"] = _make_operator("eq", eq)
74
+ body["__ne__"] = _make_ne()
75
+
76
+ if lt is not None:
77
+ num_order_functions += 1
78
+ body["__lt__"] = _make_operator("lt", lt)
79
+
80
+ if le is not None:
81
+ num_order_functions += 1
82
+ body["__le__"] = _make_operator("le", le)
83
+
84
+ if gt is not None:
85
+ num_order_functions += 1
86
+ body["__gt__"] = _make_operator("gt", gt)
87
+
88
+ if ge is not None:
89
+ num_order_functions += 1
90
+ body["__ge__"] = _make_operator("ge", ge)
91
+
92
+ type_ = types.new_class(
93
+ class_name, (object,), {}, lambda ns: ns.update(body)
94
+ )
95
+
96
+ # Add same type requirement.
97
+ if require_same_type:
98
+ type_._requirements.append(_check_same_type)
99
+
100
+ # Add total ordering if at least one operation was defined.
101
+ if 0 < num_order_functions < 4:
102
+ if not has_eq_function:
103
+ # functools.total_ordering requires __eq__ to be defined,
104
+ # so raise early error here to keep a nice stack.
105
+ msg = "eq must be define is order to complete ordering from lt, le, gt, ge."
106
+ raise ValueError(msg)
107
+ type_ = functools.total_ordering(type_)
108
+
109
+ return type_
110
+
111
+
112
+ def _make_init():
113
+ """
114
+ Create __init__ method.
115
+ """
116
+
117
+ def __init__(self, value):
118
+ """
119
+ Initialize object with *value*.
120
+ """
121
+ self.value = value
122
+
123
+ return __init__
124
+
125
+
126
+ def _make_operator(name, func):
127
+ """
128
+ Create operator method.
129
+ """
130
+
131
+ def method(self, other):
132
+ if not self._is_comparable_to(other):
133
+ return NotImplemented
134
+
135
+ result = func(self.value, other.value)
136
+ if result is NotImplemented:
137
+ return NotImplemented
138
+
139
+ return result
140
+
141
+ method.__name__ = f"__{name}__"
142
+ method.__doc__ = (
143
+ f"Return a {_operation_names[name]} b. Computed by attrs."
144
+ )
145
+
146
+ return method
147
+
148
+
149
+ def _is_comparable_to(self, other):
150
+ """
151
+ Check whether `other` is comparable to `self`.
152
+ """
153
+ return all(func(self, other) for func in self._requirements)
154
+
155
+
156
+ def _check_same_type(self, other):
157
+ """
158
+ Return True if *self* and *other* are of the same type, False otherwise.
159
+ """
160
+ return other.value.__class__ is self.value.__class__
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/_cmp.pyi ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Callable
2
+
3
+ _CompareWithType = Callable[[Any, Any], bool]
4
+
5
+ def cmp_using(
6
+ eq: _CompareWithType | None = ...,
7
+ lt: _CompareWithType | None = ...,
8
+ le: _CompareWithType | None = ...,
9
+ gt: _CompareWithType | None = ...,
10
+ ge: _CompareWithType | None = ...,
11
+ require_same_type: bool = ...,
12
+ class_name: str = ...,
13
+ ) -> type: ...
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/_make.py ADDED
@@ -0,0 +1,3055 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ from __future__ import annotations
4
+
5
+ import abc
6
+ import contextlib
7
+ import copy
8
+ import enum
9
+ import functools
10
+ import inspect
11
+ import itertools
12
+ import linecache
13
+ import sys
14
+ import types
15
+ import typing
16
+
17
+ from operator import itemgetter
18
+
19
+ # We need to import _compat itself in addition to the _compat members to avoid
20
+ # having the thread-local in the globals here.
21
+ from . import _compat, _config, setters
22
+ from ._compat import (
23
+ PY_3_10_PLUS,
24
+ PY_3_11_PLUS,
25
+ PY_3_13_PLUS,
26
+ _AnnotationExtractor,
27
+ _get_annotations,
28
+ get_generic_base,
29
+ )
30
+ from .exceptions import (
31
+ DefaultAlreadySetError,
32
+ FrozenInstanceError,
33
+ NotAnAttrsClassError,
34
+ UnannotatedAttributeError,
35
+ )
36
+
37
+
38
+ # This is used at least twice, so cache it here.
39
+ _OBJ_SETATTR = object.__setattr__
40
+ _INIT_FACTORY_PAT = "__attr_factory_%s"
41
+ _CLASSVAR_PREFIXES = (
42
+ "typing.ClassVar",
43
+ "t.ClassVar",
44
+ "ClassVar",
45
+ "typing_extensions.ClassVar",
46
+ )
47
+ # we don't use a double-underscore prefix because that triggers
48
+ # name mangling when trying to create a slot for the field
49
+ # (when slots=True)
50
+ _HASH_CACHE_FIELD = "_attrs_cached_hash"
51
+
52
+ _EMPTY_METADATA_SINGLETON = types.MappingProxyType({})
53
+
54
+ # Unique object for unequivocal getattr() defaults.
55
+ _SENTINEL = object()
56
+
57
+ _DEFAULT_ON_SETATTR = setters.pipe(setters.convert, setters.validate)
58
+
59
+
60
+ class _Nothing(enum.Enum):
61
+ """
62
+ Sentinel to indicate the lack of a value when `None` is ambiguous.
63
+
64
+ If extending attrs, you can use ``typing.Literal[NOTHING]`` to show
65
+ that a value may be ``NOTHING``.
66
+
67
+ .. versionchanged:: 21.1.0 ``bool(NOTHING)`` is now False.
68
+ .. versionchanged:: 22.2.0 ``NOTHING`` is now an ``enum.Enum`` variant.
69
+ """
70
+
71
+ NOTHING = enum.auto()
72
+
73
+ def __repr__(self):
74
+ return "NOTHING"
75
+
76
+ def __bool__(self):
77
+ return False
78
+
79
+
80
+ NOTHING = _Nothing.NOTHING
81
+ """
82
+ Sentinel to indicate the lack of a value when `None` is ambiguous.
83
+
84
+ When using in 3rd party code, use `attrs.NothingType` for type annotations.
85
+ """
86
+
87
+
88
+ class _CacheHashWrapper(int):
89
+ """
90
+ An integer subclass that pickles / copies as None
91
+
92
+ This is used for non-slots classes with ``cache_hash=True``, to avoid
93
+ serializing a potentially (even likely) invalid hash value. Since `None`
94
+ is the default value for uncalculated hashes, whenever this is copied,
95
+ the copy's value for the hash should automatically reset.
96
+
97
+ See GH #613 for more details.
98
+ """
99
+
100
+ def __reduce__(self, _none_constructor=type(None), _args=()): # noqa: B008
101
+ return _none_constructor, _args
102
+
103
+
104
+ def attrib(
105
+ default=NOTHING,
106
+ validator=None,
107
+ repr=True,
108
+ cmp=None,
109
+ hash=None,
110
+ init=True,
111
+ metadata=None,
112
+ type=None,
113
+ converter=None,
114
+ factory=None,
115
+ kw_only=False,
116
+ eq=None,
117
+ order=None,
118
+ on_setattr=None,
119
+ alias=None,
120
+ ):
121
+ """
122
+ Create a new field / attribute on a class.
123
+
124
+ Identical to `attrs.field`, except it's not keyword-only.
125
+
126
+ Consider using `attrs.field` in new code (``attr.ib`` will *never* go away,
127
+ though).
128
+
129
+ .. warning::
130
+
131
+ Does **nothing** unless the class is also decorated with
132
+ `attr.s` (or similar)!
133
+
134
+
135
+ .. versionadded:: 15.2.0 *convert*
136
+ .. versionadded:: 16.3.0 *metadata*
137
+ .. versionchanged:: 17.1.0 *validator* can be a ``list`` now.
138
+ .. versionchanged:: 17.1.0
139
+ *hash* is `None` and therefore mirrors *eq* by default.
140
+ .. versionadded:: 17.3.0 *type*
141
+ .. deprecated:: 17.4.0 *convert*
142
+ .. versionadded:: 17.4.0
143
+ *converter* as a replacement for the deprecated *convert* to achieve
144
+ consistency with other noun-based arguments.
145
+ .. versionadded:: 18.1.0
146
+ ``factory=f`` is syntactic sugar for ``default=attr.Factory(f)``.
147
+ .. versionadded:: 18.2.0 *kw_only*
148
+ .. versionchanged:: 19.2.0 *convert* keyword argument removed.
149
+ .. versionchanged:: 19.2.0 *repr* also accepts a custom callable.
150
+ .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01.
151
+ .. versionadded:: 19.2.0 *eq* and *order*
152
+ .. versionadded:: 20.1.0 *on_setattr*
153
+ .. versionchanged:: 20.3.0 *kw_only* backported to Python 2
154
+ .. versionchanged:: 21.1.0
155
+ *eq*, *order*, and *cmp* also accept a custom callable
156
+ .. versionchanged:: 21.1.0 *cmp* undeprecated
157
+ .. versionadded:: 22.2.0 *alias*
158
+ """
159
+ eq, eq_key, order, order_key = _determine_attrib_eq_order(
160
+ cmp, eq, order, True
161
+ )
162
+
163
+ if hash is not None and hash is not True and hash is not False:
164
+ msg = "Invalid value for hash. Must be True, False, or None."
165
+ raise TypeError(msg)
166
+
167
+ if factory is not None:
168
+ if default is not NOTHING:
169
+ msg = (
170
+ "The `default` and `factory` arguments are mutually exclusive."
171
+ )
172
+ raise ValueError(msg)
173
+ if not callable(factory):
174
+ msg = "The `factory` argument must be a callable."
175
+ raise ValueError(msg)
176
+ default = Factory(factory)
177
+
178
+ if metadata is None:
179
+ metadata = {}
180
+
181
+ # Apply syntactic sugar by auto-wrapping.
182
+ if isinstance(on_setattr, (list, tuple)):
183
+ on_setattr = setters.pipe(*on_setattr)
184
+
185
+ if validator and isinstance(validator, (list, tuple)):
186
+ validator = and_(*validator)
187
+
188
+ if converter and isinstance(converter, (list, tuple)):
189
+ converter = pipe(*converter)
190
+
191
+ return _CountingAttr(
192
+ default=default,
193
+ validator=validator,
194
+ repr=repr,
195
+ cmp=None,
196
+ hash=hash,
197
+ init=init,
198
+ converter=converter,
199
+ metadata=metadata,
200
+ type=type,
201
+ kw_only=kw_only,
202
+ eq=eq,
203
+ eq_key=eq_key,
204
+ order=order,
205
+ order_key=order_key,
206
+ on_setattr=on_setattr,
207
+ alias=alias,
208
+ )
209
+
210
+
211
+ def _compile_and_eval(script, globs, locs=None, filename=""):
212
+ """
213
+ Evaluate the script with the given global (globs) and local (locs)
214
+ variables.
215
+ """
216
+ bytecode = compile(script, filename, "exec")
217
+ eval(bytecode, globs, locs)
218
+
219
+
220
+ def _make_method(name, script, filename, globs, locals=None):
221
+ """
222
+ Create the method with the script given and return the method object.
223
+ """
224
+ locs = {} if locals is None else locals
225
+
226
+ # In order of debuggers like PDB being able to step through the code,
227
+ # we add a fake linecache entry.
228
+ count = 1
229
+ base_filename = filename
230
+ while True:
231
+ linecache_tuple = (
232
+ len(script),
233
+ None,
234
+ script.splitlines(True),
235
+ filename,
236
+ )
237
+ old_val = linecache.cache.setdefault(filename, linecache_tuple)
238
+ if old_val == linecache_tuple:
239
+ break
240
+
241
+ filename = f"{base_filename[:-1]}-{count}>"
242
+ count += 1
243
+
244
+ _compile_and_eval(script, globs, locs, filename)
245
+
246
+ return locs[name]
247
+
248
+
249
+ def _make_attr_tuple_class(cls_name, attr_names):
250
+ """
251
+ Create a tuple subclass to hold `Attribute`s for an `attrs` class.
252
+
253
+ The subclass is a bare tuple with properties for names.
254
+
255
+ class MyClassAttributes(tuple):
256
+ __slots__ = ()
257
+ x = property(itemgetter(0))
258
+ """
259
+ attr_class_name = f"{cls_name}Attributes"
260
+ attr_class_template = [
261
+ f"class {attr_class_name}(tuple):",
262
+ " __slots__ = ()",
263
+ ]
264
+ if attr_names:
265
+ for i, attr_name in enumerate(attr_names):
266
+ attr_class_template.append(
267
+ f" {attr_name} = _attrs_property(_attrs_itemgetter({i}))"
268
+ )
269
+ else:
270
+ attr_class_template.append(" pass")
271
+ globs = {"_attrs_itemgetter": itemgetter, "_attrs_property": property}
272
+ _compile_and_eval("\n".join(attr_class_template), globs)
273
+ return globs[attr_class_name]
274
+
275
+
276
+ # Tuple class for extracted attributes from a class definition.
277
+ # `base_attrs` is a subset of `attrs`.
278
+ _Attributes = _make_attr_tuple_class(
279
+ "_Attributes",
280
+ [
281
+ # all attributes to build dunder methods for
282
+ "attrs",
283
+ # attributes that have been inherited
284
+ "base_attrs",
285
+ # map inherited attributes to their originating classes
286
+ "base_attrs_map",
287
+ ],
288
+ )
289
+
290
+
291
+ def _is_class_var(annot):
292
+ """
293
+ Check whether *annot* is a typing.ClassVar.
294
+
295
+ The string comparison hack is used to avoid evaluating all string
296
+ annotations which would put attrs-based classes at a performance
297
+ disadvantage compared to plain old classes.
298
+ """
299
+ annot = str(annot)
300
+
301
+ # Annotation can be quoted.
302
+ if annot.startswith(("'", '"')) and annot.endswith(("'", '"')):
303
+ annot = annot[1:-1]
304
+
305
+ return annot.startswith(_CLASSVAR_PREFIXES)
306
+
307
+
308
+ def _has_own_attribute(cls, attrib_name):
309
+ """
310
+ Check whether *cls* defines *attrib_name* (and doesn't just inherit it).
311
+ """
312
+ return attrib_name in cls.__dict__
313
+
314
+
315
+ def _collect_base_attrs(cls, taken_attr_names):
316
+ """
317
+ Collect attr.ibs from base classes of *cls*, except *taken_attr_names*.
318
+ """
319
+ base_attrs = []
320
+ base_attr_map = {} # A dictionary of base attrs to their classes.
321
+
322
+ # Traverse the MRO and collect attributes.
323
+ for base_cls in reversed(cls.__mro__[1:-1]):
324
+ for a in getattr(base_cls, "__attrs_attrs__", []):
325
+ if a.inherited or a.name in taken_attr_names:
326
+ continue
327
+
328
+ a = a.evolve(inherited=True) # noqa: PLW2901
329
+ base_attrs.append(a)
330
+ base_attr_map[a.name] = base_cls
331
+
332
+ # For each name, only keep the freshest definition i.e. the furthest at the
333
+ # back. base_attr_map is fine because it gets overwritten with every new
334
+ # instance.
335
+ filtered = []
336
+ seen = set()
337
+ for a in reversed(base_attrs):
338
+ if a.name in seen:
339
+ continue
340
+ filtered.insert(0, a)
341
+ seen.add(a.name)
342
+
343
+ return filtered, base_attr_map
344
+
345
+
346
+ def _collect_base_attrs_broken(cls, taken_attr_names):
347
+ """
348
+ Collect attr.ibs from base classes of *cls*, except *taken_attr_names*.
349
+
350
+ N.B. *taken_attr_names* will be mutated.
351
+
352
+ Adhere to the old incorrect behavior.
353
+
354
+ Notably it collects from the front and considers inherited attributes which
355
+ leads to the buggy behavior reported in #428.
356
+ """
357
+ base_attrs = []
358
+ base_attr_map = {} # A dictionary of base attrs to their classes.
359
+
360
+ # Traverse the MRO and collect attributes.
361
+ for base_cls in cls.__mro__[1:-1]:
362
+ for a in getattr(base_cls, "__attrs_attrs__", []):
363
+ if a.name in taken_attr_names:
364
+ continue
365
+
366
+ a = a.evolve(inherited=True) # noqa: PLW2901
367
+ taken_attr_names.add(a.name)
368
+ base_attrs.append(a)
369
+ base_attr_map[a.name] = base_cls
370
+
371
+ return base_attrs, base_attr_map
372
+
373
+
374
+ def _transform_attrs(
375
+ cls, these, auto_attribs, kw_only, collect_by_mro, field_transformer
376
+ ):
377
+ """
378
+ Transform all `_CountingAttr`s on a class into `Attribute`s.
379
+
380
+ If *these* is passed, use that and don't look for them on the class.
381
+
382
+ If *collect_by_mro* is True, collect them in the correct MRO order,
383
+ otherwise use the old -- incorrect -- order. See #428.
384
+
385
+ Return an `_Attributes`.
386
+ """
387
+ cd = cls.__dict__
388
+ anns = _get_annotations(cls)
389
+
390
+ if these is not None:
391
+ ca_list = list(these.items())
392
+ elif auto_attribs is True:
393
+ ca_names = {
394
+ name
395
+ for name, attr in cd.items()
396
+ if isinstance(attr, _CountingAttr)
397
+ }
398
+ ca_list = []
399
+ annot_names = set()
400
+ for attr_name, type in anns.items():
401
+ if _is_class_var(type):
402
+ continue
403
+ annot_names.add(attr_name)
404
+ a = cd.get(attr_name, NOTHING)
405
+
406
+ if not isinstance(a, _CountingAttr):
407
+ a = attrib() if a is NOTHING else attrib(default=a)
408
+ ca_list.append((attr_name, a))
409
+
410
+ unannotated = ca_names - annot_names
411
+ if len(unannotated) > 0:
412
+ raise UnannotatedAttributeError(
413
+ "The following `attr.ib`s lack a type annotation: "
414
+ + ", ".join(
415
+ sorted(unannotated, key=lambda n: cd.get(n).counter)
416
+ )
417
+ + "."
418
+ )
419
+ else:
420
+ ca_list = sorted(
421
+ (
422
+ (name, attr)
423
+ for name, attr in cd.items()
424
+ if isinstance(attr, _CountingAttr)
425
+ ),
426
+ key=lambda e: e[1].counter,
427
+ )
428
+
429
+ own_attrs = [
430
+ Attribute.from_counting_attr(
431
+ name=attr_name, ca=ca, type=anns.get(attr_name)
432
+ )
433
+ for attr_name, ca in ca_list
434
+ ]
435
+
436
+ if collect_by_mro:
437
+ base_attrs, base_attr_map = _collect_base_attrs(
438
+ cls, {a.name for a in own_attrs}
439
+ )
440
+ else:
441
+ base_attrs, base_attr_map = _collect_base_attrs_broken(
442
+ cls, {a.name for a in own_attrs}
443
+ )
444
+
445
+ if kw_only:
446
+ own_attrs = [a.evolve(kw_only=True) for a in own_attrs]
447
+ base_attrs = [a.evolve(kw_only=True) for a in base_attrs]
448
+
449
+ attrs = base_attrs + own_attrs
450
+
451
+ # Mandatory vs non-mandatory attr order only matters when they are part of
452
+ # the __init__ signature and when they aren't kw_only (which are moved to
453
+ # the end and can be mandatory or non-mandatory in any order, as they will
454
+ # be specified as keyword args anyway). Check the order of those attrs:
455
+ had_default = False
456
+ for a in (a for a in attrs if a.init is not False and a.kw_only is False):
457
+ if had_default is True and a.default is NOTHING:
458
+ msg = f"No mandatory attributes allowed after an attribute with a default value or factory. Attribute in question: {a!r}"
459
+ raise ValueError(msg)
460
+
461
+ if had_default is False and a.default is not NOTHING:
462
+ had_default = True
463
+
464
+ if field_transformer is not None:
465
+ attrs = field_transformer(cls, attrs)
466
+
467
+ # Resolve default field alias after executing field_transformer.
468
+ # This allows field_transformer to differentiate between explicit vs
469
+ # default aliases and supply their own defaults.
470
+ attrs = [
471
+ a.evolve(alias=_default_init_alias_for(a.name)) if not a.alias else a
472
+ for a in attrs
473
+ ]
474
+
475
+ # Create AttrsClass *after* applying the field_transformer since it may
476
+ # add or remove attributes!
477
+ attr_names = [a.name for a in attrs]
478
+ AttrsClass = _make_attr_tuple_class(cls.__name__, attr_names)
479
+
480
+ return _Attributes((AttrsClass(attrs), base_attrs, base_attr_map))
481
+
482
+
483
+ def _make_cached_property_getattr(cached_properties, original_getattr, cls):
484
+ lines = [
485
+ # Wrapped to get `__class__` into closure cell for super()
486
+ # (It will be replaced with the newly constructed class after construction).
487
+ "def wrapper(_cls):",
488
+ " __class__ = _cls",
489
+ " def __getattr__(self, item, cached_properties=cached_properties, original_getattr=original_getattr, _cached_setattr_get=_cached_setattr_get):",
490
+ " func = cached_properties.get(item)",
491
+ " if func is not None:",
492
+ " result = func(self)",
493
+ " _setter = _cached_setattr_get(self)",
494
+ " _setter(item, result)",
495
+ " return result",
496
+ ]
497
+ if original_getattr is not None:
498
+ lines.append(
499
+ " return original_getattr(self, item)",
500
+ )
501
+ else:
502
+ lines.extend(
503
+ [
504
+ " try:",
505
+ " return super().__getattribute__(item)",
506
+ " except AttributeError:",
507
+ " if not hasattr(super(), '__getattr__'):",
508
+ " raise",
509
+ " return super().__getattr__(item)",
510
+ " original_error = f\"'{self.__class__.__name__}' object has no attribute '{item}'\"",
511
+ " raise AttributeError(original_error)",
512
+ ]
513
+ )
514
+
515
+ lines.extend(
516
+ [
517
+ " return __getattr__",
518
+ "__getattr__ = wrapper(_cls)",
519
+ ]
520
+ )
521
+
522
+ unique_filename = _generate_unique_filename(cls, "getattr")
523
+
524
+ glob = {
525
+ "cached_properties": cached_properties,
526
+ "_cached_setattr_get": _OBJ_SETATTR.__get__,
527
+ "original_getattr": original_getattr,
528
+ }
529
+
530
+ return _make_method(
531
+ "__getattr__",
532
+ "\n".join(lines),
533
+ unique_filename,
534
+ glob,
535
+ locals={
536
+ "_cls": cls,
537
+ },
538
+ )
539
+
540
+
541
+ def _frozen_setattrs(self, name, value):
542
+ """
543
+ Attached to frozen classes as __setattr__.
544
+ """
545
+ if isinstance(self, BaseException) and name in (
546
+ "__cause__",
547
+ "__context__",
548
+ "__traceback__",
549
+ "__suppress_context__",
550
+ "__notes__",
551
+ ):
552
+ BaseException.__setattr__(self, name, value)
553
+ return
554
+
555
+ raise FrozenInstanceError
556
+
557
+
558
+ def _frozen_delattrs(self, name):
559
+ """
560
+ Attached to frozen classes as __delattr__.
561
+ """
562
+ if isinstance(self, BaseException) and name in ("__notes__",):
563
+ BaseException.__delattr__(self, name)
564
+ return
565
+
566
+ raise FrozenInstanceError
567
+
568
+
569
+ def evolve(*args, **changes):
570
+ """
571
+ Create a new instance, based on the first positional argument with
572
+ *changes* applied.
573
+
574
+ .. tip::
575
+
576
+ On Python 3.13 and later, you can also use `copy.replace` instead.
577
+
578
+ Args:
579
+
580
+ inst:
581
+ Instance of a class with *attrs* attributes. *inst* must be passed
582
+ as a positional argument.
583
+
584
+ changes:
585
+ Keyword changes in the new copy.
586
+
587
+ Returns:
588
+ A copy of inst with *changes* incorporated.
589
+
590
+ Raises:
591
+ TypeError:
592
+ If *attr_name* couldn't be found in the class ``__init__``.
593
+
594
+ attrs.exceptions.NotAnAttrsClassError:
595
+ If *cls* is not an *attrs* class.
596
+
597
+ .. versionadded:: 17.1.0
598
+ .. deprecated:: 23.1.0
599
+ It is now deprecated to pass the instance using the keyword argument
600
+ *inst*. It will raise a warning until at least April 2024, after which
601
+ it will become an error. Always pass the instance as a positional
602
+ argument.
603
+ .. versionchanged:: 24.1.0
604
+ *inst* can't be passed as a keyword argument anymore.
605
+ """
606
+ try:
607
+ (inst,) = args
608
+ except ValueError:
609
+ msg = (
610
+ f"evolve() takes 1 positional argument, but {len(args)} were given"
611
+ )
612
+ raise TypeError(msg) from None
613
+
614
+ cls = inst.__class__
615
+ attrs = fields(cls)
616
+ for a in attrs:
617
+ if not a.init:
618
+ continue
619
+ attr_name = a.name # To deal with private attributes.
620
+ init_name = a.alias
621
+ if init_name not in changes:
622
+ changes[init_name] = getattr(inst, attr_name)
623
+
624
+ return cls(**changes)
625
+
626
+
627
+ class _ClassBuilder:
628
+ """
629
+ Iteratively build *one* class.
630
+ """
631
+
632
+ __slots__ = (
633
+ "_attr_names",
634
+ "_attrs",
635
+ "_base_attr_map",
636
+ "_base_names",
637
+ "_cache_hash",
638
+ "_cls",
639
+ "_cls_dict",
640
+ "_delete_attribs",
641
+ "_frozen",
642
+ "_has_custom_setattr",
643
+ "_has_post_init",
644
+ "_has_pre_init",
645
+ "_is_exc",
646
+ "_on_setattr",
647
+ "_pre_init_has_args",
648
+ "_slots",
649
+ "_weakref_slot",
650
+ "_wrote_own_setattr",
651
+ )
652
+
653
+ def __init__(
654
+ self,
655
+ cls,
656
+ these,
657
+ slots,
658
+ frozen,
659
+ weakref_slot,
660
+ getstate_setstate,
661
+ auto_attribs,
662
+ kw_only,
663
+ cache_hash,
664
+ is_exc,
665
+ collect_by_mro,
666
+ on_setattr,
667
+ has_custom_setattr,
668
+ field_transformer,
669
+ ):
670
+ attrs, base_attrs, base_map = _transform_attrs(
671
+ cls,
672
+ these,
673
+ auto_attribs,
674
+ kw_only,
675
+ collect_by_mro,
676
+ field_transformer,
677
+ )
678
+
679
+ self._cls = cls
680
+ self._cls_dict = dict(cls.__dict__) if slots else {}
681
+ self._attrs = attrs
682
+ self._base_names = {a.name for a in base_attrs}
683
+ self._base_attr_map = base_map
684
+ self._attr_names = tuple(a.name for a in attrs)
685
+ self._slots = slots
686
+ self._frozen = frozen
687
+ self._weakref_slot = weakref_slot
688
+ self._cache_hash = cache_hash
689
+ self._has_pre_init = bool(getattr(cls, "__attrs_pre_init__", False))
690
+ self._pre_init_has_args = False
691
+ if self._has_pre_init:
692
+ # Check if the pre init method has more arguments than just `self`
693
+ # We want to pass arguments if pre init expects arguments
694
+ pre_init_func = cls.__attrs_pre_init__
695
+ pre_init_signature = inspect.signature(pre_init_func)
696
+ self._pre_init_has_args = len(pre_init_signature.parameters) > 1
697
+ self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False))
698
+ self._delete_attribs = not bool(these)
699
+ self._is_exc = is_exc
700
+ self._on_setattr = on_setattr
701
+
702
+ self._has_custom_setattr = has_custom_setattr
703
+ self._wrote_own_setattr = False
704
+
705
+ self._cls_dict["__attrs_attrs__"] = self._attrs
706
+
707
+ if frozen:
708
+ self._cls_dict["__setattr__"] = _frozen_setattrs
709
+ self._cls_dict["__delattr__"] = _frozen_delattrs
710
+
711
+ self._wrote_own_setattr = True
712
+ elif on_setattr in (
713
+ _DEFAULT_ON_SETATTR,
714
+ setters.validate,
715
+ setters.convert,
716
+ ):
717
+ has_validator = has_converter = False
718
+ for a in attrs:
719
+ if a.validator is not None:
720
+ has_validator = True
721
+ if a.converter is not None:
722
+ has_converter = True
723
+
724
+ if has_validator and has_converter:
725
+ break
726
+ if (
727
+ (
728
+ on_setattr == _DEFAULT_ON_SETATTR
729
+ and not (has_validator or has_converter)
730
+ )
731
+ or (on_setattr == setters.validate and not has_validator)
732
+ or (on_setattr == setters.convert and not has_converter)
733
+ ):
734
+ # If class-level on_setattr is set to convert + validate, but
735
+ # there's no field to convert or validate, pretend like there's
736
+ # no on_setattr.
737
+ self._on_setattr = None
738
+
739
+ if getstate_setstate:
740
+ (
741
+ self._cls_dict["__getstate__"],
742
+ self._cls_dict["__setstate__"],
743
+ ) = self._make_getstate_setstate()
744
+
745
+ def __repr__(self):
746
+ return f"<_ClassBuilder(cls={self._cls.__name__})>"
747
+
748
+ def build_class(self):
749
+ """
750
+ Finalize class based on the accumulated configuration.
751
+
752
+ Builder cannot be used after calling this method.
753
+ """
754
+ if self._slots is True:
755
+ cls = self._create_slots_class()
756
+ else:
757
+ cls = self._patch_original_class()
758
+ if PY_3_10_PLUS:
759
+ cls = abc.update_abstractmethods(cls)
760
+
761
+ # The method gets only called if it's not inherited from a base class.
762
+ # _has_own_attribute does NOT work properly for classmethods.
763
+ if (
764
+ getattr(cls, "__attrs_init_subclass__", None)
765
+ and "__attrs_init_subclass__" not in cls.__dict__
766
+ ):
767
+ cls.__attrs_init_subclass__()
768
+
769
+ return cls
770
+
771
+ def _patch_original_class(self):
772
+ """
773
+ Apply accumulated methods and return the class.
774
+ """
775
+ cls = self._cls
776
+ base_names = self._base_names
777
+
778
+ # Clean class of attribute definitions (`attr.ib()`s).
779
+ if self._delete_attribs:
780
+ for name in self._attr_names:
781
+ if (
782
+ name not in base_names
783
+ and getattr(cls, name, _SENTINEL) is not _SENTINEL
784
+ ):
785
+ # An AttributeError can happen if a base class defines a
786
+ # class variable and we want to set an attribute with the
787
+ # same name by using only a type annotation.
788
+ with contextlib.suppress(AttributeError):
789
+ delattr(cls, name)
790
+
791
+ # Attach our dunder methods.
792
+ for name, value in self._cls_dict.items():
793
+ setattr(cls, name, value)
794
+
795
+ # If we've inherited an attrs __setattr__ and don't write our own,
796
+ # reset it to object's.
797
+ if not self._wrote_own_setattr and getattr(
798
+ cls, "__attrs_own_setattr__", False
799
+ ):
800
+ cls.__attrs_own_setattr__ = False
801
+
802
+ if not self._has_custom_setattr:
803
+ cls.__setattr__ = _OBJ_SETATTR
804
+
805
+ return cls
806
+
807
+ def _create_slots_class(self):
808
+ """
809
+ Build and return a new class with a `__slots__` attribute.
810
+ """
811
+ cd = {
812
+ k: v
813
+ for k, v in self._cls_dict.items()
814
+ if k not in (*tuple(self._attr_names), "__dict__", "__weakref__")
815
+ }
816
+
817
+ # If our class doesn't have its own implementation of __setattr__
818
+ # (either from the user or by us), check the bases, if one of them has
819
+ # an attrs-made __setattr__, that needs to be reset. We don't walk the
820
+ # MRO because we only care about our immediate base classes.
821
+ # XXX: This can be confused by subclassing a slotted attrs class with
822
+ # XXX: a non-attrs class and subclass the resulting class with an attrs
823
+ # XXX: class. See `test_slotted_confused` for details. For now that's
824
+ # XXX: OK with us.
825
+ if not self._wrote_own_setattr:
826
+ cd["__attrs_own_setattr__"] = False
827
+
828
+ if not self._has_custom_setattr:
829
+ for base_cls in self._cls.__bases__:
830
+ if base_cls.__dict__.get("__attrs_own_setattr__", False):
831
+ cd["__setattr__"] = _OBJ_SETATTR
832
+ break
833
+
834
+ # Traverse the MRO to collect existing slots
835
+ # and check for an existing __weakref__.
836
+ existing_slots = {}
837
+ weakref_inherited = False
838
+ for base_cls in self._cls.__mro__[1:-1]:
839
+ if base_cls.__dict__.get("__weakref__", None) is not None:
840
+ weakref_inherited = True
841
+ existing_slots.update(
842
+ {
843
+ name: getattr(base_cls, name)
844
+ for name in getattr(base_cls, "__slots__", [])
845
+ }
846
+ )
847
+
848
+ base_names = set(self._base_names)
849
+
850
+ names = self._attr_names
851
+ if (
852
+ self._weakref_slot
853
+ and "__weakref__" not in getattr(self._cls, "__slots__", ())
854
+ and "__weakref__" not in names
855
+ and not weakref_inherited
856
+ ):
857
+ names += ("__weakref__",)
858
+
859
+ cached_properties = {
860
+ name: cached_property.func
861
+ for name, cached_property in cd.items()
862
+ if isinstance(cached_property, functools.cached_property)
863
+ }
864
+
865
+ # Collect methods with a `__class__` reference that are shadowed in the new class.
866
+ # To know to update them.
867
+ additional_closure_functions_to_update = []
868
+ if cached_properties:
869
+ class_annotations = _get_annotations(self._cls)
870
+ for name, func in cached_properties.items():
871
+ # Add cached properties to names for slotting.
872
+ names += (name,)
873
+ # Clear out function from class to avoid clashing.
874
+ del cd[name]
875
+ additional_closure_functions_to_update.append(func)
876
+ annotation = inspect.signature(func).return_annotation
877
+ if annotation is not inspect.Parameter.empty:
878
+ class_annotations[name] = annotation
879
+
880
+ original_getattr = cd.get("__getattr__")
881
+ if original_getattr is not None:
882
+ additional_closure_functions_to_update.append(original_getattr)
883
+
884
+ cd["__getattr__"] = _make_cached_property_getattr(
885
+ cached_properties, original_getattr, self._cls
886
+ )
887
+
888
+ # We only add the names of attributes that aren't inherited.
889
+ # Setting __slots__ to inherited attributes wastes memory.
890
+ slot_names = [name for name in names if name not in base_names]
891
+
892
+ # There are slots for attributes from current class
893
+ # that are defined in parent classes.
894
+ # As their descriptors may be overridden by a child class,
895
+ # we collect them here and update the class dict
896
+ reused_slots = {
897
+ slot: slot_descriptor
898
+ for slot, slot_descriptor in existing_slots.items()
899
+ if slot in slot_names
900
+ }
901
+ slot_names = [name for name in slot_names if name not in reused_slots]
902
+ cd.update(reused_slots)
903
+ if self._cache_hash:
904
+ slot_names.append(_HASH_CACHE_FIELD)
905
+
906
+ cd["__slots__"] = tuple(slot_names)
907
+
908
+ cd["__qualname__"] = self._cls.__qualname__
909
+
910
+ # Create new class based on old class and our methods.
911
+ cls = type(self._cls)(self._cls.__name__, self._cls.__bases__, cd)
912
+
913
+ # The following is a fix for
914
+ # <https://github.com/python-attrs/attrs/issues/102>.
915
+ # If a method mentions `__class__` or uses the no-arg super(), the
916
+ # compiler will bake a reference to the class in the method itself
917
+ # as `method.__closure__`. Since we replace the class with a
918
+ # clone, we rewrite these references so it keeps working.
919
+ for item in itertools.chain(
920
+ cls.__dict__.values(), additional_closure_functions_to_update
921
+ ):
922
+ if isinstance(item, (classmethod, staticmethod)):
923
+ # Class- and staticmethods hide their functions inside.
924
+ # These might need to be rewritten as well.
925
+ closure_cells = getattr(item.__func__, "__closure__", None)
926
+ elif isinstance(item, property):
927
+ # Workaround for property `super()` shortcut (PY3-only).
928
+ # There is no universal way for other descriptors.
929
+ closure_cells = getattr(item.fget, "__closure__", None)
930
+ else:
931
+ closure_cells = getattr(item, "__closure__", None)
932
+
933
+ if not closure_cells: # Catch None or the empty list.
934
+ continue
935
+ for cell in closure_cells:
936
+ try:
937
+ match = cell.cell_contents is self._cls
938
+ except ValueError: # noqa: PERF203
939
+ # ValueError: Cell is empty
940
+ pass
941
+ else:
942
+ if match:
943
+ cell.cell_contents = cls
944
+ return cls
945
+
946
+ def add_repr(self, ns):
947
+ self._cls_dict["__repr__"] = self._add_method_dunders(
948
+ _make_repr(self._attrs, ns, self._cls)
949
+ )
950
+ return self
951
+
952
+ def add_str(self):
953
+ repr = self._cls_dict.get("__repr__")
954
+ if repr is None:
955
+ msg = "__str__ can only be generated if a __repr__ exists."
956
+ raise ValueError(msg)
957
+
958
+ def __str__(self):
959
+ return self.__repr__()
960
+
961
+ self._cls_dict["__str__"] = self._add_method_dunders(__str__)
962
+ return self
963
+
964
+ def _make_getstate_setstate(self):
965
+ """
966
+ Create custom __setstate__ and __getstate__ methods.
967
+ """
968
+ # __weakref__ is not writable.
969
+ state_attr_names = tuple(
970
+ an for an in self._attr_names if an != "__weakref__"
971
+ )
972
+
973
+ def slots_getstate(self):
974
+ """
975
+ Automatically created by attrs.
976
+ """
977
+ return {name: getattr(self, name) for name in state_attr_names}
978
+
979
+ hash_caching_enabled = self._cache_hash
980
+
981
+ def slots_setstate(self, state):
982
+ """
983
+ Automatically created by attrs.
984
+ """
985
+ __bound_setattr = _OBJ_SETATTR.__get__(self)
986
+ if isinstance(state, tuple):
987
+ # Backward compatibility with attrs instances pickled with
988
+ # attrs versions before v22.2.0 which stored tuples.
989
+ for name, value in zip(state_attr_names, state):
990
+ __bound_setattr(name, value)
991
+ else:
992
+ for name in state_attr_names:
993
+ if name in state:
994
+ __bound_setattr(name, state[name])
995
+
996
+ # The hash code cache is not included when the object is
997
+ # serialized, but it still needs to be initialized to None to
998
+ # indicate that the first call to __hash__ should be a cache
999
+ # miss.
1000
+ if hash_caching_enabled:
1001
+ __bound_setattr(_HASH_CACHE_FIELD, None)
1002
+
1003
+ return slots_getstate, slots_setstate
1004
+
1005
+ def make_unhashable(self):
1006
+ self._cls_dict["__hash__"] = None
1007
+ return self
1008
+
1009
+ def add_hash(self):
1010
+ self._cls_dict["__hash__"] = self._add_method_dunders(
1011
+ _make_hash(
1012
+ self._cls,
1013
+ self._attrs,
1014
+ frozen=self._frozen,
1015
+ cache_hash=self._cache_hash,
1016
+ )
1017
+ )
1018
+
1019
+ return self
1020
+
1021
+ def add_init(self):
1022
+ self._cls_dict["__init__"] = self._add_method_dunders(
1023
+ _make_init(
1024
+ self._cls,
1025
+ self._attrs,
1026
+ self._has_pre_init,
1027
+ self._pre_init_has_args,
1028
+ self._has_post_init,
1029
+ self._frozen,
1030
+ self._slots,
1031
+ self._cache_hash,
1032
+ self._base_attr_map,
1033
+ self._is_exc,
1034
+ self._on_setattr,
1035
+ attrs_init=False,
1036
+ )
1037
+ )
1038
+
1039
+ return self
1040
+
1041
+ def add_replace(self):
1042
+ self._cls_dict["__replace__"] = self._add_method_dunders(
1043
+ lambda self, **changes: evolve(self, **changes)
1044
+ )
1045
+ return self
1046
+
1047
+ def add_match_args(self):
1048
+ self._cls_dict["__match_args__"] = tuple(
1049
+ field.name
1050
+ for field in self._attrs
1051
+ if field.init and not field.kw_only
1052
+ )
1053
+
1054
+ def add_attrs_init(self):
1055
+ self._cls_dict["__attrs_init__"] = self._add_method_dunders(
1056
+ _make_init(
1057
+ self._cls,
1058
+ self._attrs,
1059
+ self._has_pre_init,
1060
+ self._pre_init_has_args,
1061
+ self._has_post_init,
1062
+ self._frozen,
1063
+ self._slots,
1064
+ self._cache_hash,
1065
+ self._base_attr_map,
1066
+ self._is_exc,
1067
+ self._on_setattr,
1068
+ attrs_init=True,
1069
+ )
1070
+ )
1071
+
1072
+ return self
1073
+
1074
+ def add_eq(self):
1075
+ cd = self._cls_dict
1076
+
1077
+ cd["__eq__"] = self._add_method_dunders(
1078
+ _make_eq(self._cls, self._attrs)
1079
+ )
1080
+ cd["__ne__"] = self._add_method_dunders(_make_ne())
1081
+
1082
+ return self
1083
+
1084
+ def add_order(self):
1085
+ cd = self._cls_dict
1086
+
1087
+ cd["__lt__"], cd["__le__"], cd["__gt__"], cd["__ge__"] = (
1088
+ self._add_method_dunders(meth)
1089
+ for meth in _make_order(self._cls, self._attrs)
1090
+ )
1091
+
1092
+ return self
1093
+
1094
+ def add_setattr(self):
1095
+ if self._frozen:
1096
+ return self
1097
+
1098
+ sa_attrs = {}
1099
+ for a in self._attrs:
1100
+ on_setattr = a.on_setattr or self._on_setattr
1101
+ if on_setattr and on_setattr is not setters.NO_OP:
1102
+ sa_attrs[a.name] = a, on_setattr
1103
+
1104
+ if not sa_attrs:
1105
+ return self
1106
+
1107
+ if self._has_custom_setattr:
1108
+ # We need to write a __setattr__ but there already is one!
1109
+ msg = "Can't combine custom __setattr__ with on_setattr hooks."
1110
+ raise ValueError(msg)
1111
+
1112
+ # docstring comes from _add_method_dunders
1113
+ def __setattr__(self, name, val):
1114
+ try:
1115
+ a, hook = sa_attrs[name]
1116
+ except KeyError:
1117
+ nval = val
1118
+ else:
1119
+ nval = hook(self, a, val)
1120
+
1121
+ _OBJ_SETATTR(self, name, nval)
1122
+
1123
+ self._cls_dict["__attrs_own_setattr__"] = True
1124
+ self._cls_dict["__setattr__"] = self._add_method_dunders(__setattr__)
1125
+ self._wrote_own_setattr = True
1126
+
1127
+ return self
1128
+
1129
+ def _add_method_dunders(self, method):
1130
+ """
1131
+ Add __module__ and __qualname__ to a *method* if possible.
1132
+ """
1133
+ with contextlib.suppress(AttributeError):
1134
+ method.__module__ = self._cls.__module__
1135
+
1136
+ with contextlib.suppress(AttributeError):
1137
+ method.__qualname__ = f"{self._cls.__qualname__}.{method.__name__}"
1138
+
1139
+ with contextlib.suppress(AttributeError):
1140
+ method.__doc__ = (
1141
+ "Method generated by attrs for class "
1142
+ f"{self._cls.__qualname__}."
1143
+ )
1144
+
1145
+ return method
1146
+
1147
+
1148
+ def _determine_attrs_eq_order(cmp, eq, order, default_eq):
1149
+ """
1150
+ Validate the combination of *cmp*, *eq*, and *order*. Derive the effective
1151
+ values of eq and order. If *eq* is None, set it to *default_eq*.
1152
+ """
1153
+ if cmp is not None and any((eq is not None, order is not None)):
1154
+ msg = "Don't mix `cmp` with `eq' and `order`."
1155
+ raise ValueError(msg)
1156
+
1157
+ # cmp takes precedence due to bw-compatibility.
1158
+ if cmp is not None:
1159
+ return cmp, cmp
1160
+
1161
+ # If left None, equality is set to the specified default and ordering
1162
+ # mirrors equality.
1163
+ if eq is None:
1164
+ eq = default_eq
1165
+
1166
+ if order is None:
1167
+ order = eq
1168
+
1169
+ if eq is False and order is True:
1170
+ msg = "`order` can only be True if `eq` is True too."
1171
+ raise ValueError(msg)
1172
+
1173
+ return eq, order
1174
+
1175
+
1176
+ def _determine_attrib_eq_order(cmp, eq, order, default_eq):
1177
+ """
1178
+ Validate the combination of *cmp*, *eq*, and *order*. Derive the effective
1179
+ values of eq and order. If *eq* is None, set it to *default_eq*.
1180
+ """
1181
+ if cmp is not None and any((eq is not None, order is not None)):
1182
+ msg = "Don't mix `cmp` with `eq' and `order`."
1183
+ raise ValueError(msg)
1184
+
1185
+ def decide_callable_or_boolean(value):
1186
+ """
1187
+ Decide whether a key function is used.
1188
+ """
1189
+ if callable(value):
1190
+ value, key = True, value
1191
+ else:
1192
+ key = None
1193
+ return value, key
1194
+
1195
+ # cmp takes precedence due to bw-compatibility.
1196
+ if cmp is not None:
1197
+ cmp, cmp_key = decide_callable_or_boolean(cmp)
1198
+ return cmp, cmp_key, cmp, cmp_key
1199
+
1200
+ # If left None, equality is set to the specified default and ordering
1201
+ # mirrors equality.
1202
+ if eq is None:
1203
+ eq, eq_key = default_eq, None
1204
+ else:
1205
+ eq, eq_key = decide_callable_or_boolean(eq)
1206
+
1207
+ if order is None:
1208
+ order, order_key = eq, eq_key
1209
+ else:
1210
+ order, order_key = decide_callable_or_boolean(order)
1211
+
1212
+ if eq is False and order is True:
1213
+ msg = "`order` can only be True if `eq` is True too."
1214
+ raise ValueError(msg)
1215
+
1216
+ return eq, eq_key, order, order_key
1217
+
1218
+
1219
+ def _determine_whether_to_implement(
1220
+ cls, flag, auto_detect, dunders, default=True
1221
+ ):
1222
+ """
1223
+ Check whether we should implement a set of methods for *cls*.
1224
+
1225
+ *flag* is the argument passed into @attr.s like 'init', *auto_detect* the
1226
+ same as passed into @attr.s and *dunders* is a tuple of attribute names
1227
+ whose presence signal that the user has implemented it themselves.
1228
+
1229
+ Return *default* if no reason for either for or against is found.
1230
+ """
1231
+ if flag is True or flag is False:
1232
+ return flag
1233
+
1234
+ if flag is None and auto_detect is False:
1235
+ return default
1236
+
1237
+ # Logically, flag is None and auto_detect is True here.
1238
+ for dunder in dunders:
1239
+ if _has_own_attribute(cls, dunder):
1240
+ return False
1241
+
1242
+ return default
1243
+
1244
+
1245
+ def attrs(
1246
+ maybe_cls=None,
1247
+ these=None,
1248
+ repr_ns=None,
1249
+ repr=None,
1250
+ cmp=None,
1251
+ hash=None,
1252
+ init=None,
1253
+ slots=False,
1254
+ frozen=False,
1255
+ weakref_slot=True,
1256
+ str=False,
1257
+ auto_attribs=False,
1258
+ kw_only=False,
1259
+ cache_hash=False,
1260
+ auto_exc=False,
1261
+ eq=None,
1262
+ order=None,
1263
+ auto_detect=False,
1264
+ collect_by_mro=False,
1265
+ getstate_setstate=None,
1266
+ on_setattr=None,
1267
+ field_transformer=None,
1268
+ match_args=True,
1269
+ unsafe_hash=None,
1270
+ ):
1271
+ r"""
1272
+ A class decorator that adds :term:`dunder methods` according to the
1273
+ specified attributes using `attr.ib` or the *these* argument.
1274
+
1275
+ Consider using `attrs.define` / `attrs.frozen` in new code (``attr.s`` will
1276
+ *never* go away, though).
1277
+
1278
+ Args:
1279
+ repr_ns (str):
1280
+ When using nested classes, there was no way in Python 2 to
1281
+ automatically detect that. This argument allows to set a custom
1282
+ name for a more meaningful ``repr`` output. This argument is
1283
+ pointless in Python 3 and is therefore deprecated.
1284
+
1285
+ .. caution::
1286
+ Refer to `attrs.define` for the rest of the parameters, but note that they
1287
+ can have different defaults.
1288
+
1289
+ Notably, leaving *on_setattr* as `None` will **not** add any hooks.
1290
+
1291
+ .. versionadded:: 16.0.0 *slots*
1292
+ .. versionadded:: 16.1.0 *frozen*
1293
+ .. versionadded:: 16.3.0 *str*
1294
+ .. versionadded:: 16.3.0 Support for ``__attrs_post_init__``.
1295
+ .. versionchanged:: 17.1.0
1296
+ *hash* supports `None` as value which is also the default now.
1297
+ .. versionadded:: 17.3.0 *auto_attribs*
1298
+ .. versionchanged:: 18.1.0
1299
+ If *these* is passed, no attributes are deleted from the class body.
1300
+ .. versionchanged:: 18.1.0 If *these* is ordered, the order is retained.
1301
+ .. versionadded:: 18.2.0 *weakref_slot*
1302
+ .. deprecated:: 18.2.0
1303
+ ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now raise a
1304
+ `DeprecationWarning` if the classes compared are subclasses of
1305
+ each other. ``__eq`` and ``__ne__`` never tried to compared subclasses
1306
+ to each other.
1307
+ .. versionchanged:: 19.2.0
1308
+ ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now do not consider
1309
+ subclasses comparable anymore.
1310
+ .. versionadded:: 18.2.0 *kw_only*
1311
+ .. versionadded:: 18.2.0 *cache_hash*
1312
+ .. versionadded:: 19.1.0 *auto_exc*
1313
+ .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01.
1314
+ .. versionadded:: 19.2.0 *eq* and *order*
1315
+ .. versionadded:: 20.1.0 *auto_detect*
1316
+ .. versionadded:: 20.1.0 *collect_by_mro*
1317
+ .. versionadded:: 20.1.0 *getstate_setstate*
1318
+ .. versionadded:: 20.1.0 *on_setattr*
1319
+ .. versionadded:: 20.3.0 *field_transformer*
1320
+ .. versionchanged:: 21.1.0
1321
+ ``init=False`` injects ``__attrs_init__``
1322
+ .. versionchanged:: 21.1.0 Support for ``__attrs_pre_init__``
1323
+ .. versionchanged:: 21.1.0 *cmp* undeprecated
1324
+ .. versionadded:: 21.3.0 *match_args*
1325
+ .. versionadded:: 22.2.0
1326
+ *unsafe_hash* as an alias for *hash* (for :pep:`681` compliance).
1327
+ .. deprecated:: 24.1.0 *repr_ns*
1328
+ .. versionchanged:: 24.1.0
1329
+ Instances are not compared as tuples of attributes anymore, but using a
1330
+ big ``and`` condition. This is faster and has more correct behavior for
1331
+ uncomparable values like `math.nan`.
1332
+ .. versionadded:: 24.1.0
1333
+ If a class has an *inherited* classmethod called
1334
+ ``__attrs_init_subclass__``, it is executed after the class is created.
1335
+ .. deprecated:: 24.1.0 *hash* is deprecated in favor of *unsafe_hash*.
1336
+ """
1337
+ if repr_ns is not None:
1338
+ import warnings
1339
+
1340
+ warnings.warn(
1341
+ DeprecationWarning(
1342
+ "The `repr_ns` argument is deprecated and will be removed in or after August 2025."
1343
+ ),
1344
+ stacklevel=2,
1345
+ )
1346
+
1347
+ eq_, order_ = _determine_attrs_eq_order(cmp, eq, order, None)
1348
+
1349
+ # unsafe_hash takes precedence due to PEP 681.
1350
+ if unsafe_hash is not None:
1351
+ hash = unsafe_hash
1352
+
1353
+ if isinstance(on_setattr, (list, tuple)):
1354
+ on_setattr = setters.pipe(*on_setattr)
1355
+
1356
+ def wrap(cls):
1357
+ is_frozen = frozen or _has_frozen_base_class(cls)
1358
+ is_exc = auto_exc is True and issubclass(cls, BaseException)
1359
+ has_own_setattr = auto_detect and _has_own_attribute(
1360
+ cls, "__setattr__"
1361
+ )
1362
+
1363
+ if has_own_setattr and is_frozen:
1364
+ msg = "Can't freeze a class with a custom __setattr__."
1365
+ raise ValueError(msg)
1366
+
1367
+ builder = _ClassBuilder(
1368
+ cls,
1369
+ these,
1370
+ slots,
1371
+ is_frozen,
1372
+ weakref_slot,
1373
+ _determine_whether_to_implement(
1374
+ cls,
1375
+ getstate_setstate,
1376
+ auto_detect,
1377
+ ("__getstate__", "__setstate__"),
1378
+ default=slots,
1379
+ ),
1380
+ auto_attribs,
1381
+ kw_only,
1382
+ cache_hash,
1383
+ is_exc,
1384
+ collect_by_mro,
1385
+ on_setattr,
1386
+ has_own_setattr,
1387
+ field_transformer,
1388
+ )
1389
+ if _determine_whether_to_implement(
1390
+ cls, repr, auto_detect, ("__repr__",)
1391
+ ):
1392
+ builder.add_repr(repr_ns)
1393
+ if str is True:
1394
+ builder.add_str()
1395
+
1396
+ eq = _determine_whether_to_implement(
1397
+ cls, eq_, auto_detect, ("__eq__", "__ne__")
1398
+ )
1399
+ if not is_exc and eq is True:
1400
+ builder.add_eq()
1401
+ if not is_exc and _determine_whether_to_implement(
1402
+ cls, order_, auto_detect, ("__lt__", "__le__", "__gt__", "__ge__")
1403
+ ):
1404
+ builder.add_order()
1405
+
1406
+ builder.add_setattr()
1407
+
1408
+ nonlocal hash
1409
+ if (
1410
+ hash is None
1411
+ and auto_detect is True
1412
+ and _has_own_attribute(cls, "__hash__")
1413
+ ):
1414
+ hash = False
1415
+
1416
+ if hash is not True and hash is not False and hash is not None:
1417
+ # Can't use `hash in` because 1 == True for example.
1418
+ msg = "Invalid value for hash. Must be True, False, or None."
1419
+ raise TypeError(msg)
1420
+
1421
+ if hash is False or (hash is None and eq is False) or is_exc:
1422
+ # Don't do anything. Should fall back to __object__'s __hash__
1423
+ # which is by id.
1424
+ if cache_hash:
1425
+ msg = "Invalid value for cache_hash. To use hash caching, hashing must be either explicitly or implicitly enabled."
1426
+ raise TypeError(msg)
1427
+ elif hash is True or (
1428
+ hash is None and eq is True and is_frozen is True
1429
+ ):
1430
+ # Build a __hash__ if told so, or if it's safe.
1431
+ builder.add_hash()
1432
+ else:
1433
+ # Raise TypeError on attempts to hash.
1434
+ if cache_hash:
1435
+ msg = "Invalid value for cache_hash. To use hash caching, hashing must be either explicitly or implicitly enabled."
1436
+ raise TypeError(msg)
1437
+ builder.make_unhashable()
1438
+
1439
+ if _determine_whether_to_implement(
1440
+ cls, init, auto_detect, ("__init__",)
1441
+ ):
1442
+ builder.add_init()
1443
+ else:
1444
+ builder.add_attrs_init()
1445
+ if cache_hash:
1446
+ msg = "Invalid value for cache_hash. To use hash caching, init must be True."
1447
+ raise TypeError(msg)
1448
+
1449
+ if PY_3_13_PLUS and not _has_own_attribute(cls, "__replace__"):
1450
+ builder.add_replace()
1451
+
1452
+ if (
1453
+ PY_3_10_PLUS
1454
+ and match_args
1455
+ and not _has_own_attribute(cls, "__match_args__")
1456
+ ):
1457
+ builder.add_match_args()
1458
+
1459
+ return builder.build_class()
1460
+
1461
+ # maybe_cls's type depends on the usage of the decorator. It's a class
1462
+ # if it's used as `@attrs` but `None` if used as `@attrs()`.
1463
+ if maybe_cls is None:
1464
+ return wrap
1465
+
1466
+ return wrap(maybe_cls)
1467
+
1468
+
1469
+ _attrs = attrs
1470
+ """
1471
+ Internal alias so we can use it in functions that take an argument called
1472
+ *attrs*.
1473
+ """
1474
+
1475
+
1476
+ def _has_frozen_base_class(cls):
1477
+ """
1478
+ Check whether *cls* has a frozen ancestor by looking at its
1479
+ __setattr__.
1480
+ """
1481
+ return cls.__setattr__ is _frozen_setattrs
1482
+
1483
+
1484
+ def _generate_unique_filename(cls, func_name):
1485
+ """
1486
+ Create a "filename" suitable for a function being generated.
1487
+ """
1488
+ return (
1489
+ f"<attrs generated {func_name} {cls.__module__}."
1490
+ f"{getattr(cls, '__qualname__', cls.__name__)}>"
1491
+ )
1492
+
1493
+
1494
+ def _make_hash(cls, attrs, frozen, cache_hash):
1495
+ attrs = tuple(
1496
+ a for a in attrs if a.hash is True or (a.hash is None and a.eq is True)
1497
+ )
1498
+
1499
+ tab = " "
1500
+
1501
+ unique_filename = _generate_unique_filename(cls, "hash")
1502
+ type_hash = hash(unique_filename)
1503
+ # If eq is custom generated, we need to include the functions in globs
1504
+ globs = {}
1505
+
1506
+ hash_def = "def __hash__(self"
1507
+ hash_func = "hash(("
1508
+ closing_braces = "))"
1509
+ if not cache_hash:
1510
+ hash_def += "):"
1511
+ else:
1512
+ hash_def += ", *"
1513
+
1514
+ hash_def += ", _cache_wrapper=__import__('attr._make')._make._CacheHashWrapper):"
1515
+ hash_func = "_cache_wrapper(" + hash_func
1516
+ closing_braces += ")"
1517
+
1518
+ method_lines = [hash_def]
1519
+
1520
+ def append_hash_computation_lines(prefix, indent):
1521
+ """
1522
+ Generate the code for actually computing the hash code.
1523
+ Below this will either be returned directly or used to compute
1524
+ a value which is then cached, depending on the value of cache_hash
1525
+ """
1526
+
1527
+ method_lines.extend(
1528
+ [
1529
+ indent + prefix + hash_func,
1530
+ indent + f" {type_hash},",
1531
+ ]
1532
+ )
1533
+
1534
+ for a in attrs:
1535
+ if a.eq_key:
1536
+ cmp_name = f"_{a.name}_key"
1537
+ globs[cmp_name] = a.eq_key
1538
+ method_lines.append(
1539
+ indent + f" {cmp_name}(self.{a.name}),"
1540
+ )
1541
+ else:
1542
+ method_lines.append(indent + f" self.{a.name},")
1543
+
1544
+ method_lines.append(indent + " " + closing_braces)
1545
+
1546
+ if cache_hash:
1547
+ method_lines.append(tab + f"if self.{_HASH_CACHE_FIELD} is None:")
1548
+ if frozen:
1549
+ append_hash_computation_lines(
1550
+ f"object.__setattr__(self, '{_HASH_CACHE_FIELD}', ", tab * 2
1551
+ )
1552
+ method_lines.append(tab * 2 + ")") # close __setattr__
1553
+ else:
1554
+ append_hash_computation_lines(
1555
+ f"self.{_HASH_CACHE_FIELD} = ", tab * 2
1556
+ )
1557
+ method_lines.append(tab + f"return self.{_HASH_CACHE_FIELD}")
1558
+ else:
1559
+ append_hash_computation_lines("return ", tab)
1560
+
1561
+ script = "\n".join(method_lines)
1562
+ return _make_method("__hash__", script, unique_filename, globs)
1563
+
1564
+
1565
+ def _add_hash(cls, attrs):
1566
+ """
1567
+ Add a hash method to *cls*.
1568
+ """
1569
+ cls.__hash__ = _make_hash(cls, attrs, frozen=False, cache_hash=False)
1570
+ return cls
1571
+
1572
+
1573
+ def _make_ne():
1574
+ """
1575
+ Create __ne__ method.
1576
+ """
1577
+
1578
+ def __ne__(self, other):
1579
+ """
1580
+ Check equality and either forward a NotImplemented or
1581
+ return the result negated.
1582
+ """
1583
+ result = self.__eq__(other)
1584
+ if result is NotImplemented:
1585
+ return NotImplemented
1586
+
1587
+ return not result
1588
+
1589
+ return __ne__
1590
+
1591
+
1592
+ def _make_eq(cls, attrs):
1593
+ """
1594
+ Create __eq__ method for *cls* with *attrs*.
1595
+ """
1596
+ attrs = [a for a in attrs if a.eq]
1597
+
1598
+ unique_filename = _generate_unique_filename(cls, "eq")
1599
+ lines = [
1600
+ "def __eq__(self, other):",
1601
+ " if other.__class__ is not self.__class__:",
1602
+ " return NotImplemented",
1603
+ ]
1604
+
1605
+ globs = {}
1606
+ if attrs:
1607
+ lines.append(" return (")
1608
+ for a in attrs:
1609
+ if a.eq_key:
1610
+ cmp_name = f"_{a.name}_key"
1611
+ # Add the key function to the global namespace
1612
+ # of the evaluated function.
1613
+ globs[cmp_name] = a.eq_key
1614
+ lines.append(
1615
+ f" {cmp_name}(self.{a.name}) == {cmp_name}(other.{a.name})"
1616
+ )
1617
+ else:
1618
+ lines.append(f" self.{a.name} == other.{a.name}")
1619
+ if a is not attrs[-1]:
1620
+ lines[-1] = f"{lines[-1]} and"
1621
+ lines.append(" )")
1622
+ else:
1623
+ lines.append(" return True")
1624
+
1625
+ script = "\n".join(lines)
1626
+
1627
+ return _make_method("__eq__", script, unique_filename, globs)
1628
+
1629
+
1630
+ def _make_order(cls, attrs):
1631
+ """
1632
+ Create ordering methods for *cls* with *attrs*.
1633
+ """
1634
+ attrs = [a for a in attrs if a.order]
1635
+
1636
+ def attrs_to_tuple(obj):
1637
+ """
1638
+ Save us some typing.
1639
+ """
1640
+ return tuple(
1641
+ key(value) if key else value
1642
+ for value, key in (
1643
+ (getattr(obj, a.name), a.order_key) for a in attrs
1644
+ )
1645
+ )
1646
+
1647
+ def __lt__(self, other):
1648
+ """
1649
+ Automatically created by attrs.
1650
+ """
1651
+ if other.__class__ is self.__class__:
1652
+ return attrs_to_tuple(self) < attrs_to_tuple(other)
1653
+
1654
+ return NotImplemented
1655
+
1656
+ def __le__(self, other):
1657
+ """
1658
+ Automatically created by attrs.
1659
+ """
1660
+ if other.__class__ is self.__class__:
1661
+ return attrs_to_tuple(self) <= attrs_to_tuple(other)
1662
+
1663
+ return NotImplemented
1664
+
1665
+ def __gt__(self, other):
1666
+ """
1667
+ Automatically created by attrs.
1668
+ """
1669
+ if other.__class__ is self.__class__:
1670
+ return attrs_to_tuple(self) > attrs_to_tuple(other)
1671
+
1672
+ return NotImplemented
1673
+
1674
+ def __ge__(self, other):
1675
+ """
1676
+ Automatically created by attrs.
1677
+ """
1678
+ if other.__class__ is self.__class__:
1679
+ return attrs_to_tuple(self) >= attrs_to_tuple(other)
1680
+
1681
+ return NotImplemented
1682
+
1683
+ return __lt__, __le__, __gt__, __ge__
1684
+
1685
+
1686
+ def _add_eq(cls, attrs=None):
1687
+ """
1688
+ Add equality methods to *cls* with *attrs*.
1689
+ """
1690
+ if attrs is None:
1691
+ attrs = cls.__attrs_attrs__
1692
+
1693
+ cls.__eq__ = _make_eq(cls, attrs)
1694
+ cls.__ne__ = _make_ne()
1695
+
1696
+ return cls
1697
+
1698
+
1699
+ def _make_repr(attrs, ns, cls):
1700
+ unique_filename = _generate_unique_filename(cls, "repr")
1701
+ # Figure out which attributes to include, and which function to use to
1702
+ # format them. The a.repr value can be either bool or a custom
1703
+ # callable.
1704
+ attr_names_with_reprs = tuple(
1705
+ (a.name, (repr if a.repr is True else a.repr), a.init)
1706
+ for a in attrs
1707
+ if a.repr is not False
1708
+ )
1709
+ globs = {
1710
+ name + "_repr": r for name, r, _ in attr_names_with_reprs if r != repr
1711
+ }
1712
+ globs["_compat"] = _compat
1713
+ globs["AttributeError"] = AttributeError
1714
+ globs["NOTHING"] = NOTHING
1715
+ attribute_fragments = []
1716
+ for name, r, i in attr_names_with_reprs:
1717
+ accessor = (
1718
+ "self." + name if i else 'getattr(self, "' + name + '", NOTHING)'
1719
+ )
1720
+ fragment = (
1721
+ "%s={%s!r}" % (name, accessor)
1722
+ if r == repr
1723
+ else "%s={%s_repr(%s)}" % (name, name, accessor)
1724
+ )
1725
+ attribute_fragments.append(fragment)
1726
+ repr_fragment = ", ".join(attribute_fragments)
1727
+
1728
+ if ns is None:
1729
+ cls_name_fragment = '{self.__class__.__qualname__.rsplit(">.", 1)[-1]}'
1730
+ else:
1731
+ cls_name_fragment = ns + ".{self.__class__.__name__}"
1732
+
1733
+ lines = [
1734
+ "def __repr__(self):",
1735
+ " try:",
1736
+ " already_repring = _compat.repr_context.already_repring",
1737
+ " except AttributeError:",
1738
+ " already_repring = {id(self),}",
1739
+ " _compat.repr_context.already_repring = already_repring",
1740
+ " else:",
1741
+ " if id(self) in already_repring:",
1742
+ " return '...'",
1743
+ " else:",
1744
+ " already_repring.add(id(self))",
1745
+ " try:",
1746
+ f" return f'{cls_name_fragment}({repr_fragment})'",
1747
+ " finally:",
1748
+ " already_repring.remove(id(self))",
1749
+ ]
1750
+
1751
+ return _make_method(
1752
+ "__repr__", "\n".join(lines), unique_filename, globs=globs
1753
+ )
1754
+
1755
+
1756
+ def _add_repr(cls, ns=None, attrs=None):
1757
+ """
1758
+ Add a repr method to *cls*.
1759
+ """
1760
+ if attrs is None:
1761
+ attrs = cls.__attrs_attrs__
1762
+
1763
+ cls.__repr__ = _make_repr(attrs, ns, cls)
1764
+ return cls
1765
+
1766
+
1767
+ def fields(cls):
1768
+ """
1769
+ Return the tuple of *attrs* attributes for a class.
1770
+
1771
+ The tuple also allows accessing the fields by their names (see below for
1772
+ examples).
1773
+
1774
+ Args:
1775
+ cls (type): Class to introspect.
1776
+
1777
+ Raises:
1778
+ TypeError: If *cls* is not a class.
1779
+
1780
+ attrs.exceptions.NotAnAttrsClassError:
1781
+ If *cls* is not an *attrs* class.
1782
+
1783
+ Returns:
1784
+ tuple (with name accessors) of `attrs.Attribute`
1785
+
1786
+ .. versionchanged:: 16.2.0 Returned tuple allows accessing the fields
1787
+ by name.
1788
+ .. versionchanged:: 23.1.0 Add support for generic classes.
1789
+ """
1790
+ generic_base = get_generic_base(cls)
1791
+
1792
+ if generic_base is None and not isinstance(cls, type):
1793
+ msg = "Passed object must be a class."
1794
+ raise TypeError(msg)
1795
+
1796
+ attrs = getattr(cls, "__attrs_attrs__", None)
1797
+
1798
+ if attrs is None:
1799
+ if generic_base is not None:
1800
+ attrs = getattr(generic_base, "__attrs_attrs__", None)
1801
+ if attrs is not None:
1802
+ # Even though this is global state, stick it on here to speed
1803
+ # it up. We rely on `cls` being cached for this to be
1804
+ # efficient.
1805
+ cls.__attrs_attrs__ = attrs
1806
+ return attrs
1807
+ msg = f"{cls!r} is not an attrs-decorated class."
1808
+ raise NotAnAttrsClassError(msg)
1809
+
1810
+ return attrs
1811
+
1812
+
1813
+ def fields_dict(cls):
1814
+ """
1815
+ Return an ordered dictionary of *attrs* attributes for a class, whose keys
1816
+ are the attribute names.
1817
+
1818
+ Args:
1819
+ cls (type): Class to introspect.
1820
+
1821
+ Raises:
1822
+ TypeError: If *cls* is not a class.
1823
+
1824
+ attrs.exceptions.NotAnAttrsClassError:
1825
+ If *cls* is not an *attrs* class.
1826
+
1827
+ Returns:
1828
+ dict[str, attrs.Attribute]: Dict of attribute name to definition
1829
+
1830
+ .. versionadded:: 18.1.0
1831
+ """
1832
+ if not isinstance(cls, type):
1833
+ msg = "Passed object must be a class."
1834
+ raise TypeError(msg)
1835
+ attrs = getattr(cls, "__attrs_attrs__", None)
1836
+ if attrs is None:
1837
+ msg = f"{cls!r} is not an attrs-decorated class."
1838
+ raise NotAnAttrsClassError(msg)
1839
+ return {a.name: a for a in attrs}
1840
+
1841
+
1842
+ def validate(inst):
1843
+ """
1844
+ Validate all attributes on *inst* that have a validator.
1845
+
1846
+ Leaves all exceptions through.
1847
+
1848
+ Args:
1849
+ inst: Instance of a class with *attrs* attributes.
1850
+ """
1851
+ if _config._run_validators is False:
1852
+ return
1853
+
1854
+ for a in fields(inst.__class__):
1855
+ v = a.validator
1856
+ if v is not None:
1857
+ v(inst, a, getattr(inst, a.name))
1858
+
1859
+
1860
+ def _is_slot_attr(a_name, base_attr_map):
1861
+ """
1862
+ Check if the attribute name comes from a slot class.
1863
+ """
1864
+ cls = base_attr_map.get(a_name)
1865
+ return cls and "__slots__" in cls.__dict__
1866
+
1867
+
1868
+ def _make_init(
1869
+ cls,
1870
+ attrs,
1871
+ pre_init,
1872
+ pre_init_has_args,
1873
+ post_init,
1874
+ frozen,
1875
+ slots,
1876
+ cache_hash,
1877
+ base_attr_map,
1878
+ is_exc,
1879
+ cls_on_setattr,
1880
+ attrs_init,
1881
+ ):
1882
+ has_cls_on_setattr = (
1883
+ cls_on_setattr is not None and cls_on_setattr is not setters.NO_OP
1884
+ )
1885
+
1886
+ if frozen and has_cls_on_setattr:
1887
+ msg = "Frozen classes can't use on_setattr."
1888
+ raise ValueError(msg)
1889
+
1890
+ needs_cached_setattr = cache_hash or frozen
1891
+ filtered_attrs = []
1892
+ attr_dict = {}
1893
+ for a in attrs:
1894
+ if not a.init and a.default is NOTHING:
1895
+ continue
1896
+
1897
+ filtered_attrs.append(a)
1898
+ attr_dict[a.name] = a
1899
+
1900
+ if a.on_setattr is not None:
1901
+ if frozen is True:
1902
+ msg = "Frozen classes can't use on_setattr."
1903
+ raise ValueError(msg)
1904
+
1905
+ needs_cached_setattr = True
1906
+ elif has_cls_on_setattr and a.on_setattr is not setters.NO_OP:
1907
+ needs_cached_setattr = True
1908
+
1909
+ unique_filename = _generate_unique_filename(cls, "init")
1910
+
1911
+ script, globs, annotations = _attrs_to_init_script(
1912
+ filtered_attrs,
1913
+ frozen,
1914
+ slots,
1915
+ pre_init,
1916
+ pre_init_has_args,
1917
+ post_init,
1918
+ cache_hash,
1919
+ base_attr_map,
1920
+ is_exc,
1921
+ needs_cached_setattr,
1922
+ has_cls_on_setattr,
1923
+ "__attrs_init__" if attrs_init else "__init__",
1924
+ )
1925
+ if cls.__module__ in sys.modules:
1926
+ # This makes typing.get_type_hints(CLS.__init__) resolve string types.
1927
+ globs.update(sys.modules[cls.__module__].__dict__)
1928
+
1929
+ globs.update({"NOTHING": NOTHING, "attr_dict": attr_dict})
1930
+
1931
+ if needs_cached_setattr:
1932
+ # Save the lookup overhead in __init__ if we need to circumvent
1933
+ # setattr hooks.
1934
+ globs["_cached_setattr_get"] = _OBJ_SETATTR.__get__
1935
+
1936
+ init = _make_method(
1937
+ "__attrs_init__" if attrs_init else "__init__",
1938
+ script,
1939
+ unique_filename,
1940
+ globs,
1941
+ )
1942
+ init.__annotations__ = annotations
1943
+
1944
+ return init
1945
+
1946
+
1947
+ def _setattr(attr_name: str, value_var: str, has_on_setattr: bool) -> str:
1948
+ """
1949
+ Use the cached object.setattr to set *attr_name* to *value_var*.
1950
+ """
1951
+ return f"_setattr('{attr_name}', {value_var})"
1952
+
1953
+
1954
+ def _setattr_with_converter(
1955
+ attr_name: str, value_var: str, has_on_setattr: bool, converter: Converter
1956
+ ) -> str:
1957
+ """
1958
+ Use the cached object.setattr to set *attr_name* to *value_var*, but run
1959
+ its converter first.
1960
+ """
1961
+ return f"_setattr('{attr_name}', {converter._fmt_converter_call(attr_name, value_var)})"
1962
+
1963
+
1964
+ def _assign(attr_name: str, value: str, has_on_setattr: bool) -> str:
1965
+ """
1966
+ Unless *attr_name* has an on_setattr hook, use normal assignment. Otherwise
1967
+ relegate to _setattr.
1968
+ """
1969
+ if has_on_setattr:
1970
+ return _setattr(attr_name, value, True)
1971
+
1972
+ return f"self.{attr_name} = {value}"
1973
+
1974
+
1975
+ def _assign_with_converter(
1976
+ attr_name: str, value_var: str, has_on_setattr: bool, converter: Converter
1977
+ ) -> str:
1978
+ """
1979
+ Unless *attr_name* has an on_setattr hook, use normal assignment after
1980
+ conversion. Otherwise relegate to _setattr_with_converter.
1981
+ """
1982
+ if has_on_setattr:
1983
+ return _setattr_with_converter(attr_name, value_var, True, converter)
1984
+
1985
+ return f"self.{attr_name} = {converter._fmt_converter_call(attr_name, value_var)}"
1986
+
1987
+
1988
+ def _determine_setters(
1989
+ frozen: bool, slots: bool, base_attr_map: dict[str, type]
1990
+ ):
1991
+ """
1992
+ Determine the correct setter functions based on whether a class is frozen
1993
+ and/or slotted.
1994
+ """
1995
+ if frozen is True:
1996
+ if slots is True:
1997
+ return (), _setattr, _setattr_with_converter
1998
+
1999
+ # Dict frozen classes assign directly to __dict__.
2000
+ # But only if the attribute doesn't come from an ancestor slot
2001
+ # class.
2002
+ # Note _inst_dict will be used again below if cache_hash is True
2003
+
2004
+ def fmt_setter(
2005
+ attr_name: str, value_var: str, has_on_setattr: bool
2006
+ ) -> str:
2007
+ if _is_slot_attr(attr_name, base_attr_map):
2008
+ return _setattr(attr_name, value_var, has_on_setattr)
2009
+
2010
+ return f"_inst_dict['{attr_name}'] = {value_var}"
2011
+
2012
+ def fmt_setter_with_converter(
2013
+ attr_name: str,
2014
+ value_var: str,
2015
+ has_on_setattr: bool,
2016
+ converter: Converter,
2017
+ ) -> str:
2018
+ if has_on_setattr or _is_slot_attr(attr_name, base_attr_map):
2019
+ return _setattr_with_converter(
2020
+ attr_name, value_var, has_on_setattr, converter
2021
+ )
2022
+
2023
+ return f"_inst_dict['{attr_name}'] = {converter._fmt_converter_call(attr_name, value_var)}"
2024
+
2025
+ return (
2026
+ ("_inst_dict = self.__dict__",),
2027
+ fmt_setter,
2028
+ fmt_setter_with_converter,
2029
+ )
2030
+
2031
+ # Not frozen -- we can just assign directly.
2032
+ return (), _assign, _assign_with_converter
2033
+
2034
+
2035
+ def _attrs_to_init_script(
2036
+ attrs: list[Attribute],
2037
+ is_frozen: bool,
2038
+ is_slotted: bool,
2039
+ call_pre_init: bool,
2040
+ pre_init_has_args: bool,
2041
+ call_post_init: bool,
2042
+ does_cache_hash: bool,
2043
+ base_attr_map: dict[str, type],
2044
+ is_exc: bool,
2045
+ needs_cached_setattr: bool,
2046
+ has_cls_on_setattr: bool,
2047
+ method_name: str,
2048
+ ) -> tuple[str, dict, dict]:
2049
+ """
2050
+ Return a script of an initializer for *attrs*, a dict of globals, and
2051
+ annotations for the initializer.
2052
+
2053
+ The globals are required by the generated script.
2054
+ """
2055
+ lines = ["self.__attrs_pre_init__()"] if call_pre_init else []
2056
+
2057
+ if needs_cached_setattr:
2058
+ lines.append(
2059
+ # Circumvent the __setattr__ descriptor to save one lookup per
2060
+ # assignment. Note _setattr will be used again below if
2061
+ # does_cache_hash is True.
2062
+ "_setattr = _cached_setattr_get(self)"
2063
+ )
2064
+
2065
+ extra_lines, fmt_setter, fmt_setter_with_converter = _determine_setters(
2066
+ is_frozen, is_slotted, base_attr_map
2067
+ )
2068
+ lines.extend(extra_lines)
2069
+
2070
+ args = []
2071
+ kw_only_args = []
2072
+ attrs_to_validate = []
2073
+
2074
+ # This is a dictionary of names to validator and converter callables.
2075
+ # Injecting this into __init__ globals lets us avoid lookups.
2076
+ names_for_globals = {}
2077
+ annotations = {"return": None}
2078
+
2079
+ for a in attrs:
2080
+ if a.validator:
2081
+ attrs_to_validate.append(a)
2082
+
2083
+ attr_name = a.name
2084
+ has_on_setattr = a.on_setattr is not None or (
2085
+ a.on_setattr is not setters.NO_OP and has_cls_on_setattr
2086
+ )
2087
+ # a.alias is set to maybe-mangled attr_name in _ClassBuilder if not
2088
+ # explicitly provided
2089
+ arg_name = a.alias
2090
+
2091
+ has_factory = isinstance(a.default, Factory)
2092
+ maybe_self = "self" if has_factory and a.default.takes_self else ""
2093
+
2094
+ if a.converter is not None and not isinstance(a.converter, Converter):
2095
+ converter = Converter(a.converter)
2096
+ else:
2097
+ converter = a.converter
2098
+
2099
+ if a.init is False:
2100
+ if has_factory:
2101
+ init_factory_name = _INIT_FACTORY_PAT % (a.name,)
2102
+ if converter is not None:
2103
+ lines.append(
2104
+ fmt_setter_with_converter(
2105
+ attr_name,
2106
+ init_factory_name + f"({maybe_self})",
2107
+ has_on_setattr,
2108
+ converter,
2109
+ )
2110
+ )
2111
+ names_for_globals[converter._get_global_name(a.name)] = (
2112
+ converter.converter
2113
+ )
2114
+ else:
2115
+ lines.append(
2116
+ fmt_setter(
2117
+ attr_name,
2118
+ init_factory_name + f"({maybe_self})",
2119
+ has_on_setattr,
2120
+ )
2121
+ )
2122
+ names_for_globals[init_factory_name] = a.default.factory
2123
+ elif converter is not None:
2124
+ lines.append(
2125
+ fmt_setter_with_converter(
2126
+ attr_name,
2127
+ f"attr_dict['{attr_name}'].default",
2128
+ has_on_setattr,
2129
+ converter,
2130
+ )
2131
+ )
2132
+ names_for_globals[converter._get_global_name(a.name)] = (
2133
+ converter.converter
2134
+ )
2135
+ else:
2136
+ lines.append(
2137
+ fmt_setter(
2138
+ attr_name,
2139
+ f"attr_dict['{attr_name}'].default",
2140
+ has_on_setattr,
2141
+ )
2142
+ )
2143
+ elif a.default is not NOTHING and not has_factory:
2144
+ arg = f"{arg_name}=attr_dict['{attr_name}'].default"
2145
+ if a.kw_only:
2146
+ kw_only_args.append(arg)
2147
+ else:
2148
+ args.append(arg)
2149
+
2150
+ if converter is not None:
2151
+ lines.append(
2152
+ fmt_setter_with_converter(
2153
+ attr_name, arg_name, has_on_setattr, converter
2154
+ )
2155
+ )
2156
+ names_for_globals[converter._get_global_name(a.name)] = (
2157
+ converter.converter
2158
+ )
2159
+ else:
2160
+ lines.append(fmt_setter(attr_name, arg_name, has_on_setattr))
2161
+
2162
+ elif has_factory:
2163
+ arg = f"{arg_name}=NOTHING"
2164
+ if a.kw_only:
2165
+ kw_only_args.append(arg)
2166
+ else:
2167
+ args.append(arg)
2168
+ lines.append(f"if {arg_name} is not NOTHING:")
2169
+
2170
+ init_factory_name = _INIT_FACTORY_PAT % (a.name,)
2171
+ if converter is not None:
2172
+ lines.append(
2173
+ " "
2174
+ + fmt_setter_with_converter(
2175
+ attr_name, arg_name, has_on_setattr, converter
2176
+ )
2177
+ )
2178
+ lines.append("else:")
2179
+ lines.append(
2180
+ " "
2181
+ + fmt_setter_with_converter(
2182
+ attr_name,
2183
+ init_factory_name + "(" + maybe_self + ")",
2184
+ has_on_setattr,
2185
+ converter,
2186
+ )
2187
+ )
2188
+ names_for_globals[converter._get_global_name(a.name)] = (
2189
+ converter.converter
2190
+ )
2191
+ else:
2192
+ lines.append(
2193
+ " " + fmt_setter(attr_name, arg_name, has_on_setattr)
2194
+ )
2195
+ lines.append("else:")
2196
+ lines.append(
2197
+ " "
2198
+ + fmt_setter(
2199
+ attr_name,
2200
+ init_factory_name + "(" + maybe_self + ")",
2201
+ has_on_setattr,
2202
+ )
2203
+ )
2204
+ names_for_globals[init_factory_name] = a.default.factory
2205
+ else:
2206
+ if a.kw_only:
2207
+ kw_only_args.append(arg_name)
2208
+ else:
2209
+ args.append(arg_name)
2210
+
2211
+ if converter is not None:
2212
+ lines.append(
2213
+ fmt_setter_with_converter(
2214
+ attr_name, arg_name, has_on_setattr, converter
2215
+ )
2216
+ )
2217
+ names_for_globals[converter._get_global_name(a.name)] = (
2218
+ converter.converter
2219
+ )
2220
+ else:
2221
+ lines.append(fmt_setter(attr_name, arg_name, has_on_setattr))
2222
+
2223
+ if a.init is True:
2224
+ if a.type is not None and converter is None:
2225
+ annotations[arg_name] = a.type
2226
+ elif converter is not None and converter._first_param_type:
2227
+ # Use the type from the converter if present.
2228
+ annotations[arg_name] = converter._first_param_type
2229
+
2230
+ if attrs_to_validate: # we can skip this if there are no validators.
2231
+ names_for_globals["_config"] = _config
2232
+ lines.append("if _config._run_validators is True:")
2233
+ for a in attrs_to_validate:
2234
+ val_name = "__attr_validator_" + a.name
2235
+ attr_name = "__attr_" + a.name
2236
+ lines.append(f" {val_name}(self, {attr_name}, self.{a.name})")
2237
+ names_for_globals[val_name] = a.validator
2238
+ names_for_globals[attr_name] = a
2239
+
2240
+ if call_post_init:
2241
+ lines.append("self.__attrs_post_init__()")
2242
+
2243
+ # Because this is set only after __attrs_post_init__ is called, a crash
2244
+ # will result if post-init tries to access the hash code. This seemed
2245
+ # preferable to setting this beforehand, in which case alteration to field
2246
+ # values during post-init combined with post-init accessing the hash code
2247
+ # would result in silent bugs.
2248
+ if does_cache_hash:
2249
+ if is_frozen:
2250
+ if is_slotted:
2251
+ init_hash_cache = f"_setattr('{_HASH_CACHE_FIELD}', None)"
2252
+ else:
2253
+ init_hash_cache = f"_inst_dict['{_HASH_CACHE_FIELD}'] = None"
2254
+ else:
2255
+ init_hash_cache = f"self.{_HASH_CACHE_FIELD} = None"
2256
+ lines.append(init_hash_cache)
2257
+
2258
+ # For exceptions we rely on BaseException.__init__ for proper
2259
+ # initialization.
2260
+ if is_exc:
2261
+ vals = ",".join(f"self.{a.name}" for a in attrs if a.init)
2262
+
2263
+ lines.append(f"BaseException.__init__(self, {vals})")
2264
+
2265
+ args = ", ".join(args)
2266
+ pre_init_args = args
2267
+ if kw_only_args:
2268
+ # leading comma & kw_only args
2269
+ args += f"{', ' if args else ''}*, {', '.join(kw_only_args)}"
2270
+ pre_init_kw_only_args = ", ".join(
2271
+ [
2272
+ f"{kw_arg_name}={kw_arg_name}"
2273
+ # We need to remove the defaults from the kw_only_args.
2274
+ for kw_arg_name in (kwa.split("=")[0] for kwa in kw_only_args)
2275
+ ]
2276
+ )
2277
+ pre_init_args += ", " if pre_init_args else ""
2278
+ pre_init_args += pre_init_kw_only_args
2279
+
2280
+ if call_pre_init and pre_init_has_args:
2281
+ # If pre init method has arguments, pass same arguments as `__init__`.
2282
+ lines[0] = f"self.__attrs_pre_init__({pre_init_args})"
2283
+
2284
+ # Python <3.12 doesn't allow backslashes in f-strings.
2285
+ NL = "\n "
2286
+ return (
2287
+ f"""def {method_name}(self, {args}):
2288
+ {NL.join(lines) if lines else "pass"}
2289
+ """,
2290
+ names_for_globals,
2291
+ annotations,
2292
+ )
2293
+
2294
+
2295
+ def _default_init_alias_for(name: str) -> str:
2296
+ """
2297
+ The default __init__ parameter name for a field.
2298
+
2299
+ This performs private-name adjustment via leading-unscore stripping,
2300
+ and is the default value of Attribute.alias if not provided.
2301
+ """
2302
+
2303
+ return name.lstrip("_")
2304
+
2305
+
2306
+ class Attribute:
2307
+ """
2308
+ *Read-only* representation of an attribute.
2309
+
2310
+ .. warning::
2311
+
2312
+ You should never instantiate this class yourself.
2313
+
2314
+ The class has *all* arguments of `attr.ib` (except for ``factory`` which is
2315
+ only syntactic sugar for ``default=Factory(...)`` plus the following:
2316
+
2317
+ - ``name`` (`str`): The name of the attribute.
2318
+ - ``alias`` (`str`): The __init__ parameter name of the attribute, after
2319
+ any explicit overrides and default private-attribute-name handling.
2320
+ - ``inherited`` (`bool`): Whether or not that attribute has been inherited
2321
+ from a base class.
2322
+ - ``eq_key`` and ``order_key`` (`typing.Callable` or `None`): The
2323
+ callables that are used for comparing and ordering objects by this
2324
+ attribute, respectively. These are set by passing a callable to
2325
+ `attr.ib`'s ``eq``, ``order``, or ``cmp`` arguments. See also
2326
+ :ref:`comparison customization <custom-comparison>`.
2327
+
2328
+ Instances of this class are frequently used for introspection purposes
2329
+ like:
2330
+
2331
+ - `fields` returns a tuple of them.
2332
+ - Validators get them passed as the first argument.
2333
+ - The :ref:`field transformer <transform-fields>` hook receives a list of
2334
+ them.
2335
+ - The ``alias`` property exposes the __init__ parameter name of the field,
2336
+ with any overrides and default private-attribute handling applied.
2337
+
2338
+
2339
+ .. versionadded:: 20.1.0 *inherited*
2340
+ .. versionadded:: 20.1.0 *on_setattr*
2341
+ .. versionchanged:: 20.2.0 *inherited* is not taken into account for
2342
+ equality checks and hashing anymore.
2343
+ .. versionadded:: 21.1.0 *eq_key* and *order_key*
2344
+ .. versionadded:: 22.2.0 *alias*
2345
+
2346
+ For the full version history of the fields, see `attr.ib`.
2347
+ """
2348
+
2349
+ # These slots must NOT be reordered because we use them later for
2350
+ # instantiation.
2351
+ __slots__ = ( # noqa: RUF023
2352
+ "name",
2353
+ "default",
2354
+ "validator",
2355
+ "repr",
2356
+ "eq",
2357
+ "eq_key",
2358
+ "order",
2359
+ "order_key",
2360
+ "hash",
2361
+ "init",
2362
+ "metadata",
2363
+ "type",
2364
+ "converter",
2365
+ "kw_only",
2366
+ "inherited",
2367
+ "on_setattr",
2368
+ "alias",
2369
+ )
2370
+
2371
+ def __init__(
2372
+ self,
2373
+ name,
2374
+ default,
2375
+ validator,
2376
+ repr,
2377
+ cmp, # XXX: unused, remove along with other cmp code.
2378
+ hash,
2379
+ init,
2380
+ inherited,
2381
+ metadata=None,
2382
+ type=None,
2383
+ converter=None,
2384
+ kw_only=False,
2385
+ eq=None,
2386
+ eq_key=None,
2387
+ order=None,
2388
+ order_key=None,
2389
+ on_setattr=None,
2390
+ alias=None,
2391
+ ):
2392
+ eq, eq_key, order, order_key = _determine_attrib_eq_order(
2393
+ cmp, eq_key or eq, order_key or order, True
2394
+ )
2395
+
2396
+ # Cache this descriptor here to speed things up later.
2397
+ bound_setattr = _OBJ_SETATTR.__get__(self)
2398
+
2399
+ # Despite the big red warning, people *do* instantiate `Attribute`
2400
+ # themselves.
2401
+ bound_setattr("name", name)
2402
+ bound_setattr("default", default)
2403
+ bound_setattr("validator", validator)
2404
+ bound_setattr("repr", repr)
2405
+ bound_setattr("eq", eq)
2406
+ bound_setattr("eq_key", eq_key)
2407
+ bound_setattr("order", order)
2408
+ bound_setattr("order_key", order_key)
2409
+ bound_setattr("hash", hash)
2410
+ bound_setattr("init", init)
2411
+ bound_setattr("converter", converter)
2412
+ bound_setattr(
2413
+ "metadata",
2414
+ (
2415
+ types.MappingProxyType(dict(metadata)) # Shallow copy
2416
+ if metadata
2417
+ else _EMPTY_METADATA_SINGLETON
2418
+ ),
2419
+ )
2420
+ bound_setattr("type", type)
2421
+ bound_setattr("kw_only", kw_only)
2422
+ bound_setattr("inherited", inherited)
2423
+ bound_setattr("on_setattr", on_setattr)
2424
+ bound_setattr("alias", alias)
2425
+
2426
+ def __setattr__(self, name, value):
2427
+ raise FrozenInstanceError
2428
+
2429
+ @classmethod
2430
+ def from_counting_attr(cls, name, ca, type=None):
2431
+ # type holds the annotated value. deal with conflicts:
2432
+ if type is None:
2433
+ type = ca.type
2434
+ elif ca.type is not None:
2435
+ msg = "Type annotation and type argument cannot both be present"
2436
+ raise ValueError(msg)
2437
+ inst_dict = {
2438
+ k: getattr(ca, k)
2439
+ for k in Attribute.__slots__
2440
+ if k
2441
+ not in (
2442
+ "name",
2443
+ "validator",
2444
+ "default",
2445
+ "type",
2446
+ "inherited",
2447
+ ) # exclude methods and deprecated alias
2448
+ }
2449
+ return cls(
2450
+ name=name,
2451
+ validator=ca._validator,
2452
+ default=ca._default,
2453
+ type=type,
2454
+ cmp=None,
2455
+ inherited=False,
2456
+ **inst_dict,
2457
+ )
2458
+
2459
+ # Don't use attrs.evolve since fields(Attribute) doesn't work
2460
+ def evolve(self, **changes):
2461
+ """
2462
+ Copy *self* and apply *changes*.
2463
+
2464
+ This works similarly to `attrs.evolve` but that function does not work
2465
+ with :class:`attrs.Attribute`.
2466
+
2467
+ It is mainly meant to be used for `transform-fields`.
2468
+
2469
+ .. versionadded:: 20.3.0
2470
+ """
2471
+ new = copy.copy(self)
2472
+
2473
+ new._setattrs(changes.items())
2474
+
2475
+ return new
2476
+
2477
+ # Don't use _add_pickle since fields(Attribute) doesn't work
2478
+ def __getstate__(self):
2479
+ """
2480
+ Play nice with pickle.
2481
+ """
2482
+ return tuple(
2483
+ getattr(self, name) if name != "metadata" else dict(self.metadata)
2484
+ for name in self.__slots__
2485
+ )
2486
+
2487
+ def __setstate__(self, state):
2488
+ """
2489
+ Play nice with pickle.
2490
+ """
2491
+ self._setattrs(zip(self.__slots__, state))
2492
+
2493
+ def _setattrs(self, name_values_pairs):
2494
+ bound_setattr = _OBJ_SETATTR.__get__(self)
2495
+ for name, value in name_values_pairs:
2496
+ if name != "metadata":
2497
+ bound_setattr(name, value)
2498
+ else:
2499
+ bound_setattr(
2500
+ name,
2501
+ (
2502
+ types.MappingProxyType(dict(value))
2503
+ if value
2504
+ else _EMPTY_METADATA_SINGLETON
2505
+ ),
2506
+ )
2507
+
2508
+
2509
+ _a = [
2510
+ Attribute(
2511
+ name=name,
2512
+ default=NOTHING,
2513
+ validator=None,
2514
+ repr=True,
2515
+ cmp=None,
2516
+ eq=True,
2517
+ order=False,
2518
+ hash=(name != "metadata"),
2519
+ init=True,
2520
+ inherited=False,
2521
+ alias=_default_init_alias_for(name),
2522
+ )
2523
+ for name in Attribute.__slots__
2524
+ ]
2525
+
2526
+ Attribute = _add_hash(
2527
+ _add_eq(
2528
+ _add_repr(Attribute, attrs=_a),
2529
+ attrs=[a for a in _a if a.name != "inherited"],
2530
+ ),
2531
+ attrs=[a for a in _a if a.hash and a.name != "inherited"],
2532
+ )
2533
+
2534
+
2535
+ class _CountingAttr:
2536
+ """
2537
+ Intermediate representation of attributes that uses a counter to preserve
2538
+ the order in which the attributes have been defined.
2539
+
2540
+ *Internal* data structure of the attrs library. Running into is most
2541
+ likely the result of a bug like a forgotten `@attr.s` decorator.
2542
+ """
2543
+
2544
+ __slots__ = (
2545
+ "_default",
2546
+ "_validator",
2547
+ "alias",
2548
+ "converter",
2549
+ "counter",
2550
+ "eq",
2551
+ "eq_key",
2552
+ "hash",
2553
+ "init",
2554
+ "kw_only",
2555
+ "metadata",
2556
+ "on_setattr",
2557
+ "order",
2558
+ "order_key",
2559
+ "repr",
2560
+ "type",
2561
+ )
2562
+ __attrs_attrs__ = (
2563
+ *tuple(
2564
+ Attribute(
2565
+ name=name,
2566
+ alias=_default_init_alias_for(name),
2567
+ default=NOTHING,
2568
+ validator=None,
2569
+ repr=True,
2570
+ cmp=None,
2571
+ hash=True,
2572
+ init=True,
2573
+ kw_only=False,
2574
+ eq=True,
2575
+ eq_key=None,
2576
+ order=False,
2577
+ order_key=None,
2578
+ inherited=False,
2579
+ on_setattr=None,
2580
+ )
2581
+ for name in (
2582
+ "counter",
2583
+ "_default",
2584
+ "repr",
2585
+ "eq",
2586
+ "order",
2587
+ "hash",
2588
+ "init",
2589
+ "on_setattr",
2590
+ "alias",
2591
+ )
2592
+ ),
2593
+ Attribute(
2594
+ name="metadata",
2595
+ alias="metadata",
2596
+ default=None,
2597
+ validator=None,
2598
+ repr=True,
2599
+ cmp=None,
2600
+ hash=False,
2601
+ init=True,
2602
+ kw_only=False,
2603
+ eq=True,
2604
+ eq_key=None,
2605
+ order=False,
2606
+ order_key=None,
2607
+ inherited=False,
2608
+ on_setattr=None,
2609
+ ),
2610
+ )
2611
+ cls_counter = 0
2612
+
2613
+ def __init__(
2614
+ self,
2615
+ default,
2616
+ validator,
2617
+ repr,
2618
+ cmp,
2619
+ hash,
2620
+ init,
2621
+ converter,
2622
+ metadata,
2623
+ type,
2624
+ kw_only,
2625
+ eq,
2626
+ eq_key,
2627
+ order,
2628
+ order_key,
2629
+ on_setattr,
2630
+ alias,
2631
+ ):
2632
+ _CountingAttr.cls_counter += 1
2633
+ self.counter = _CountingAttr.cls_counter
2634
+ self._default = default
2635
+ self._validator = validator
2636
+ self.converter = converter
2637
+ self.repr = repr
2638
+ self.eq = eq
2639
+ self.eq_key = eq_key
2640
+ self.order = order
2641
+ self.order_key = order_key
2642
+ self.hash = hash
2643
+ self.init = init
2644
+ self.metadata = metadata
2645
+ self.type = type
2646
+ self.kw_only = kw_only
2647
+ self.on_setattr = on_setattr
2648
+ self.alias = alias
2649
+
2650
+ def validator(self, meth):
2651
+ """
2652
+ Decorator that adds *meth* to the list of validators.
2653
+
2654
+ Returns *meth* unchanged.
2655
+
2656
+ .. versionadded:: 17.1.0
2657
+ """
2658
+ if self._validator is None:
2659
+ self._validator = meth
2660
+ else:
2661
+ self._validator = and_(self._validator, meth)
2662
+ return meth
2663
+
2664
+ def default(self, meth):
2665
+ """
2666
+ Decorator that allows to set the default for an attribute.
2667
+
2668
+ Returns *meth* unchanged.
2669
+
2670
+ Raises:
2671
+ DefaultAlreadySetError: If default has been set before.
2672
+
2673
+ .. versionadded:: 17.1.0
2674
+ """
2675
+ if self._default is not NOTHING:
2676
+ raise DefaultAlreadySetError
2677
+
2678
+ self._default = Factory(meth, takes_self=True)
2679
+
2680
+ return meth
2681
+
2682
+
2683
+ _CountingAttr = _add_eq(_add_repr(_CountingAttr))
2684
+
2685
+
2686
+ class Factory:
2687
+ """
2688
+ Stores a factory callable.
2689
+
2690
+ If passed as the default value to `attrs.field`, the factory is used to
2691
+ generate a new value.
2692
+
2693
+ Args:
2694
+ factory (typing.Callable):
2695
+ A callable that takes either none or exactly one mandatory
2696
+ positional argument depending on *takes_self*.
2697
+
2698
+ takes_self (bool):
2699
+ Pass the partially initialized instance that is being initialized
2700
+ as a positional argument.
2701
+
2702
+ .. versionadded:: 17.1.0 *takes_self*
2703
+ """
2704
+
2705
+ __slots__ = ("factory", "takes_self")
2706
+
2707
+ def __init__(self, factory, takes_self=False):
2708
+ self.factory = factory
2709
+ self.takes_self = takes_self
2710
+
2711
+ def __getstate__(self):
2712
+ """
2713
+ Play nice with pickle.
2714
+ """
2715
+ return tuple(getattr(self, name) for name in self.__slots__)
2716
+
2717
+ def __setstate__(self, state):
2718
+ """
2719
+ Play nice with pickle.
2720
+ """
2721
+ for name, value in zip(self.__slots__, state):
2722
+ setattr(self, name, value)
2723
+
2724
+
2725
+ _f = [
2726
+ Attribute(
2727
+ name=name,
2728
+ default=NOTHING,
2729
+ validator=None,
2730
+ repr=True,
2731
+ cmp=None,
2732
+ eq=True,
2733
+ order=False,
2734
+ hash=True,
2735
+ init=True,
2736
+ inherited=False,
2737
+ )
2738
+ for name in Factory.__slots__
2739
+ ]
2740
+
2741
+ Factory = _add_hash(_add_eq(_add_repr(Factory, attrs=_f), attrs=_f), attrs=_f)
2742
+
2743
+
2744
+ class Converter:
2745
+ """
2746
+ Stores a converter callable.
2747
+
2748
+ Allows for the wrapped converter to take additional arguments. The
2749
+ arguments are passed in the order they are documented.
2750
+
2751
+ Args:
2752
+ converter (Callable): A callable that converts the passed value.
2753
+
2754
+ takes_self (bool):
2755
+ Pass the partially initialized instance that is being initialized
2756
+ as a positional argument. (default: `False`)
2757
+
2758
+ takes_field (bool):
2759
+ Pass the field definition (an :class:`Attribute`) into the
2760
+ converter as a positional argument. (default: `False`)
2761
+
2762
+ .. versionadded:: 24.1.0
2763
+ """
2764
+
2765
+ __slots__ = (
2766
+ "__call__",
2767
+ "_first_param_type",
2768
+ "_global_name",
2769
+ "converter",
2770
+ "takes_field",
2771
+ "takes_self",
2772
+ )
2773
+
2774
+ def __init__(self, converter, *, takes_self=False, takes_field=False):
2775
+ self.converter = converter
2776
+ self.takes_self = takes_self
2777
+ self.takes_field = takes_field
2778
+
2779
+ ex = _AnnotationExtractor(converter)
2780
+ self._first_param_type = ex.get_first_param_type()
2781
+
2782
+ if not (self.takes_self or self.takes_field):
2783
+ self.__call__ = lambda value, _, __: self.converter(value)
2784
+ elif self.takes_self and not self.takes_field:
2785
+ self.__call__ = lambda value, instance, __: self.converter(
2786
+ value, instance
2787
+ )
2788
+ elif not self.takes_self and self.takes_field:
2789
+ self.__call__ = lambda value, __, field: self.converter(
2790
+ value, field
2791
+ )
2792
+ else:
2793
+ self.__call__ = lambda value, instance, field: self.converter(
2794
+ value, instance, field
2795
+ )
2796
+
2797
+ rt = ex.get_return_type()
2798
+ if rt is not None:
2799
+ self.__call__.__annotations__["return"] = rt
2800
+
2801
+ @staticmethod
2802
+ def _get_global_name(attr_name: str) -> str:
2803
+ """
2804
+ Return the name that a converter for an attribute name *attr_name*
2805
+ would have.
2806
+ """
2807
+ return f"__attr_converter_{attr_name}"
2808
+
2809
+ def _fmt_converter_call(self, attr_name: str, value_var: str) -> str:
2810
+ """
2811
+ Return a string that calls the converter for an attribute name
2812
+ *attr_name* and the value in variable named *value_var* according to
2813
+ `self.takes_self` and `self.takes_field`.
2814
+ """
2815
+ if not (self.takes_self or self.takes_field):
2816
+ return f"{self._get_global_name(attr_name)}({value_var})"
2817
+
2818
+ if self.takes_self and self.takes_field:
2819
+ return f"{self._get_global_name(attr_name)}({value_var}, self, attr_dict['{attr_name}'])"
2820
+
2821
+ if self.takes_self:
2822
+ return f"{self._get_global_name(attr_name)}({value_var}, self)"
2823
+
2824
+ return f"{self._get_global_name(attr_name)}({value_var}, attr_dict['{attr_name}'])"
2825
+
2826
+ def __getstate__(self):
2827
+ """
2828
+ Return a dict containing only converter and takes_self -- the rest gets
2829
+ computed when loading.
2830
+ """
2831
+ return {
2832
+ "converter": self.converter,
2833
+ "takes_self": self.takes_self,
2834
+ "takes_field": self.takes_field,
2835
+ }
2836
+
2837
+ def __setstate__(self, state):
2838
+ """
2839
+ Load instance from state.
2840
+ """
2841
+ self.__init__(**state)
2842
+
2843
+
2844
+ _f = [
2845
+ Attribute(
2846
+ name=name,
2847
+ default=NOTHING,
2848
+ validator=None,
2849
+ repr=True,
2850
+ cmp=None,
2851
+ eq=True,
2852
+ order=False,
2853
+ hash=True,
2854
+ init=True,
2855
+ inherited=False,
2856
+ )
2857
+ for name in ("converter", "takes_self", "takes_field")
2858
+ ]
2859
+
2860
+ Converter = _add_hash(
2861
+ _add_eq(_add_repr(Converter, attrs=_f), attrs=_f), attrs=_f
2862
+ )
2863
+
2864
+
2865
+ def make_class(
2866
+ name, attrs, bases=(object,), class_body=None, **attributes_arguments
2867
+ ):
2868
+ r"""
2869
+ A quick way to create a new class called *name* with *attrs*.
2870
+
2871
+ .. note::
2872
+
2873
+ ``make_class()`` is a thin wrapper around `attr.s`, not `attrs.define`
2874
+ which means that it doesn't come with some of the improved defaults.
2875
+
2876
+ For example, if you want the same ``on_setattr`` behavior as in
2877
+ `attrs.define`, you have to pass the hooks yourself: ``make_class(...,
2878
+ on_setattr=setters.pipe(setters.convert, setters.validate)``
2879
+
2880
+ Args:
2881
+ name (str): The name for the new class.
2882
+
2883
+ attrs (list | dict):
2884
+ A list of names or a dictionary of mappings of names to `attr.ib`\
2885
+ s / `attrs.field`\ s.
2886
+
2887
+ The order is deduced from the order of the names or attributes
2888
+ inside *attrs*. Otherwise the order of the definition of the
2889
+ attributes is used.
2890
+
2891
+ bases (tuple[type, ...]): Classes that the new class will subclass.
2892
+
2893
+ class_body (dict):
2894
+ An optional dictionary of class attributes for the new class.
2895
+
2896
+ attributes_arguments: Passed unmodified to `attr.s`.
2897
+
2898
+ Returns:
2899
+ type: A new class with *attrs*.
2900
+
2901
+ .. versionadded:: 17.1.0 *bases*
2902
+ .. versionchanged:: 18.1.0 If *attrs* is ordered, the order is retained.
2903
+ .. versionchanged:: 23.2.0 *class_body*
2904
+ """
2905
+ if isinstance(attrs, dict):
2906
+ cls_dict = attrs
2907
+ elif isinstance(attrs, (list, tuple)):
2908
+ cls_dict = {a: attrib() for a in attrs}
2909
+ else:
2910
+ msg = "attrs argument must be a dict or a list."
2911
+ raise TypeError(msg)
2912
+
2913
+ pre_init = cls_dict.pop("__attrs_pre_init__", None)
2914
+ post_init = cls_dict.pop("__attrs_post_init__", None)
2915
+ user_init = cls_dict.pop("__init__", None)
2916
+
2917
+ body = {}
2918
+ if class_body is not None:
2919
+ body.update(class_body)
2920
+ if pre_init is not None:
2921
+ body["__attrs_pre_init__"] = pre_init
2922
+ if post_init is not None:
2923
+ body["__attrs_post_init__"] = post_init
2924
+ if user_init is not None:
2925
+ body["__init__"] = user_init
2926
+
2927
+ type_ = types.new_class(name, bases, {}, lambda ns: ns.update(body))
2928
+
2929
+ # For pickling to work, the __module__ variable needs to be set to the
2930
+ # frame where the class is created. Bypass this step in environments where
2931
+ # sys._getframe is not defined (Jython for example) or sys._getframe is not
2932
+ # defined for arguments greater than 0 (IronPython).
2933
+ with contextlib.suppress(AttributeError, ValueError):
2934
+ type_.__module__ = sys._getframe(1).f_globals.get(
2935
+ "__name__", "__main__"
2936
+ )
2937
+
2938
+ # We do it here for proper warnings with meaningful stacklevel.
2939
+ cmp = attributes_arguments.pop("cmp", None)
2940
+ (
2941
+ attributes_arguments["eq"],
2942
+ attributes_arguments["order"],
2943
+ ) = _determine_attrs_eq_order(
2944
+ cmp,
2945
+ attributes_arguments.get("eq"),
2946
+ attributes_arguments.get("order"),
2947
+ True,
2948
+ )
2949
+
2950
+ cls = _attrs(these=cls_dict, **attributes_arguments)(type_)
2951
+ # Only add type annotations now or "_attrs()" will complain:
2952
+ cls.__annotations__ = {
2953
+ k: v.type for k, v in cls_dict.items() if v.type is not None
2954
+ }
2955
+ return cls
2956
+
2957
+
2958
+ # These are required by within this module so we define them here and merely
2959
+ # import into .validators / .converters.
2960
+
2961
+
2962
+ @attrs(slots=True, unsafe_hash=True)
2963
+ class _AndValidator:
2964
+ """
2965
+ Compose many validators to a single one.
2966
+ """
2967
+
2968
+ _validators = attrib()
2969
+
2970
+ def __call__(self, inst, attr, value):
2971
+ for v in self._validators:
2972
+ v(inst, attr, value)
2973
+
2974
+
2975
+ def and_(*validators):
2976
+ """
2977
+ A validator that composes multiple validators into one.
2978
+
2979
+ When called on a value, it runs all wrapped validators.
2980
+
2981
+ Args:
2982
+ validators (~collections.abc.Iterable[typing.Callable]):
2983
+ Arbitrary number of validators.
2984
+
2985
+ .. versionadded:: 17.1.0
2986
+ """
2987
+ vals = []
2988
+ for validator in validators:
2989
+ vals.extend(
2990
+ validator._validators
2991
+ if isinstance(validator, _AndValidator)
2992
+ else [validator]
2993
+ )
2994
+
2995
+ return _AndValidator(tuple(vals))
2996
+
2997
+
2998
+ def pipe(*converters):
2999
+ """
3000
+ A converter that composes multiple converters into one.
3001
+
3002
+ When called on a value, it runs all wrapped converters, returning the
3003
+ *last* value.
3004
+
3005
+ Type annotations will be inferred from the wrapped converters', if they
3006
+ have any.
3007
+
3008
+ converters (~collections.abc.Iterable[typing.Callable]):
3009
+ Arbitrary number of converters.
3010
+
3011
+ .. versionadded:: 20.1.0
3012
+ """
3013
+
3014
+ return_instance = any(isinstance(c, Converter) for c in converters)
3015
+
3016
+ if return_instance:
3017
+
3018
+ def pipe_converter(val, inst, field):
3019
+ for c in converters:
3020
+ val = (
3021
+ c(val, inst, field) if isinstance(c, Converter) else c(val)
3022
+ )
3023
+
3024
+ return val
3025
+
3026
+ else:
3027
+
3028
+ def pipe_converter(val):
3029
+ for c in converters:
3030
+ val = c(val)
3031
+
3032
+ return val
3033
+
3034
+ if not converters:
3035
+ # If the converter list is empty, pipe_converter is the identity.
3036
+ A = typing.TypeVar("A")
3037
+ pipe_converter.__annotations__.update({"val": A, "return": A})
3038
+ else:
3039
+ # Get parameter type from first converter.
3040
+ t = _AnnotationExtractor(converters[0]).get_first_param_type()
3041
+ if t:
3042
+ pipe_converter.__annotations__["val"] = t
3043
+
3044
+ last = converters[-1]
3045
+ if not PY_3_11_PLUS and isinstance(last, Converter):
3046
+ last = last.__call__
3047
+
3048
+ # Get return type from last converter.
3049
+ rt = _AnnotationExtractor(last).get_return_type()
3050
+ if rt:
3051
+ pipe_converter.__annotations__["return"] = rt
3052
+
3053
+ if return_instance:
3054
+ return Converter(pipe_converter, takes_self=True, takes_field=True)
3055
+ return pipe_converter
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/_next_gen.py ADDED
@@ -0,0 +1,623 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ """
4
+ These are keyword-only APIs that call `attr.s` and `attr.ib` with different
5
+ default values.
6
+ """
7
+
8
+ from functools import partial
9
+
10
+ from . import setters
11
+ from ._funcs import asdict as _asdict
12
+ from ._funcs import astuple as _astuple
13
+ from ._make import (
14
+ _DEFAULT_ON_SETATTR,
15
+ NOTHING,
16
+ _frozen_setattrs,
17
+ attrib,
18
+ attrs,
19
+ )
20
+ from .exceptions import UnannotatedAttributeError
21
+
22
+
23
+ def 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 True or 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
+
412
+ mutable = define
413
+ frozen = partial(define, frozen=True, on_setattr=None)
414
+
415
+
416
+ def 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
+
598
+ def 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
+
614
+ def 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
+ )
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/_typing_compat.pyi ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, ClassVar, Protocol
2
+
3
+ # MYPY is a special constant in mypy which works the same way as `TYPE_CHECKING`.
4
+ MYPY = False
5
+
6
+ if MYPY:
7
+ # A protocol to be able to statically accept an attrs class.
8
+ class AttrsInstance_(Protocol):
9
+ __attrs_attrs__: ClassVar[Any]
10
+
11
+ else:
12
+ # For type checkers without plug-in support use an empty protocol that
13
+ # will (hopefully) be combined into a union.
14
+ class AttrsInstance_(Protocol):
15
+ pass
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/_version_info.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+
4
+ from functools import total_ordering
5
+
6
+ from ._funcs import astuple
7
+ from ._make import attrib, attrs
8
+
9
+
10
+ @total_ordering
11
+ @attrs(eq=False, order=False, slots=True, frozen=True)
12
+ class VersionInfo:
13
+ """
14
+ A version object that can be compared to tuple of length 1--4:
15
+
16
+ >>> attr.VersionInfo(19, 1, 0, "final") <= (19, 2)
17
+ True
18
+ >>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1)
19
+ True
20
+ >>> vi = attr.VersionInfo(19, 2, 0, "final")
21
+ >>> vi < (19, 1, 1)
22
+ False
23
+ >>> vi < (19,)
24
+ False
25
+ >>> vi == (19, 2,)
26
+ True
27
+ >>> vi == (19, 2, 1)
28
+ False
29
+
30
+ .. versionadded:: 19.2
31
+ """
32
+
33
+ year = attrib(type=int)
34
+ minor = attrib(type=int)
35
+ micro = attrib(type=int)
36
+ releaselevel = attrib(type=str)
37
+
38
+ @classmethod
39
+ def _from_version_string(cls, s):
40
+ """
41
+ Parse *s* and return a _VersionInfo.
42
+ """
43
+ v = s.split(".")
44
+ if len(v) == 3:
45
+ v.append("final")
46
+
47
+ return cls(
48
+ year=int(v[0]), minor=int(v[1]), micro=int(v[2]), releaselevel=v[3]
49
+ )
50
+
51
+ def _ensure_tuple(self, other):
52
+ """
53
+ Ensure *other* is a tuple of a valid length.
54
+
55
+ Returns a possibly transformed *other* and ourselves as a tuple of
56
+ the same length as *other*.
57
+ """
58
+
59
+ if self.__class__ is other.__class__:
60
+ other = astuple(other)
61
+
62
+ if not isinstance(other, tuple):
63
+ raise NotImplementedError
64
+
65
+ if not (1 <= len(other) <= 4):
66
+ raise NotImplementedError
67
+
68
+ return astuple(self)[: len(other)], other
69
+
70
+ def __eq__(self, other):
71
+ try:
72
+ us, them = self._ensure_tuple(other)
73
+ except NotImplementedError:
74
+ return NotImplemented
75
+
76
+ return us == them
77
+
78
+ def __lt__(self, other):
79
+ try:
80
+ us, them = self._ensure_tuple(other)
81
+ except NotImplementedError:
82
+ return NotImplemented
83
+
84
+ # Since alphabetically "dev0" < "final" < "post1" < "post2", we don't
85
+ # have to do anything special with releaselevel for now.
86
+ return us < them
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/converters.py ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ """
4
+ Commonly useful converters.
5
+ """
6
+
7
+ import typing
8
+
9
+ from ._compat import _AnnotationExtractor
10
+ from ._make import NOTHING, Converter, Factory, pipe
11
+
12
+
13
+ __all__ = [
14
+ "default_if_none",
15
+ "optional",
16
+ "pipe",
17
+ "to_bool",
18
+ ]
19
+
20
+
21
+ def optional(converter):
22
+ """
23
+ A converter that allows an attribute to be optional. An optional attribute
24
+ is one which can be set to `None`.
25
+
26
+ Type annotations will be inferred from the wrapped converter's, if it has
27
+ any.
28
+
29
+ Args:
30
+ converter (typing.Callable):
31
+ the converter that is used for non-`None` values.
32
+
33
+ .. versionadded:: 17.1.0
34
+ """
35
+
36
+ if isinstance(converter, Converter):
37
+
38
+ def optional_converter(val, inst, field):
39
+ if val is None:
40
+ return None
41
+ return converter(val, inst, field)
42
+
43
+ else:
44
+
45
+ def optional_converter(val):
46
+ if val is None:
47
+ return None
48
+ return converter(val)
49
+
50
+ xtr = _AnnotationExtractor(converter)
51
+
52
+ t = xtr.get_first_param_type()
53
+ if t:
54
+ optional_converter.__annotations__["val"] = typing.Optional[t]
55
+
56
+ rt = xtr.get_return_type()
57
+ if rt:
58
+ optional_converter.__annotations__["return"] = typing.Optional[rt]
59
+
60
+ if isinstance(converter, Converter):
61
+ return Converter(optional_converter, takes_self=True, takes_field=True)
62
+
63
+ return optional_converter
64
+
65
+
66
+ def default_if_none(default=NOTHING, factory=None):
67
+ """
68
+ A converter that allows to replace `None` values by *default* or the result
69
+ of *factory*.
70
+
71
+ Args:
72
+ default:
73
+ Value to be used if `None` is passed. Passing an instance of
74
+ `attrs.Factory` is supported, however the ``takes_self`` option is
75
+ *not*.
76
+
77
+ factory (typing.Callable):
78
+ A callable that takes no parameters whose result is used if `None`
79
+ is passed.
80
+
81
+ Raises:
82
+ TypeError: If **neither** *default* or *factory* is passed.
83
+
84
+ TypeError: If **both** *default* and *factory* are passed.
85
+
86
+ ValueError:
87
+ If an instance of `attrs.Factory` is passed with
88
+ ``takes_self=True``.
89
+
90
+ .. versionadded:: 18.2.0
91
+ """
92
+ if default is NOTHING and factory is None:
93
+ msg = "Must pass either `default` or `factory`."
94
+ raise TypeError(msg)
95
+
96
+ if default is not NOTHING and factory is not None:
97
+ msg = "Must pass either `default` or `factory` but not both."
98
+ raise TypeError(msg)
99
+
100
+ if factory is not None:
101
+ default = Factory(factory)
102
+
103
+ if isinstance(default, Factory):
104
+ if default.takes_self:
105
+ msg = "`takes_self` is not supported by default_if_none."
106
+ raise ValueError(msg)
107
+
108
+ def default_if_none_converter(val):
109
+ if val is not None:
110
+ return val
111
+
112
+ return default.factory()
113
+
114
+ else:
115
+
116
+ def default_if_none_converter(val):
117
+ if val is not None:
118
+ return val
119
+
120
+ return default
121
+
122
+ return default_if_none_converter
123
+
124
+
125
+ def to_bool(val):
126
+ """
127
+ Convert "boolean" strings (for example, from environment variables) to real
128
+ booleans.
129
+
130
+ Values mapping to `True`:
131
+
132
+ - ``True``
133
+ - ``"true"`` / ``"t"``
134
+ - ``"yes"`` / ``"y"``
135
+ - ``"on"``
136
+ - ``"1"``
137
+ - ``1``
138
+
139
+ Values mapping to `False`:
140
+
141
+ - ``False``
142
+ - ``"false"`` / ``"f"``
143
+ - ``"no"`` / ``"n"``
144
+ - ``"off"``
145
+ - ``"0"``
146
+ - ``0``
147
+
148
+ Raises:
149
+ ValueError: For any other value.
150
+
151
+ .. versionadded:: 21.3.0
152
+ """
153
+ if isinstance(val, str):
154
+ val = val.lower()
155
+
156
+ if val in (True, "true", "t", "yes", "y", "on", "1", 1):
157
+ return True
158
+ if val in (False, "false", "f", "no", "n", "off", "0", 0):
159
+ return False
160
+
161
+ msg = f"Cannot convert value to bool: {val!r}"
162
+ raise ValueError(msg)
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/converters.pyi ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Callable, Any, overload
2
+
3
+ from attrs import _ConverterType, _CallableConverterType
4
+
5
+ @overload
6
+ def pipe(*validators: _CallableConverterType) -> _CallableConverterType: ...
7
+ @overload
8
+ def pipe(*validators: _ConverterType) -> _ConverterType: ...
9
+ @overload
10
+ def optional(converter: _CallableConverterType) -> _CallableConverterType: ...
11
+ @overload
12
+ def optional(converter: _ConverterType) -> _ConverterType: ...
13
+ @overload
14
+ def default_if_none(default: Any) -> _CallableConverterType: ...
15
+ @overload
16
+ def default_if_none(
17
+ *, factory: Callable[[], Any]
18
+ ) -> _CallableConverterType: ...
19
+ def to_bool(val: str | int | bool) -> bool: ...
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/exceptions.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import ClassVar
6
+
7
+
8
+ class FrozenError(AttributeError):
9
+ """
10
+ A frozen/immutable instance or attribute have been attempted to be
11
+ modified.
12
+
13
+ It mirrors the behavior of ``namedtuples`` by using the same error message
14
+ and subclassing `AttributeError`.
15
+
16
+ .. versionadded:: 20.1.0
17
+ """
18
+
19
+ msg = "can't set attribute"
20
+ args: ClassVar[tuple[str]] = [msg]
21
+
22
+
23
+ class FrozenInstanceError(FrozenError):
24
+ """
25
+ A frozen instance has been attempted to be modified.
26
+
27
+ .. versionadded:: 16.1.0
28
+ """
29
+
30
+
31
+ class FrozenAttributeError(FrozenError):
32
+ """
33
+ A frozen attribute has been attempted to be modified.
34
+
35
+ .. versionadded:: 20.1.0
36
+ """
37
+
38
+
39
+ class AttrsAttributeNotFoundError(ValueError):
40
+ """
41
+ An *attrs* function couldn't find an attribute that the user asked for.
42
+
43
+ .. versionadded:: 16.2.0
44
+ """
45
+
46
+
47
+ class NotAnAttrsClassError(ValueError):
48
+ """
49
+ A non-*attrs* class has been passed into an *attrs* function.
50
+
51
+ .. versionadded:: 16.2.0
52
+ """
53
+
54
+
55
+ class DefaultAlreadySetError(RuntimeError):
56
+ """
57
+ A default has been set when defining the field and is attempted to be reset
58
+ using the decorator.
59
+
60
+ .. versionadded:: 17.1.0
61
+ """
62
+
63
+
64
+ class UnannotatedAttributeError(RuntimeError):
65
+ """
66
+ A class with ``auto_attribs=True`` has a field without a type annotation.
67
+
68
+ .. versionadded:: 17.3.0
69
+ """
70
+
71
+
72
+ class PythonTooOldError(RuntimeError):
73
+ """
74
+ It was attempted to use an *attrs* feature that requires a newer Python
75
+ version.
76
+
77
+ .. versionadded:: 18.2.0
78
+ """
79
+
80
+
81
+ class NotCallableError(TypeError):
82
+ """
83
+ A field requiring a callable has been set with a value that is not
84
+ callable.
85
+
86
+ .. versionadded:: 19.2.0
87
+ """
88
+
89
+ def __init__(self, msg, value):
90
+ super(TypeError, self).__init__(msg, value)
91
+ self.msg = msg
92
+ self.value = value
93
+
94
+ def __str__(self):
95
+ return str(self.msg)
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/filters.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ """
4
+ Commonly useful filters for `attrs.asdict` and `attrs.astuple`.
5
+ """
6
+
7
+ from ._make import Attribute
8
+
9
+
10
+ def _split_what(what):
11
+ """
12
+ Returns a tuple of `frozenset`s of classes and attributes.
13
+ """
14
+ return (
15
+ frozenset(cls for cls in what if isinstance(cls, type)),
16
+ frozenset(cls for cls in what if isinstance(cls, str)),
17
+ frozenset(cls for cls in what if isinstance(cls, Attribute)),
18
+ )
19
+
20
+
21
+ def include(*what):
22
+ """
23
+ Create a filter that only allows *what*.
24
+
25
+ Args:
26
+ what (list[type, str, attrs.Attribute]):
27
+ What to include. Can be a type, a name, or an attribute.
28
+
29
+ Returns:
30
+ Callable:
31
+ A callable that can be passed to `attrs.asdict`'s and
32
+ `attrs.astuple`'s *filter* argument.
33
+
34
+ .. versionchanged:: 23.1.0 Accept strings with field names.
35
+ """
36
+ cls, names, attrs = _split_what(what)
37
+
38
+ def include_(attribute, value):
39
+ return (
40
+ value.__class__ in cls
41
+ or attribute.name in names
42
+ or attribute in attrs
43
+ )
44
+
45
+ return include_
46
+
47
+
48
+ def exclude(*what):
49
+ """
50
+ Create a filter that does **not** allow *what*.
51
+
52
+ Args:
53
+ what (list[type, str, attrs.Attribute]):
54
+ What to exclude. Can be a type, a name, or an attribute.
55
+
56
+ Returns:
57
+ Callable:
58
+ A callable that can be passed to `attrs.asdict`'s and
59
+ `attrs.astuple`'s *filter* argument.
60
+
61
+ .. versionchanged:: 23.3.0 Accept field name string as input argument
62
+ """
63
+ cls, names, attrs = _split_what(what)
64
+
65
+ def exclude_(attribute, value):
66
+ return not (
67
+ value.__class__ in cls
68
+ or attribute.name in names
69
+ or attribute in attrs
70
+ )
71
+
72
+ return exclude_
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/filters.pyi ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from typing import Any
2
+
3
+ from . import Attribute, _FilterType
4
+
5
+ def include(*what: type | str | Attribute[Any]) -> _FilterType[Any]: ...
6
+ def exclude(*what: type | str | Attribute[Any]) -> _FilterType[Any]: ...
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/py.typed ADDED
File without changes
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/setters.pyi ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, NewType, NoReturn, TypeVar
2
+
3
+ from . import Attribute
4
+ from attrs import _OnSetAttrType
5
+
6
+ _T = TypeVar("_T")
7
+
8
+ def frozen(
9
+ instance: Any, attribute: Attribute[Any], new_value: Any
10
+ ) -> NoReturn: ...
11
+ def pipe(*setters: _OnSetAttrType) -> _OnSetAttrType: ...
12
+ def validate(instance: Any, attribute: Attribute[_T], new_value: _T) -> _T: ...
13
+
14
+ # convert is allowed to return Any, because they can be chained using pipe.
15
+ def convert(
16
+ instance: Any, attribute: Attribute[Any], new_value: Any
17
+ ) -> Any: ...
18
+
19
+ _NoOpType = NewType("_NoOpType", object)
20
+ NO_OP: _NoOpType
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/validators.py ADDED
@@ -0,0 +1,710 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ """
4
+ Commonly useful validators.
5
+ """
6
+
7
+ import operator
8
+ import re
9
+
10
+ from contextlib import contextmanager
11
+ from re import Pattern
12
+
13
+ from ._config import get_run_validators, set_run_validators
14
+ from ._make import _AndValidator, and_, attrib, attrs
15
+ from .converters import default_if_none
16
+ from .exceptions import NotCallableError
17
+
18
+
19
+ __all__ = [
20
+ "and_",
21
+ "deep_iterable",
22
+ "deep_mapping",
23
+ "disabled",
24
+ "ge",
25
+ "get_disabled",
26
+ "gt",
27
+ "in_",
28
+ "instance_of",
29
+ "is_callable",
30
+ "le",
31
+ "lt",
32
+ "matches_re",
33
+ "max_len",
34
+ "min_len",
35
+ "not_",
36
+ "optional",
37
+ "or_",
38
+ "set_disabled",
39
+ ]
40
+
41
+
42
+ def set_disabled(disabled):
43
+ """
44
+ Globally disable or enable running validators.
45
+
46
+ By default, they are run.
47
+
48
+ Args:
49
+ disabled (bool): If `True`, disable running all validators.
50
+
51
+ .. warning::
52
+
53
+ This function is not thread-safe!
54
+
55
+ .. versionadded:: 21.3.0
56
+ """
57
+ set_run_validators(not disabled)
58
+
59
+
60
+ def get_disabled():
61
+ """
62
+ Return a bool indicating whether validators are currently disabled or not.
63
+
64
+ Returns:
65
+ bool:`True` if validators are currently disabled.
66
+
67
+ .. versionadded:: 21.3.0
68
+ """
69
+ return not get_run_validators()
70
+
71
+
72
+ @contextmanager
73
+ def disabled():
74
+ """
75
+ Context manager that disables running validators within its context.
76
+
77
+ .. warning::
78
+
79
+ This context manager is not thread-safe!
80
+
81
+ .. versionadded:: 21.3.0
82
+ """
83
+ set_run_validators(False)
84
+ try:
85
+ yield
86
+ finally:
87
+ set_run_validators(True)
88
+
89
+
90
+ @attrs(repr=False, slots=True, unsafe_hash=True)
91
+ class _InstanceOfValidator:
92
+ type = attrib()
93
+
94
+ def __call__(self, inst, attr, value):
95
+ """
96
+ We use a callable class to be able to change the ``__repr__``.
97
+ """
98
+ if not isinstance(value, self.type):
99
+ msg = f"'{attr.name}' must be {self.type!r} (got {value!r} that is a {value.__class__!r})."
100
+ raise TypeError(
101
+ msg,
102
+ attr,
103
+ self.type,
104
+ value,
105
+ )
106
+
107
+ def __repr__(self):
108
+ return f"<instance_of validator for type {self.type!r}>"
109
+
110
+
111
+ def instance_of(type):
112
+ """
113
+ A validator that raises a `TypeError` if the initializer is called with a
114
+ wrong type for this particular attribute (checks are performed using
115
+ `isinstance` therefore it's also valid to pass a tuple of types).
116
+
117
+ Args:
118
+ type (type | tuple[type]): The type to check for.
119
+
120
+ Raises:
121
+ TypeError:
122
+ With a human readable error message, the attribute (of type
123
+ `attrs.Attribute`), the expected type, and the value it got.
124
+ """
125
+ return _InstanceOfValidator(type)
126
+
127
+
128
+ @attrs(repr=False, frozen=True, slots=True)
129
+ class _MatchesReValidator:
130
+ pattern = attrib()
131
+ match_func = attrib()
132
+
133
+ def __call__(self, inst, attr, value):
134
+ """
135
+ We use a callable class to be able to change the ``__repr__``.
136
+ """
137
+ if not self.match_func(value):
138
+ msg = f"'{attr.name}' must match regex {self.pattern.pattern!r} ({value!r} doesn't)"
139
+ raise ValueError(
140
+ msg,
141
+ attr,
142
+ self.pattern,
143
+ value,
144
+ )
145
+
146
+ def __repr__(self):
147
+ return f"<matches_re validator for pattern {self.pattern!r}>"
148
+
149
+
150
+ def matches_re(regex, flags=0, func=None):
151
+ r"""
152
+ A validator that raises `ValueError` if the initializer is called with a
153
+ string that doesn't match *regex*.
154
+
155
+ Args:
156
+ regex (str, re.Pattern):
157
+ A regex string or precompiled pattern to match against
158
+
159
+ flags (int):
160
+ Flags that will be passed to the underlying re function (default 0)
161
+
162
+ func (typing.Callable):
163
+ Which underlying `re` function to call. Valid options are
164
+ `re.fullmatch`, `re.search`, and `re.match`; the default `None`
165
+ means `re.fullmatch`. For performance reasons, the pattern is
166
+ always precompiled using `re.compile`.
167
+
168
+ .. versionadded:: 19.2.0
169
+ .. versionchanged:: 21.3.0 *regex* can be a pre-compiled pattern.
170
+ """
171
+ valid_funcs = (re.fullmatch, None, re.search, re.match)
172
+ if func not in valid_funcs:
173
+ msg = "'func' must be one of {}.".format(
174
+ ", ".join(
175
+ sorted((e and e.__name__) or "None" for e in set(valid_funcs))
176
+ )
177
+ )
178
+ raise ValueError(msg)
179
+
180
+ if isinstance(regex, Pattern):
181
+ if flags:
182
+ msg = "'flags' can only be used with a string pattern; pass flags to re.compile() instead"
183
+ raise TypeError(msg)
184
+ pattern = regex
185
+ else:
186
+ pattern = re.compile(regex, flags)
187
+
188
+ if func is re.match:
189
+ match_func = pattern.match
190
+ elif func is re.search:
191
+ match_func = pattern.search
192
+ else:
193
+ match_func = pattern.fullmatch
194
+
195
+ return _MatchesReValidator(pattern, match_func)
196
+
197
+
198
+ @attrs(repr=False, slots=True, unsafe_hash=True)
199
+ class _OptionalValidator:
200
+ validator = attrib()
201
+
202
+ def __call__(self, inst, attr, value):
203
+ if value is None:
204
+ return
205
+
206
+ self.validator(inst, attr, value)
207
+
208
+ def __repr__(self):
209
+ return f"<optional validator for {self.validator!r} or None>"
210
+
211
+
212
+ def optional(validator):
213
+ """
214
+ A validator that makes an attribute optional. An optional attribute is one
215
+ which can be set to `None` in addition to satisfying the requirements of
216
+ the sub-validator.
217
+
218
+ Args:
219
+ validator
220
+ (typing.Callable | tuple[typing.Callable] | list[typing.Callable]):
221
+ A validator (or validators) that is used for non-`None` values.
222
+
223
+ .. versionadded:: 15.1.0
224
+ .. versionchanged:: 17.1.0 *validator* can be a list of validators.
225
+ .. versionchanged:: 23.1.0 *validator* can also be a tuple of validators.
226
+ """
227
+ if isinstance(validator, (list, tuple)):
228
+ return _OptionalValidator(_AndValidator(validator))
229
+
230
+ return _OptionalValidator(validator)
231
+
232
+
233
+ @attrs(repr=False, slots=True, unsafe_hash=True)
234
+ class _InValidator:
235
+ options = attrib()
236
+ _original_options = attrib(hash=False)
237
+
238
+ def __call__(self, inst, attr, value):
239
+ try:
240
+ in_options = value in self.options
241
+ except TypeError: # e.g. `1 in "abc"`
242
+ in_options = False
243
+
244
+ if not in_options:
245
+ msg = f"'{attr.name}' must be in {self._original_options!r} (got {value!r})"
246
+ raise ValueError(
247
+ msg,
248
+ attr,
249
+ self._original_options,
250
+ value,
251
+ )
252
+
253
+ def __repr__(self):
254
+ return f"<in_ validator with options {self._original_options!r}>"
255
+
256
+
257
+ def in_(options):
258
+ """
259
+ A validator that raises a `ValueError` if the initializer is called with a
260
+ value that does not belong in the *options* provided.
261
+
262
+ The check is performed using ``value in options``, so *options* has to
263
+ support that operation.
264
+
265
+ To keep the validator hashable, dicts, lists, and sets are transparently
266
+ transformed into a `tuple`.
267
+
268
+ Args:
269
+ options: Allowed options.
270
+
271
+ Raises:
272
+ ValueError:
273
+ With a human readable error message, the attribute (of type
274
+ `attrs.Attribute`), the expected options, and the value it got.
275
+
276
+ .. versionadded:: 17.1.0
277
+ .. versionchanged:: 22.1.0
278
+ The ValueError was incomplete until now and only contained the human
279
+ readable error message. Now it contains all the information that has
280
+ been promised since 17.1.0.
281
+ .. versionchanged:: 24.1.0
282
+ *options* that are a list, dict, or a set are now transformed into a
283
+ tuple to keep the validator hashable.
284
+ """
285
+ repr_options = options
286
+ if isinstance(options, (list, dict, set)):
287
+ options = tuple(options)
288
+
289
+ return _InValidator(options, repr_options)
290
+
291
+
292
+ @attrs(repr=False, slots=False, unsafe_hash=True)
293
+ class _IsCallableValidator:
294
+ def __call__(self, inst, attr, value):
295
+ """
296
+ We use a callable class to be able to change the ``__repr__``.
297
+ """
298
+ if not callable(value):
299
+ message = (
300
+ "'{name}' must be callable "
301
+ "(got {value!r} that is a {actual!r})."
302
+ )
303
+ raise NotCallableError(
304
+ msg=message.format(
305
+ name=attr.name, value=value, actual=value.__class__
306
+ ),
307
+ value=value,
308
+ )
309
+
310
+ def __repr__(self):
311
+ return "<is_callable validator>"
312
+
313
+
314
+ def is_callable():
315
+ """
316
+ A validator that raises a `attrs.exceptions.NotCallableError` if the
317
+ initializer is called with a value for this particular attribute that is
318
+ not callable.
319
+
320
+ .. versionadded:: 19.1.0
321
+
322
+ Raises:
323
+ attrs.exceptions.NotCallableError:
324
+ With a human readable error message containing the attribute
325
+ (`attrs.Attribute`) name, and the value it got.
326
+ """
327
+ return _IsCallableValidator()
328
+
329
+
330
+ @attrs(repr=False, slots=True, unsafe_hash=True)
331
+ class _DeepIterable:
332
+ member_validator = attrib(validator=is_callable())
333
+ iterable_validator = attrib(
334
+ default=None, validator=optional(is_callable())
335
+ )
336
+
337
+ def __call__(self, inst, attr, value):
338
+ """
339
+ We use a callable class to be able to change the ``__repr__``.
340
+ """
341
+ if self.iterable_validator is not None:
342
+ self.iterable_validator(inst, attr, value)
343
+
344
+ for member in value:
345
+ self.member_validator(inst, attr, member)
346
+
347
+ def __repr__(self):
348
+ iterable_identifier = (
349
+ ""
350
+ if self.iterable_validator is None
351
+ else f" {self.iterable_validator!r}"
352
+ )
353
+ return (
354
+ f"<deep_iterable validator for{iterable_identifier}"
355
+ f" iterables of {self.member_validator!r}>"
356
+ )
357
+
358
+
359
+ def deep_iterable(member_validator, iterable_validator=None):
360
+ """
361
+ A validator that performs deep validation of an iterable.
362
+
363
+ Args:
364
+ member_validator: Validator to apply to iterable members.
365
+
366
+ iterable_validator:
367
+ Validator to apply to iterable itself (optional).
368
+
369
+ Raises
370
+ TypeError: if any sub-validators fail
371
+
372
+ .. versionadded:: 19.1.0
373
+ """
374
+ if isinstance(member_validator, (list, tuple)):
375
+ member_validator = and_(*member_validator)
376
+ return _DeepIterable(member_validator, iterable_validator)
377
+
378
+
379
+ @attrs(repr=False, slots=True, unsafe_hash=True)
380
+ class _DeepMapping:
381
+ key_validator = attrib(validator=is_callable())
382
+ value_validator = attrib(validator=is_callable())
383
+ mapping_validator = attrib(default=None, validator=optional(is_callable()))
384
+
385
+ def __call__(self, inst, attr, value):
386
+ """
387
+ We use a callable class to be able to change the ``__repr__``.
388
+ """
389
+ if self.mapping_validator is not None:
390
+ self.mapping_validator(inst, attr, value)
391
+
392
+ for key in value:
393
+ self.key_validator(inst, attr, key)
394
+ self.value_validator(inst, attr, value[key])
395
+
396
+ def __repr__(self):
397
+ return f"<deep_mapping validator for objects mapping {self.key_validator!r} to {self.value_validator!r}>"
398
+
399
+
400
+ def deep_mapping(key_validator, value_validator, mapping_validator=None):
401
+ """
402
+ A validator that performs deep validation of a dictionary.
403
+
404
+ Args:
405
+ key_validator: Validator to apply to dictionary keys.
406
+
407
+ value_validator: Validator to apply to dictionary values.
408
+
409
+ mapping_validator:
410
+ Validator to apply to top-level mapping attribute (optional).
411
+
412
+ .. versionadded:: 19.1.0
413
+
414
+ Raises:
415
+ TypeError: if any sub-validators fail
416
+ """
417
+ return _DeepMapping(key_validator, value_validator, mapping_validator)
418
+
419
+
420
+ @attrs(repr=False, frozen=True, slots=True)
421
+ class _NumberValidator:
422
+ bound = attrib()
423
+ compare_op = attrib()
424
+ compare_func = attrib()
425
+
426
+ def __call__(self, inst, attr, value):
427
+ """
428
+ We use a callable class to be able to change the ``__repr__``.
429
+ """
430
+ if not self.compare_func(value, self.bound):
431
+ msg = f"'{attr.name}' must be {self.compare_op} {self.bound}: {value}"
432
+ raise ValueError(msg)
433
+
434
+ def __repr__(self):
435
+ return f"<Validator for x {self.compare_op} {self.bound}>"
436
+
437
+
438
+ def lt(val):
439
+ """
440
+ A validator that raises `ValueError` if the initializer is called with a
441
+ number larger or equal to *val*.
442
+
443
+ The validator uses `operator.lt` to compare the values.
444
+
445
+ Args:
446
+ val: Exclusive upper bound for values.
447
+
448
+ .. versionadded:: 21.3.0
449
+ """
450
+ return _NumberValidator(val, "<", operator.lt)
451
+
452
+
453
+ def le(val):
454
+ """
455
+ A validator that raises `ValueError` if the initializer is called with a
456
+ number greater than *val*.
457
+
458
+ The validator uses `operator.le` to compare the values.
459
+
460
+ Args:
461
+ val: Inclusive upper bound for values.
462
+
463
+ .. versionadded:: 21.3.0
464
+ """
465
+ return _NumberValidator(val, "<=", operator.le)
466
+
467
+
468
+ def ge(val):
469
+ """
470
+ A validator that raises `ValueError` if the initializer is called with a
471
+ number smaller than *val*.
472
+
473
+ The validator uses `operator.ge` to compare the values.
474
+
475
+ Args:
476
+ val: Inclusive lower bound for values
477
+
478
+ .. versionadded:: 21.3.0
479
+ """
480
+ return _NumberValidator(val, ">=", operator.ge)
481
+
482
+
483
+ def gt(val):
484
+ """
485
+ A validator that raises `ValueError` if the initializer is called with a
486
+ number smaller or equal to *val*.
487
+
488
+ The validator uses `operator.ge` to compare the values.
489
+
490
+ Args:
491
+ val: Exclusive lower bound for values
492
+
493
+ .. versionadded:: 21.3.0
494
+ """
495
+ return _NumberValidator(val, ">", operator.gt)
496
+
497
+
498
+ @attrs(repr=False, frozen=True, slots=True)
499
+ class _MaxLengthValidator:
500
+ max_length = attrib()
501
+
502
+ def __call__(self, inst, attr, value):
503
+ """
504
+ We use a callable class to be able to change the ``__repr__``.
505
+ """
506
+ if len(value) > self.max_length:
507
+ msg = f"Length of '{attr.name}' must be <= {self.max_length}: {len(value)}"
508
+ raise ValueError(msg)
509
+
510
+ def __repr__(self):
511
+ return f"<max_len validator for {self.max_length}>"
512
+
513
+
514
+ def max_len(length):
515
+ """
516
+ A validator that raises `ValueError` if the initializer is called
517
+ with a string or iterable that is longer than *length*.
518
+
519
+ Args:
520
+ length (int): Maximum length of the string or iterable
521
+
522
+ .. versionadded:: 21.3.0
523
+ """
524
+ return _MaxLengthValidator(length)
525
+
526
+
527
+ @attrs(repr=False, frozen=True, slots=True)
528
+ class _MinLengthValidator:
529
+ min_length = attrib()
530
+
531
+ def __call__(self, inst, attr, value):
532
+ """
533
+ We use a callable class to be able to change the ``__repr__``.
534
+ """
535
+ if len(value) < self.min_length:
536
+ msg = f"Length of '{attr.name}' must be >= {self.min_length}: {len(value)}"
537
+ raise ValueError(msg)
538
+
539
+ def __repr__(self):
540
+ return f"<min_len validator for {self.min_length}>"
541
+
542
+
543
+ def min_len(length):
544
+ """
545
+ A validator that raises `ValueError` if the initializer is called
546
+ with a string or iterable that is shorter than *length*.
547
+
548
+ Args:
549
+ length (int): Minimum length of the string or iterable
550
+
551
+ .. versionadded:: 22.1.0
552
+ """
553
+ return _MinLengthValidator(length)
554
+
555
+
556
+ @attrs(repr=False, slots=True, unsafe_hash=True)
557
+ class _SubclassOfValidator:
558
+ type = attrib()
559
+
560
+ def __call__(self, inst, attr, value):
561
+ """
562
+ We use a callable class to be able to change the ``__repr__``.
563
+ """
564
+ if not issubclass(value, self.type):
565
+ msg = f"'{attr.name}' must be a subclass of {self.type!r} (got {value!r})."
566
+ raise TypeError(
567
+ msg,
568
+ attr,
569
+ self.type,
570
+ value,
571
+ )
572
+
573
+ def __repr__(self):
574
+ return f"<subclass_of validator for type {self.type!r}>"
575
+
576
+
577
+ def _subclass_of(type):
578
+ """
579
+ A validator that raises a `TypeError` if the initializer is called with a
580
+ wrong type for this particular attribute (checks are performed using
581
+ `issubclass` therefore it's also valid to pass a tuple of types).
582
+
583
+ Args:
584
+ type (type | tuple[type, ...]): The type(s) to check for.
585
+
586
+ Raises:
587
+ TypeError:
588
+ With a human readable error message, the attribute (of type
589
+ `attrs.Attribute`), the expected type, and the value it got.
590
+ """
591
+ return _SubclassOfValidator(type)
592
+
593
+
594
+ @attrs(repr=False, slots=True, unsafe_hash=True)
595
+ class _NotValidator:
596
+ validator = attrib()
597
+ msg = attrib(
598
+ converter=default_if_none(
599
+ "not_ validator child '{validator!r}' "
600
+ "did not raise a captured error"
601
+ )
602
+ )
603
+ exc_types = attrib(
604
+ validator=deep_iterable(
605
+ member_validator=_subclass_of(Exception),
606
+ iterable_validator=instance_of(tuple),
607
+ ),
608
+ )
609
+
610
+ def __call__(self, inst, attr, value):
611
+ try:
612
+ self.validator(inst, attr, value)
613
+ except self.exc_types:
614
+ pass # suppress error to invert validity
615
+ else:
616
+ raise ValueError(
617
+ self.msg.format(
618
+ validator=self.validator,
619
+ exc_types=self.exc_types,
620
+ ),
621
+ attr,
622
+ self.validator,
623
+ value,
624
+ self.exc_types,
625
+ )
626
+
627
+ def __repr__(self):
628
+ return f"<not_ validator wrapping {self.validator!r}, capturing {self.exc_types!r}>"
629
+
630
+
631
+ def not_(validator, *, msg=None, exc_types=(ValueError, TypeError)):
632
+ """
633
+ A validator that wraps and logically 'inverts' the validator passed to it.
634
+ It will raise a `ValueError` if the provided validator *doesn't* raise a
635
+ `ValueError` or `TypeError` (by default), and will suppress the exception
636
+ if the provided validator *does*.
637
+
638
+ Intended to be used with existing validators to compose logic without
639
+ needing to create inverted variants, for example, ``not_(in_(...))``.
640
+
641
+ Args:
642
+ validator: A validator to be logically inverted.
643
+
644
+ msg (str):
645
+ Message to raise if validator fails. Formatted with keys
646
+ ``exc_types`` and ``validator``.
647
+
648
+ exc_types (tuple[type, ...]):
649
+ Exception type(s) to capture. Other types raised by child
650
+ validators will not be intercepted and pass through.
651
+
652
+ Raises:
653
+ ValueError:
654
+ With a human readable error message, the attribute (of type
655
+ `attrs.Attribute`), the validator that failed to raise an
656
+ exception, the value it got, and the expected exception types.
657
+
658
+ .. versionadded:: 22.2.0
659
+ """
660
+ try:
661
+ exc_types = tuple(exc_types)
662
+ except TypeError:
663
+ exc_types = (exc_types,)
664
+ return _NotValidator(validator, msg, exc_types)
665
+
666
+
667
+ @attrs(repr=False, slots=True, unsafe_hash=True)
668
+ class _OrValidator:
669
+ validators = attrib()
670
+
671
+ def __call__(self, inst, attr, value):
672
+ for v in self.validators:
673
+ try:
674
+ v(inst, attr, value)
675
+ except Exception: # noqa: BLE001, PERF203, S112
676
+ continue
677
+ else:
678
+ return
679
+
680
+ msg = f"None of {self.validators!r} satisfied for value {value!r}"
681
+ raise ValueError(msg)
682
+
683
+ def __repr__(self):
684
+ return f"<or validator wrapping {self.validators!r}>"
685
+
686
+
687
+ def or_(*validators):
688
+ """
689
+ A validator that composes multiple validators into one.
690
+
691
+ When called on a value, it runs all wrapped validators until one of them is
692
+ satisfied.
693
+
694
+ Args:
695
+ validators (~collections.abc.Iterable[typing.Callable]):
696
+ Arbitrary number of validators.
697
+
698
+ Raises:
699
+ ValueError:
700
+ If no validator is satisfied. Raised with a human-readable error
701
+ message listing all the wrapped validators and the value that
702
+ failed all of them.
703
+
704
+ .. versionadded:: 24.1.0
705
+ """
706
+ vals = []
707
+ for v in validators:
708
+ vals.extend(v.validators if isinstance(v, _OrValidator) else [v])
709
+
710
+ return _OrValidator(tuple(vals))
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attr/validators.pyi ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from types import UnionType
2
+ from typing import (
3
+ Any,
4
+ AnyStr,
5
+ Callable,
6
+ Container,
7
+ ContextManager,
8
+ Iterable,
9
+ Mapping,
10
+ Match,
11
+ Pattern,
12
+ TypeVar,
13
+ overload,
14
+ )
15
+
16
+ from attrs import _ValidatorType
17
+ from attrs import _ValidatorArgType
18
+
19
+ _T = TypeVar("_T")
20
+ _T1 = TypeVar("_T1")
21
+ _T2 = TypeVar("_T2")
22
+ _T3 = TypeVar("_T3")
23
+ _I = TypeVar("_I", bound=Iterable)
24
+ _K = TypeVar("_K")
25
+ _V = TypeVar("_V")
26
+ _M = TypeVar("_M", bound=Mapping)
27
+
28
+ def set_disabled(run: bool) -> None: ...
29
+ def get_disabled() -> bool: ...
30
+ def disabled() -> ContextManager[None]: ...
31
+
32
+ # To be more precise on instance_of use some overloads.
33
+ # If there are more than 3 items in the tuple then we fall back to Any
34
+ @overload
35
+ def instance_of(type: type[_T]) -> _ValidatorType[_T]: ...
36
+ @overload
37
+ def instance_of(type: tuple[type[_T]]) -> _ValidatorType[_T]: ...
38
+ @overload
39
+ def instance_of(
40
+ type: tuple[type[_T1], type[_T2]],
41
+ ) -> _ValidatorType[_T1 | _T2]: ...
42
+ @overload
43
+ def instance_of(
44
+ type: tuple[type[_T1], type[_T2], type[_T3]],
45
+ ) -> _ValidatorType[_T1 | _T2 | _T3]: ...
46
+ @overload
47
+ def instance_of(type: tuple[type, ...]) -> _ValidatorType[Any]: ...
48
+ @overload
49
+ def instance_of(type: UnionType) -> _ValidatorType[Any]: ...
50
+ def optional(
51
+ validator: (
52
+ _ValidatorType[_T]
53
+ | list[_ValidatorType[_T]]
54
+ | tuple[_ValidatorType[_T]]
55
+ ),
56
+ ) -> _ValidatorType[_T | None]: ...
57
+ def in_(options: Container[_T]) -> _ValidatorType[_T]: ...
58
+ def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ...
59
+ def matches_re(
60
+ regex: Pattern[AnyStr] | AnyStr,
61
+ flags: int = ...,
62
+ func: Callable[[AnyStr, AnyStr, int], Match[AnyStr] | None] | None = ...,
63
+ ) -> _ValidatorType[AnyStr]: ...
64
+ def deep_iterable(
65
+ member_validator: _ValidatorArgType[_T],
66
+ iterable_validator: _ValidatorType[_I] | None = ...,
67
+ ) -> _ValidatorType[_I]: ...
68
+ def deep_mapping(
69
+ key_validator: _ValidatorType[_K],
70
+ value_validator: _ValidatorType[_V],
71
+ mapping_validator: _ValidatorType[_M] | None = ...,
72
+ ) -> _ValidatorType[_M]: ...
73
+ def is_callable() -> _ValidatorType[_T]: ...
74
+ def lt(val: _T) -> _ValidatorType[_T]: ...
75
+ def le(val: _T) -> _ValidatorType[_T]: ...
76
+ def ge(val: _T) -> _ValidatorType[_T]: ...
77
+ def gt(val: _T) -> _ValidatorType[_T]: ...
78
+ def max_len(length: int) -> _ValidatorType[_T]: ...
79
+ def min_len(length: int) -> _ValidatorType[_T]: ...
80
+ def not_(
81
+ validator: _ValidatorType[_T],
82
+ *,
83
+ msg: str | None = None,
84
+ exc_types: type[Exception] | Iterable[type[Exception]] = ...,
85
+ ) -> _ValidatorType[_T]: ...
86
+ def or_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ...
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs-25.1.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs-25.1.0.dist-info/METADATA ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.4
2
+ Name: attrs
3
+ Version: 25.1.0
4
+ Summary: Classes Without Boilerplate
5
+ Project-URL: Documentation, https://www.attrs.org/
6
+ Project-URL: Changelog, https://www.attrs.org/en/stable/changelog.html
7
+ Project-URL: GitHub, https://github.com/python-attrs/attrs
8
+ Project-URL: Funding, https://github.com/sponsors/hynek
9
+ Project-URL: Tidelift, https://tidelift.com/subscription/pkg/pypi-attrs?utm_source=pypi-attrs&utm_medium=pypi
10
+ Author-email: Hynek Schlawack <hs@ox.cx>
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: attribute,boilerplate,class
14
+ Classifier: Development Status :: 5 - Production/Stable
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: Implementation :: CPython
22
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.8
25
+ Provides-Extra: benchmark
26
+ Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'benchmark'
27
+ Requires-Dist: hypothesis; extra == 'benchmark'
28
+ Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.10') and extra == 'benchmark'
29
+ Requires-Dist: pympler; extra == 'benchmark'
30
+ Requires-Dist: pytest-codspeed; extra == 'benchmark'
31
+ Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.10') and extra == 'benchmark'
32
+ Requires-Dist: pytest-xdist[psutil]; extra == 'benchmark'
33
+ Requires-Dist: pytest>=4.3.0; extra == 'benchmark'
34
+ Provides-Extra: cov
35
+ Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'cov'
36
+ Requires-Dist: coverage[toml]>=5.3; extra == 'cov'
37
+ Requires-Dist: hypothesis; extra == 'cov'
38
+ Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.10') and extra == 'cov'
39
+ Requires-Dist: pympler; extra == 'cov'
40
+ Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.10') and extra == 'cov'
41
+ Requires-Dist: pytest-xdist[psutil]; extra == 'cov'
42
+ Requires-Dist: pytest>=4.3.0; extra == 'cov'
43
+ Provides-Extra: dev
44
+ Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'dev'
45
+ Requires-Dist: hypothesis; extra == 'dev'
46
+ Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.10') and extra == 'dev'
47
+ Requires-Dist: pre-commit-uv; extra == 'dev'
48
+ Requires-Dist: pympler; extra == 'dev'
49
+ Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.10') and extra == 'dev'
50
+ Requires-Dist: pytest-xdist[psutil]; extra == 'dev'
51
+ Requires-Dist: pytest>=4.3.0; extra == 'dev'
52
+ Provides-Extra: docs
53
+ Requires-Dist: cogapp; extra == 'docs'
54
+ Requires-Dist: furo; extra == 'docs'
55
+ Requires-Dist: myst-parser; extra == 'docs'
56
+ Requires-Dist: sphinx; extra == 'docs'
57
+ Requires-Dist: sphinx-notfound-page; extra == 'docs'
58
+ Requires-Dist: sphinxcontrib-towncrier; extra == 'docs'
59
+ Requires-Dist: towncrier<24.7; extra == 'docs'
60
+ Provides-Extra: tests
61
+ Requires-Dist: cloudpickle; (platform_python_implementation == 'CPython') and extra == 'tests'
62
+ Requires-Dist: hypothesis; extra == 'tests'
63
+ Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.10') and extra == 'tests'
64
+ Requires-Dist: pympler; extra == 'tests'
65
+ Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.10') and extra == 'tests'
66
+ Requires-Dist: pytest-xdist[psutil]; extra == 'tests'
67
+ Requires-Dist: pytest>=4.3.0; extra == 'tests'
68
+ Provides-Extra: tests-mypy
69
+ Requires-Dist: mypy>=1.11.1; (platform_python_implementation == 'CPython' and python_version >= '3.10') and extra == 'tests-mypy'
70
+ Requires-Dist: pytest-mypy-plugins; (platform_python_implementation == 'CPython' and python_version >= '3.10') and extra == 'tests-mypy'
71
+ Description-Content-Type: text/markdown
72
+
73
+ <p align="center">
74
+ <a href="https://www.attrs.org/">
75
+ <img src="https://raw.githubusercontent.com/python-attrs/attrs/main/docs/_static/attrs_logo.svg" width="35%" alt="attrs" />
76
+ </a>
77
+ </p>
78
+
79
+
80
+ *attrs* is the Python package that will bring back the **joy** of **writing classes** by relieving you from the drudgery of implementing object protocols (aka [dunder methods](https://www.attrs.org/en/latest/glossary.html#term-dunder-methods)).
81
+ [Trusted by NASA](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/customizing-your-profile/personalizing-your-profile#list-of-qualifying-repositories-for-mars-2020-helicopter-contributor-achievement) for Mars missions since 2020!
82
+
83
+ Its main goal is to help you to write **concise** and **correct** software without slowing down your code.
84
+
85
+
86
+ ## Sponsors
87
+
88
+ *attrs* would not be possible without our [amazing sponsors](https://github.com/sponsors/hynek).
89
+ Especially those generously supporting us at the *The Organization* tier and higher:
90
+
91
+ <!-- sponsor-break-begin -->
92
+
93
+ <p align="center">
94
+
95
+ <!-- [[[cog
96
+ import pathlib, tomllib
97
+
98
+ for sponsor in tomllib.loads(pathlib.Path("pyproject.toml").read_text())["tool"]["sponcon"]["sponsors"]:
99
+ print(f'<a href="{sponsor["url"]}"><img title="{sponsor["title"]}" src="https://www.attrs.org/en/25.1.0/_static/sponsors/{sponsor["img"]}" width="190" /></a>')
100
+ ]]] -->
101
+ <a href="https://www.variomedia.de/"><img title="Variomedia AG" src="https://www.attrs.org/en/25.1.0/_static/sponsors/Variomedia.svg" width="190" /></a>
102
+ <a href="https://tidelift.com/?utm_source=lifter&utm_medium=referral&utm_campaign=hynek"><img title="Tidelift" src="https://www.attrs.org/en/25.1.0/_static/sponsors/Tidelift.svg" width="190" /></a>
103
+ <a href="https://klaviyo.com/"><img title="Klaviyo" src="https://www.attrs.org/en/25.1.0/_static/sponsors/Klaviyo.svg" width="190" /></a>
104
+ <a href="https://www.emsys-renewables.com/"><img title="emsys renewables" src="https://www.attrs.org/en/25.1.0/_static/sponsors/emsys-renewables.svg" width="190" /></a>
105
+ <a href="https://filepreviews.io/"><img title="FilePreviews" src="https://www.attrs.org/en/25.1.0/_static/sponsors/FilePreviews.svg" width="190" /></a>
106
+ <a href="https://privacy-solutions.org/"><img title="Privacy Solutions" src="https://www.attrs.org/en/25.1.0/_static/sponsors/Privacy-Solutions.svg" width="190" /></a>
107
+ <a href="https://polar.sh/"><img title="Polar" src="https://www.attrs.org/en/25.1.0/_static/sponsors/Polar.svg" width="190" /></a>
108
+ <!-- [[[end]]] -->
109
+
110
+ </p>
111
+
112
+ <!-- sponsor-break-end -->
113
+
114
+ <p align="center">
115
+ <strong>Please consider <a href="https://github.com/sponsors/hynek">joining them</a> to help make <em>attrs</em>’s maintenance more sustainable!</strong>
116
+ </p>
117
+
118
+ <!-- teaser-end -->
119
+
120
+ ## Example
121
+
122
+ *attrs* gives you a class decorator and a way to declaratively define the attributes on that class:
123
+
124
+ <!-- code-begin -->
125
+
126
+ ```pycon
127
+ >>> from attrs import asdict, define, make_class, Factory
128
+
129
+ >>> @define
130
+ ... class SomeClass:
131
+ ... a_number: int = 42
132
+ ... list_of_numbers: list[int] = Factory(list)
133
+ ...
134
+ ... def hard_math(self, another_number):
135
+ ... return self.a_number + sum(self.list_of_numbers) * another_number
136
+
137
+
138
+ >>> sc = SomeClass(1, [1, 2, 3])
139
+ >>> sc
140
+ SomeClass(a_number=1, list_of_numbers=[1, 2, 3])
141
+
142
+ >>> sc.hard_math(3)
143
+ 19
144
+ >>> sc == SomeClass(1, [1, 2, 3])
145
+ True
146
+ >>> sc != SomeClass(2, [3, 2, 1])
147
+ True
148
+
149
+ >>> asdict(sc)
150
+ {'a_number': 1, 'list_of_numbers': [1, 2, 3]}
151
+
152
+ >>> SomeClass()
153
+ SomeClass(a_number=42, list_of_numbers=[])
154
+
155
+ >>> C = make_class("C", ["a", "b"])
156
+ >>> C("foo", "bar")
157
+ C(a='foo', b='bar')
158
+ ```
159
+
160
+ After *declaring* your attributes, *attrs* gives you:
161
+
162
+ - a concise and explicit overview of the class's attributes,
163
+ - a nice human-readable `__repr__`,
164
+ - equality-checking methods,
165
+ - an initializer,
166
+ - and much more,
167
+
168
+ *without* writing dull boilerplate code again and again and *without* runtime performance penalties.
169
+
170
+ ---
171
+
172
+ This example uses *attrs*'s modern APIs that have been introduced in version 20.1.0, and the *attrs* package import name that has been added in version 21.3.0.
173
+ The classic APIs (`@attr.s`, `attr.ib`, plus their serious-business aliases) and the `attr` package import name will remain **indefinitely**.
174
+
175
+ Check out [*On The Core API Names*](https://www.attrs.org/en/latest/names.html) for an in-depth explanation!
176
+
177
+
178
+ ### Hate Type Annotations!?
179
+
180
+ No problem!
181
+ Types are entirely **optional** with *attrs*.
182
+ Simply assign `attrs.field()` to the attributes instead of annotating them with types:
183
+
184
+ ```python
185
+ from attrs import define, field
186
+
187
+ @define
188
+ class SomeClass:
189
+ a_number = field(default=42)
190
+ list_of_numbers = field(factory=list)
191
+ ```
192
+
193
+
194
+ ## Data Classes
195
+
196
+ On the tin, *attrs* might remind you of `dataclasses` (and indeed, `dataclasses` [are a descendant](https://hynek.me/articles/import-attrs/) of *attrs*).
197
+ In practice it does a lot more and is more flexible.
198
+ For instance, it allows you to define [special handling of NumPy arrays for equality checks](https://www.attrs.org/en/stable/comparison.html#customization), allows more ways to [plug into the initialization process](https://www.attrs.org/en/stable/init.html#hooking-yourself-into-initialization), has a replacement for `__init_subclass__`, and allows for stepping through the generated methods using a debugger.
199
+
200
+ For more details, please refer to our [comparison page](https://www.attrs.org/en/stable/why.html#data-classes), but generally speaking, we are more likely to commit crimes against nature to make things work that one would expect to work, but that are quite complicated in practice.
201
+
202
+
203
+ ## Project Information
204
+
205
+ - [**Changelog**](https://www.attrs.org/en/stable/changelog.html)
206
+ - [**Documentation**](https://www.attrs.org/)
207
+ - [**PyPI**](https://pypi.org/project/attrs/)
208
+ - [**Source Code**](https://github.com/python-attrs/attrs)
209
+ - [**Contributing**](https://github.com/python-attrs/attrs/blob/main/.github/CONTRIBUTING.md)
210
+ - [**Third-party Extensions**](https://github.com/python-attrs/attrs/wiki/Extensions-to-attrs)
211
+ - **Get Help**: use the `python-attrs` tag on [Stack Overflow](https://stackoverflow.com/questions/tagged/python-attrs)
212
+
213
+
214
+ ### *attrs* for Enterprise
215
+
216
+ Available as part of the [Tidelift Subscription](https://tidelift.com/?utm_source=lifter&utm_medium=referral&utm_campaign=hynek).
217
+
218
+ The maintainers of *attrs* and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications.
219
+ Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use.
220
+
221
+ ## Release Information
222
+
223
+ ### Changes
224
+
225
+ - This release only ensures correct PyPI licensing metadata.
226
+ [#1386](https://github.com/python-attrs/attrs/issues/1386)
227
+
228
+
229
+
230
+ ---
231
+
232
+ [Full changelog →](https://www.attrs.org/en/stable/changelog.html)
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs-25.1.0.dist-info/RECORD ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ attr/__init__.py,sha256=fOYIvt1eGSqQre4uCS3sJWKZ0mwAuC8UD6qba5OS9_U,2057
2
+ attr/__init__.pyi,sha256=QIXnnHPoucmDWkbpNsWTP-cgJ1bn8le7DjyRa_wYdew,11281
3
+ attr/__pycache__/__init__.cpython-311.pyc,,
4
+ attr/__pycache__/_cmp.cpython-311.pyc,,
5
+ attr/__pycache__/_compat.cpython-311.pyc,,
6
+ attr/__pycache__/_config.cpython-311.pyc,,
7
+ attr/__pycache__/_funcs.cpython-311.pyc,,
8
+ attr/__pycache__/_make.cpython-311.pyc,,
9
+ attr/__pycache__/_next_gen.cpython-311.pyc,,
10
+ attr/__pycache__/_version_info.cpython-311.pyc,,
11
+ attr/__pycache__/converters.cpython-311.pyc,,
12
+ attr/__pycache__/exceptions.cpython-311.pyc,,
13
+ attr/__pycache__/filters.cpython-311.pyc,,
14
+ attr/__pycache__/setters.cpython-311.pyc,,
15
+ attr/__pycache__/validators.cpython-311.pyc,,
16
+ attr/_cmp.py,sha256=3umHiBtgsEYtvNP_8XrQwTCdFoZIX4DEur76N-2a3X8,4123
17
+ attr/_cmp.pyi,sha256=U-_RU_UZOyPUEQzXE6RMYQQcjkZRY25wTH99sN0s7MM,368
18
+ attr/_compat.py,sha256=4hlXbWhdDjQCDK6FKF1EgnZ3POiHgtpp54qE0nxaGHg,2704
19
+ attr/_config.py,sha256=dGq3xR6fgZEF6UBt_L0T-eUHIB4i43kRmH0P28sJVw8,843
20
+ attr/_funcs.py,sha256=5-tUKJtp3h5El55EcDl6GWXFp68fT8D8U7uCRN6497I,15854
21
+ attr/_make.py,sha256=XS_pYn_-KNo69Tb8-_y3YUcB3Xus00MwAShh2WulkjQ,94157
22
+ attr/_next_gen.py,sha256=7FRkbtl_N017SuBhf_Vw3mw2c2pGZhtCGOzadgz7tp4,24395
23
+ attr/_typing_compat.pyi,sha256=XDP54TUn-ZKhD62TOQebmzrwFyomhUCoGRpclb6alRA,469
24
+ attr/_version_info.py,sha256=exSqb3b5E-fMSsgZAlEw9XcLpEgobPORCZpcaEglAM4,2121
25
+ attr/_version_info.pyi,sha256=x_M3L3WuB7r_ULXAWjx959udKQ4HLB8l-hsc1FDGNvk,209
26
+ attr/converters.py,sha256=GlDeOzPeTFgeBBLbj9G57Ez5lAk68uhSALRYJ_exe84,3861
27
+ attr/converters.pyi,sha256=orU2bff-VjQa2kMDyvnMQV73oJT2WRyQuw4ZR1ym1bE,643
28
+ attr/exceptions.py,sha256=HRFq4iybmv7-DcZwyjl6M1euM2YeJVK_hFxuaBGAngI,1977
29
+ attr/exceptions.pyi,sha256=zZq8bCUnKAy9mDtBEw42ZhPhAUIHoTKedDQInJD883M,539
30
+ attr/filters.py,sha256=ZBiKWLp3R0LfCZsq7X11pn9WX8NslS2wXM4jsnLOGc8,1795
31
+ attr/filters.pyi,sha256=3J5BG-dTxltBk1_-RuNRUHrv2qu1v8v4aDNAQ7_mifA,208
32
+ attr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
+ attr/setters.py,sha256=5-dcT63GQK35ONEzSgfXCkbB7pPkaR-qv15mm4PVSzQ,1617
34
+ attr/setters.pyi,sha256=NnVkaFU1BB4JB8E4JuXyrzTUgvtMpj8p3wBdJY7uix4,584
35
+ attr/validators.py,sha256=WaB1HLAHHqRHWsrv_K9H-sJ7ESil3H3Cmv2d8TtVZx4,20046
36
+ attr/validators.pyi,sha256=s2WhKPqskxbsckJfKk8zOuuB088GfgpyxcCYSNFLqNU,2603
37
+ attrs-25.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
38
+ attrs-25.1.0.dist-info/METADATA,sha256=bZidcSPgoF4BvFNQYyqph4NeHVg9r55WXiwAEtbvRnc,10999
39
+ attrs-25.1.0.dist-info/RECORD,,
40
+ attrs-25.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
41
+ attrs-25.1.0.dist-info/licenses/LICENSE,sha256=iCEVyV38KvHutnFPjsbVy8q_Znyv-HKfQkINpj9xTp8,1109
42
+ attrs/__init__.py,sha256=qeQJZ4O08yczSn840v9bYOaZyRE81WsVi-QCrY3krCU,1107
43
+ attrs/__init__.pyi,sha256=nZmInocjM7tHV4AQw0vxO_fo6oJjL_PonlV9zKKW8DY,7931
44
+ attrs/__pycache__/__init__.cpython-311.pyc,,
45
+ attrs/__pycache__/converters.cpython-311.pyc,,
46
+ attrs/__pycache__/exceptions.cpython-311.pyc,,
47
+ attrs/__pycache__/filters.cpython-311.pyc,,
48
+ attrs/__pycache__/setters.cpython-311.pyc,,
49
+ attrs/__pycache__/validators.cpython-311.pyc,,
50
+ attrs/converters.py,sha256=8kQljrVwfSTRu8INwEk8SI0eGrzmWftsT7rM0EqyohM,76
51
+ attrs/exceptions.py,sha256=ACCCmg19-vDFaDPY9vFl199SPXCQMN_bENs4DALjzms,76
52
+ attrs/filters.py,sha256=VOUMZug9uEU6dUuA0dF1jInUK0PL3fLgP0VBS5d-CDE,73
53
+ attrs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
+ attrs/setters.py,sha256=eL1YidYQV3T2h9_SYIZSZR1FAcHGb1TuCTy0E0Lv2SU,73
55
+ attrs/validators.py,sha256=xcy6wD5TtTkdCG1f4XWbocPSO0faBjk5IfVJfP6SUj0,76
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs-25.1.0.dist-info/WHEEL ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs-25.1.0.dist-info/licenses/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Hynek Schlawack and the attrs contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__init__.py ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ from attr import (
4
+ NOTHING,
5
+ Attribute,
6
+ AttrsInstance,
7
+ Converter,
8
+ Factory,
9
+ NothingType,
10
+ _make_getattr,
11
+ assoc,
12
+ cmp_using,
13
+ define,
14
+ evolve,
15
+ field,
16
+ fields,
17
+ fields_dict,
18
+ frozen,
19
+ has,
20
+ make_class,
21
+ mutable,
22
+ resolve_types,
23
+ validate,
24
+ )
25
+ from attr._next_gen import asdict, astuple
26
+
27
+ from . import converters, exceptions, filters, setters, validators
28
+
29
+
30
+ __all__ = [
31
+ "NOTHING",
32
+ "Attribute",
33
+ "AttrsInstance",
34
+ "Converter",
35
+ "Factory",
36
+ "NothingType",
37
+ "__author__",
38
+ "__copyright__",
39
+ "__description__",
40
+ "__doc__",
41
+ "__email__",
42
+ "__license__",
43
+ "__title__",
44
+ "__url__",
45
+ "__version__",
46
+ "__version_info__",
47
+ "asdict",
48
+ "assoc",
49
+ "astuple",
50
+ "cmp_using",
51
+ "converters",
52
+ "define",
53
+ "evolve",
54
+ "exceptions",
55
+ "field",
56
+ "fields",
57
+ "fields_dict",
58
+ "filters",
59
+ "frozen",
60
+ "has",
61
+ "make_class",
62
+ "mutable",
63
+ "resolve_types",
64
+ "setters",
65
+ "validate",
66
+ "validators",
67
+ ]
68
+
69
+ __getattr__ = _make_getattr(__name__)
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__init__.pyi ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+
3
+ from typing import (
4
+ Any,
5
+ Callable,
6
+ Mapping,
7
+ Sequence,
8
+ overload,
9
+ TypeVar,
10
+ )
11
+
12
+ # Because we need to type our own stuff, we have to make everything from
13
+ # attr explicitly public too.
14
+ from attr import __author__ as __author__
15
+ from attr import __copyright__ as __copyright__
16
+ from attr import __description__ as __description__
17
+ from attr import __email__ as __email__
18
+ from attr import __license__ as __license__
19
+ from attr import __title__ as __title__
20
+ from attr import __url__ as __url__
21
+ from attr import __version__ as __version__
22
+ from attr import __version_info__ as __version_info__
23
+ from attr import assoc as assoc
24
+ from attr import Attribute as Attribute
25
+ from attr import AttrsInstance as AttrsInstance
26
+ from attr import cmp_using as cmp_using
27
+ from attr import converters as converters
28
+ from attr import Converter as Converter
29
+ from attr import evolve as evolve
30
+ from attr import exceptions as exceptions
31
+ from attr import Factory as Factory
32
+ from attr import fields as fields
33
+ from attr import fields_dict as fields_dict
34
+ from attr import filters as filters
35
+ from attr import has as has
36
+ from attr import make_class as make_class
37
+ from attr import NOTHING as NOTHING
38
+ from attr import resolve_types as resolve_types
39
+ from attr import setters as setters
40
+ from attr import validate as validate
41
+ from attr import validators as validators
42
+ from attr import attrib, asdict as asdict, astuple as astuple
43
+ from attr import NothingType as NothingType
44
+
45
+ if sys.version_info >= (3, 11):
46
+ from typing import dataclass_transform
47
+ else:
48
+ from typing_extensions import dataclass_transform
49
+
50
+ _T = TypeVar("_T")
51
+ _C = TypeVar("_C", bound=type)
52
+
53
+ _EqOrderType = bool | Callable[[Any], Any]
54
+ _ValidatorType = Callable[[Any, "Attribute[_T]", _T], Any]
55
+ _CallableConverterType = Callable[[Any], Any]
56
+ _ConverterType = _CallableConverterType | Converter[Any, Any]
57
+ _ReprType = Callable[[Any], str]
58
+ _ReprArgType = bool | _ReprType
59
+ _OnSetAttrType = Callable[[Any, "Attribute[Any]", Any], Any]
60
+ _OnSetAttrArgType = _OnSetAttrType | list[_OnSetAttrType] | setters._NoOpType
61
+ _FieldTransformer = Callable[
62
+ [type, list["Attribute[Any]"]], list["Attribute[Any]"]
63
+ ]
64
+ # FIXME: in reality, if multiple validators are passed they must be in a list
65
+ # or tuple, but those are invariant and so would prevent subtypes of
66
+ # _ValidatorType from working when passed in a list or tuple.
67
+ _ValidatorArgType = _ValidatorType[_T] | Sequence[_ValidatorType[_T]]
68
+
69
+ @overload
70
+ def field(
71
+ *,
72
+ default: None = ...,
73
+ validator: None = ...,
74
+ repr: _ReprArgType = ...,
75
+ hash: bool | None = ...,
76
+ init: bool = ...,
77
+ metadata: Mapping[Any, Any] | None = ...,
78
+ converter: None = ...,
79
+ factory: None = ...,
80
+ kw_only: bool = ...,
81
+ eq: bool | None = ...,
82
+ order: bool | None = ...,
83
+ on_setattr: _OnSetAttrArgType | None = ...,
84
+ alias: str | None = ...,
85
+ type: type | None = ...,
86
+ ) -> Any: ...
87
+
88
+ # This form catches an explicit None or no default and infers the type from the
89
+ # other arguments.
90
+ @overload
91
+ def field(
92
+ *,
93
+ default: None = ...,
94
+ validator: _ValidatorArgType[_T] | None = ...,
95
+ repr: _ReprArgType = ...,
96
+ hash: bool | None = ...,
97
+ init: bool = ...,
98
+ metadata: Mapping[Any, Any] | None = ...,
99
+ converter: _ConverterType
100
+ | list[_ConverterType]
101
+ | tuple[_ConverterType]
102
+ | None = ...,
103
+ factory: Callable[[], _T] | None = ...,
104
+ kw_only: bool = ...,
105
+ eq: _EqOrderType | None = ...,
106
+ order: _EqOrderType | None = ...,
107
+ on_setattr: _OnSetAttrArgType | None = ...,
108
+ alias: str | None = ...,
109
+ type: type | None = ...,
110
+ ) -> _T: ...
111
+
112
+ # This form catches an explicit default argument.
113
+ @overload
114
+ def field(
115
+ *,
116
+ default: _T,
117
+ validator: _ValidatorArgType[_T] | None = ...,
118
+ repr: _ReprArgType = ...,
119
+ hash: bool | None = ...,
120
+ init: bool = ...,
121
+ metadata: Mapping[Any, Any] | None = ...,
122
+ converter: _ConverterType
123
+ | list[_ConverterType]
124
+ | tuple[_ConverterType]
125
+ | None = ...,
126
+ factory: Callable[[], _T] | None = ...,
127
+ kw_only: bool = ...,
128
+ eq: _EqOrderType | None = ...,
129
+ order: _EqOrderType | None = ...,
130
+ on_setattr: _OnSetAttrArgType | None = ...,
131
+ alias: str | None = ...,
132
+ type: type | None = ...,
133
+ ) -> _T: ...
134
+
135
+ # This form covers type=non-Type: e.g. forward references (str), Any
136
+ @overload
137
+ def field(
138
+ *,
139
+ default: _T | None = ...,
140
+ validator: _ValidatorArgType[_T] | None = ...,
141
+ repr: _ReprArgType = ...,
142
+ hash: bool | None = ...,
143
+ init: bool = ...,
144
+ metadata: Mapping[Any, Any] | None = ...,
145
+ converter: _ConverterType
146
+ | list[_ConverterType]
147
+ | tuple[_ConverterType]
148
+ | None = ...,
149
+ factory: Callable[[], _T] | None = ...,
150
+ kw_only: bool = ...,
151
+ eq: _EqOrderType | None = ...,
152
+ order: _EqOrderType | None = ...,
153
+ on_setattr: _OnSetAttrArgType | None = ...,
154
+ alias: str | None = ...,
155
+ type: type | None = ...,
156
+ ) -> Any: ...
157
+ @overload
158
+ @dataclass_transform(field_specifiers=(attrib, field))
159
+ def define(
160
+ maybe_cls: _C,
161
+ *,
162
+ these: dict[str, Any] | None = ...,
163
+ repr: bool = ...,
164
+ unsafe_hash: bool | None = ...,
165
+ hash: bool | None = ...,
166
+ init: bool = ...,
167
+ slots: bool = ...,
168
+ frozen: bool = ...,
169
+ weakref_slot: bool = ...,
170
+ str: bool = ...,
171
+ auto_attribs: bool = ...,
172
+ kw_only: bool = ...,
173
+ cache_hash: bool = ...,
174
+ auto_exc: bool = ...,
175
+ eq: bool | None = ...,
176
+ order: bool | None = ...,
177
+ auto_detect: bool = ...,
178
+ getstate_setstate: bool | None = ...,
179
+ on_setattr: _OnSetAttrArgType | None = ...,
180
+ field_transformer: _FieldTransformer | None = ...,
181
+ match_args: bool = ...,
182
+ ) -> _C: ...
183
+ @overload
184
+ @dataclass_transform(field_specifiers=(attrib, field))
185
+ def define(
186
+ maybe_cls: None = ...,
187
+ *,
188
+ these: dict[str, Any] | None = ...,
189
+ repr: bool = ...,
190
+ unsafe_hash: bool | None = ...,
191
+ hash: bool | None = ...,
192
+ init: bool = ...,
193
+ slots: bool = ...,
194
+ frozen: bool = ...,
195
+ weakref_slot: bool = ...,
196
+ str: bool = ...,
197
+ auto_attribs: bool = ...,
198
+ kw_only: bool = ...,
199
+ cache_hash: bool = ...,
200
+ auto_exc: bool = ...,
201
+ eq: bool | None = ...,
202
+ order: bool | None = ...,
203
+ auto_detect: bool = ...,
204
+ getstate_setstate: bool | None = ...,
205
+ on_setattr: _OnSetAttrArgType | None = ...,
206
+ field_transformer: _FieldTransformer | None = ...,
207
+ match_args: bool = ...,
208
+ ) -> Callable[[_C], _C]: ...
209
+
210
+ mutable = define
211
+
212
+ @overload
213
+ @dataclass_transform(frozen_default=True, field_specifiers=(attrib, field))
214
+ def frozen(
215
+ maybe_cls: _C,
216
+ *,
217
+ these: dict[str, Any] | None = ...,
218
+ repr: bool = ...,
219
+ unsafe_hash: bool | None = ...,
220
+ hash: bool | None = ...,
221
+ init: bool = ...,
222
+ slots: bool = ...,
223
+ frozen: bool = ...,
224
+ weakref_slot: bool = ...,
225
+ str: bool = ...,
226
+ auto_attribs: bool = ...,
227
+ kw_only: bool = ...,
228
+ cache_hash: bool = ...,
229
+ auto_exc: bool = ...,
230
+ eq: bool | None = ...,
231
+ order: bool | None = ...,
232
+ auto_detect: bool = ...,
233
+ getstate_setstate: bool | None = ...,
234
+ on_setattr: _OnSetAttrArgType | None = ...,
235
+ field_transformer: _FieldTransformer | None = ...,
236
+ match_args: bool = ...,
237
+ ) -> _C: ...
238
+ @overload
239
+ @dataclass_transform(frozen_default=True, field_specifiers=(attrib, field))
240
+ def frozen(
241
+ maybe_cls: None = ...,
242
+ *,
243
+ these: dict[str, Any] | None = ...,
244
+ repr: bool = ...,
245
+ unsafe_hash: bool | None = ...,
246
+ hash: bool | None = ...,
247
+ init: bool = ...,
248
+ slots: bool = ...,
249
+ frozen: bool = ...,
250
+ weakref_slot: bool = ...,
251
+ str: bool = ...,
252
+ auto_attribs: bool = ...,
253
+ kw_only: bool = ...,
254
+ cache_hash: bool = ...,
255
+ auto_exc: bool = ...,
256
+ eq: bool | None = ...,
257
+ order: bool | None = ...,
258
+ auto_detect: bool = ...,
259
+ getstate_setstate: bool | None = ...,
260
+ on_setattr: _OnSetAttrArgType | None = ...,
261
+ field_transformer: _FieldTransformer | None = ...,
262
+ match_args: bool = ...,
263
+ ) -> Callable[[_C], _C]: ...
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (1.44 kB). View file
 
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__pycache__/converters.cpython-311.pyc ADDED
Binary file (270 Bytes). View file
 
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__pycache__/exceptions.cpython-311.pyc ADDED
Binary file (270 Bytes). View file
 
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__pycache__/filters.cpython-311.pyc ADDED
Binary file (264 Bytes). View file
 
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__pycache__/setters.cpython-311.pyc ADDED
Binary file (264 Bytes). View file
 
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/__pycache__/validators.cpython-311.pyc ADDED
Binary file (270 Bytes). View file
 
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/converters.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ from attr.converters import * # noqa: F403
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/exceptions.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ from attr.exceptions import * # noqa: F403
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/filters.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ from attr.filters import * # noqa: F403
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/py.typed ADDED
File without changes
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/setters.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ from attr.setters import * # noqa: F403
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/attrs/validators.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # SPDX-License-Identifier: MIT
2
+
3
+ from attr.validators import * # noqa: F403
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/frozenlist/__init__.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import types
4
+ from collections.abc import MutableSequence
5
+ from functools import total_ordering
6
+ from typing import Any, Type
7
+
8
+ __version__ = "1.5.0"
9
+
10
+ __all__ = ("FrozenList", "PyFrozenList") # type: Tuple[str, ...]
11
+
12
+
13
+ NO_EXTENSIONS = bool(os.environ.get("FROZENLIST_NO_EXTENSIONS")) # type: bool
14
+
15
+
16
+ @total_ordering
17
+ class FrozenList(MutableSequence):
18
+ __slots__ = ("_frozen", "_items")
19
+
20
+ if sys.version_info >= (3, 9):
21
+ __class_getitem__ = classmethod(types.GenericAlias)
22
+ else:
23
+
24
+ @classmethod
25
+ def __class_getitem__(
26
+ cls: Type["FrozenList"],
27
+ cls_item: Any,
28
+ ) -> Type["FrozenList"]:
29
+ return cls
30
+
31
+ def __init__(self, items=None):
32
+ self._frozen = False
33
+ if items is not None:
34
+ items = list(items)
35
+ else:
36
+ items = []
37
+ self._items = items
38
+
39
+ @property
40
+ def frozen(self):
41
+ return self._frozen
42
+
43
+ def freeze(self):
44
+ self._frozen = True
45
+
46
+ def __getitem__(self, index):
47
+ return self._items[index]
48
+
49
+ def __setitem__(self, index, value):
50
+ if self._frozen:
51
+ raise RuntimeError("Cannot modify frozen list.")
52
+ self._items[index] = value
53
+
54
+ def __delitem__(self, index):
55
+ if self._frozen:
56
+ raise RuntimeError("Cannot modify frozen list.")
57
+ del self._items[index]
58
+
59
+ def __len__(self):
60
+ return self._items.__len__()
61
+
62
+ def __iter__(self):
63
+ return self._items.__iter__()
64
+
65
+ def __reversed__(self):
66
+ return self._items.__reversed__()
67
+
68
+ def __eq__(self, other):
69
+ return list(self) == other
70
+
71
+ def __le__(self, other):
72
+ return list(self) <= other
73
+
74
+ def insert(self, pos, item):
75
+ if self._frozen:
76
+ raise RuntimeError("Cannot modify frozen list.")
77
+ self._items.insert(pos, item)
78
+
79
+ def __repr__(self):
80
+ return f"<FrozenList(frozen={self._frozen}, {self._items!r})>"
81
+
82
+ def __hash__(self):
83
+ if self._frozen:
84
+ return hash(tuple(self))
85
+ else:
86
+ raise RuntimeError("Cannot hash unfrozen list.")
87
+
88
+
89
+ PyFrozenList = FrozenList
90
+
91
+
92
+ if not NO_EXTENSIONS:
93
+ try:
94
+ from ._frozenlist import FrozenList as CFrozenList # type: ignore
95
+ except ImportError: # pragma: no cover
96
+ pass
97
+ else:
98
+ FrozenList = CFrozenList # type: ignore
.venv/lib/python3.11/site-packages/ray/_private/runtime_env/agent/thirdparty_files/frozenlist/__init__.pyi ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import (
2
+ Generic,
3
+ Iterable,
4
+ Iterator,
5
+ List,
6
+ MutableSequence,
7
+ Optional,
8
+ TypeVar,
9
+ Union,
10
+ overload,
11
+ )
12
+
13
+ _T = TypeVar("_T")
14
+ _Arg = Union[List[_T], Iterable[_T]]
15
+
16
+ class FrozenList(MutableSequence[_T], Generic[_T]):
17
+ def __init__(self, items: Optional[_Arg[_T]] = None) -> None: ...
18
+ @property
19
+ def frozen(self) -> bool: ...
20
+ def freeze(self) -> None: ...
21
+ @overload
22
+ def __getitem__(self, i: int) -> _T: ...
23
+ @overload
24
+ def __getitem__(self, s: slice) -> FrozenList[_T]: ...
25
+ @overload
26
+ def __setitem__(self, i: int, o: _T) -> None: ...
27
+ @overload
28
+ def __setitem__(self, s: slice, o: Iterable[_T]) -> None: ...
29
+ @overload
30
+ def __delitem__(self, i: int) -> None: ...
31
+ @overload
32
+ def __delitem__(self, i: slice) -> None: ...
33
+ def __len__(self) -> int: ...
34
+ def __iter__(self) -> Iterator[_T]: ...
35
+ def __reversed__(self) -> Iterator[_T]: ...
36
+ def __eq__(self, other: object) -> bool: ...
37
+ def __le__(self, other: FrozenList[_T]) -> bool: ...
38
+ def __ne__(self, other: object) -> bool: ...
39
+ def __lt__(self, other: FrozenList[_T]) -> bool: ...
40
+ def __ge__(self, other: FrozenList[_T]) -> bool: ...
41
+ def __gt__(self, other: FrozenList[_T]) -> bool: ...
42
+ def insert(self, pos: int, item: _T) -> None: ...
43
+ def __repr__(self) -> str: ...
44
+ def __hash__(self) -> int: ...
45
+
46
+ # types for C accelerators are the same
47
+ CFrozenList = PyFrozenList = FrozenList