SQLAlchemy 2.0.47__cp313-cp313t-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. sqlalchemy/__init__.py +283 -0
  2. sqlalchemy/connectors/__init__.py +18 -0
  3. sqlalchemy/connectors/aioodbc.py +184 -0
  4. sqlalchemy/connectors/asyncio.py +429 -0
  5. sqlalchemy/connectors/pyodbc.py +250 -0
  6. sqlalchemy/cyextension/__init__.py +6 -0
  7. sqlalchemy/cyextension/collections.cp313t-win_amd64.pyd +0 -0
  8. sqlalchemy/cyextension/collections.pyx +409 -0
  9. sqlalchemy/cyextension/immutabledict.cp313t-win_amd64.pyd +0 -0
  10. sqlalchemy/cyextension/immutabledict.pxd +8 -0
  11. sqlalchemy/cyextension/immutabledict.pyx +133 -0
  12. sqlalchemy/cyextension/processors.cp313t-win_amd64.pyd +0 -0
  13. sqlalchemy/cyextension/processors.pyx +68 -0
  14. sqlalchemy/cyextension/resultproxy.cp313t-win_amd64.pyd +0 -0
  15. sqlalchemy/cyextension/resultproxy.pyx +102 -0
  16. sqlalchemy/cyextension/util.cp313t-win_amd64.pyd +0 -0
  17. sqlalchemy/cyextension/util.pyx +90 -0
  18. sqlalchemy/dialects/__init__.py +62 -0
  19. sqlalchemy/dialects/_typing.py +30 -0
  20. sqlalchemy/dialects/mssql/__init__.py +88 -0
  21. sqlalchemy/dialects/mssql/aioodbc.py +63 -0
  22. sqlalchemy/dialects/mssql/base.py +4093 -0
  23. sqlalchemy/dialects/mssql/information_schema.py +285 -0
  24. sqlalchemy/dialects/mssql/json.py +129 -0
  25. sqlalchemy/dialects/mssql/provision.py +185 -0
  26. sqlalchemy/dialects/mssql/pymssql.py +126 -0
  27. sqlalchemy/dialects/mssql/pyodbc.py +760 -0
  28. sqlalchemy/dialects/mysql/__init__.py +104 -0
  29. sqlalchemy/dialects/mysql/aiomysql.py +250 -0
  30. sqlalchemy/dialects/mysql/asyncmy.py +231 -0
  31. sqlalchemy/dialects/mysql/base.py +3949 -0
  32. sqlalchemy/dialects/mysql/cymysql.py +106 -0
  33. sqlalchemy/dialects/mysql/dml.py +225 -0
  34. sqlalchemy/dialects/mysql/enumerated.py +282 -0
  35. sqlalchemy/dialects/mysql/expression.py +146 -0
  36. sqlalchemy/dialects/mysql/json.py +91 -0
  37. sqlalchemy/dialects/mysql/mariadb.py +72 -0
  38. sqlalchemy/dialects/mysql/mariadbconnector.py +322 -0
  39. sqlalchemy/dialects/mysql/mysqlconnector.py +302 -0
  40. sqlalchemy/dialects/mysql/mysqldb.py +314 -0
  41. sqlalchemy/dialects/mysql/provision.py +153 -0
  42. sqlalchemy/dialects/mysql/pymysql.py +158 -0
  43. sqlalchemy/dialects/mysql/pyodbc.py +157 -0
  44. sqlalchemy/dialects/mysql/reflection.py +727 -0
  45. sqlalchemy/dialects/mysql/reserved_words.py +570 -0
  46. sqlalchemy/dialects/mysql/types.py +835 -0
  47. sqlalchemy/dialects/oracle/__init__.py +81 -0
  48. sqlalchemy/dialects/oracle/base.py +3802 -0
  49. sqlalchemy/dialects/oracle/cx_oracle.py +1555 -0
  50. sqlalchemy/dialects/oracle/dictionary.py +507 -0
  51. sqlalchemy/dialects/oracle/oracledb.py +941 -0
  52. sqlalchemy/dialects/oracle/provision.py +297 -0
  53. sqlalchemy/dialects/oracle/types.py +316 -0
  54. sqlalchemy/dialects/oracle/vector.py +365 -0
  55. sqlalchemy/dialects/postgresql/__init__.py +167 -0
  56. sqlalchemy/dialects/postgresql/_psycopg_common.py +189 -0
  57. sqlalchemy/dialects/postgresql/array.py +519 -0
  58. sqlalchemy/dialects/postgresql/asyncpg.py +1284 -0
  59. sqlalchemy/dialects/postgresql/base.py +5378 -0
  60. sqlalchemy/dialects/postgresql/dml.py +339 -0
  61. sqlalchemy/dialects/postgresql/ext.py +540 -0
  62. sqlalchemy/dialects/postgresql/hstore.py +406 -0
  63. sqlalchemy/dialects/postgresql/json.py +404 -0
  64. sqlalchemy/dialects/postgresql/named_types.py +524 -0
  65. sqlalchemy/dialects/postgresql/operators.py +129 -0
  66. sqlalchemy/dialects/postgresql/pg8000.py +669 -0
  67. sqlalchemy/dialects/postgresql/pg_catalog.py +326 -0
  68. sqlalchemy/dialects/postgresql/provision.py +183 -0
  69. sqlalchemy/dialects/postgresql/psycopg.py +862 -0
  70. sqlalchemy/dialects/postgresql/psycopg2.py +892 -0
  71. sqlalchemy/dialects/postgresql/psycopg2cffi.py +61 -0
  72. sqlalchemy/dialects/postgresql/ranges.py +1031 -0
  73. sqlalchemy/dialects/postgresql/types.py +313 -0
  74. sqlalchemy/dialects/sqlite/__init__.py +57 -0
  75. sqlalchemy/dialects/sqlite/aiosqlite.py +482 -0
  76. sqlalchemy/dialects/sqlite/base.py +3056 -0
  77. sqlalchemy/dialects/sqlite/dml.py +263 -0
  78. sqlalchemy/dialects/sqlite/json.py +92 -0
  79. sqlalchemy/dialects/sqlite/provision.py +229 -0
  80. sqlalchemy/dialects/sqlite/pysqlcipher.py +157 -0
  81. sqlalchemy/dialects/sqlite/pysqlite.py +756 -0
  82. sqlalchemy/dialects/type_migration_guidelines.txt +145 -0
  83. sqlalchemy/engine/__init__.py +62 -0
  84. sqlalchemy/engine/_py_processors.py +136 -0
  85. sqlalchemy/engine/_py_row.py +128 -0
  86. sqlalchemy/engine/_py_util.py +74 -0
  87. sqlalchemy/engine/base.py +3390 -0
  88. sqlalchemy/engine/characteristics.py +155 -0
  89. sqlalchemy/engine/create.py +893 -0
  90. sqlalchemy/engine/cursor.py +2298 -0
  91. sqlalchemy/engine/default.py +2394 -0
  92. sqlalchemy/engine/events.py +965 -0
  93. sqlalchemy/engine/interfaces.py +3471 -0
  94. sqlalchemy/engine/mock.py +134 -0
  95. sqlalchemy/engine/processors.py +61 -0
  96. sqlalchemy/engine/reflection.py +2102 -0
  97. sqlalchemy/engine/result.py +2399 -0
  98. sqlalchemy/engine/row.py +400 -0
  99. sqlalchemy/engine/strategies.py +16 -0
  100. sqlalchemy/engine/url.py +924 -0
  101. sqlalchemy/engine/util.py +167 -0
  102. sqlalchemy/event/__init__.py +26 -0
  103. sqlalchemy/event/api.py +220 -0
  104. sqlalchemy/event/attr.py +676 -0
  105. sqlalchemy/event/base.py +472 -0
  106. sqlalchemy/event/legacy.py +258 -0
  107. sqlalchemy/event/registry.py +390 -0
  108. sqlalchemy/events.py +17 -0
  109. sqlalchemy/exc.py +832 -0
  110. sqlalchemy/ext/__init__.py +11 -0
  111. sqlalchemy/ext/associationproxy.py +2027 -0
  112. sqlalchemy/ext/asyncio/__init__.py +25 -0
  113. sqlalchemy/ext/asyncio/base.py +281 -0
  114. sqlalchemy/ext/asyncio/engine.py +1471 -0
  115. sqlalchemy/ext/asyncio/exc.py +21 -0
  116. sqlalchemy/ext/asyncio/result.py +965 -0
  117. sqlalchemy/ext/asyncio/scoping.py +1599 -0
  118. sqlalchemy/ext/asyncio/session.py +1947 -0
  119. sqlalchemy/ext/automap.py +1701 -0
  120. sqlalchemy/ext/baked.py +570 -0
  121. sqlalchemy/ext/compiler.py +600 -0
  122. sqlalchemy/ext/declarative/__init__.py +65 -0
  123. sqlalchemy/ext/declarative/extensions.py +564 -0
  124. sqlalchemy/ext/horizontal_shard.py +478 -0
  125. sqlalchemy/ext/hybrid.py +1535 -0
  126. sqlalchemy/ext/indexable.py +364 -0
  127. sqlalchemy/ext/instrumentation.py +450 -0
  128. sqlalchemy/ext/mutable.py +1085 -0
  129. sqlalchemy/ext/mypy/__init__.py +6 -0
  130. sqlalchemy/ext/mypy/apply.py +324 -0
  131. sqlalchemy/ext/mypy/decl_class.py +515 -0
  132. sqlalchemy/ext/mypy/infer.py +590 -0
  133. sqlalchemy/ext/mypy/names.py +335 -0
  134. sqlalchemy/ext/mypy/plugin.py +303 -0
  135. sqlalchemy/ext/mypy/util.py +357 -0
  136. sqlalchemy/ext/orderinglist.py +439 -0
  137. sqlalchemy/ext/serializer.py +185 -0
  138. sqlalchemy/future/__init__.py +16 -0
  139. sqlalchemy/future/engine.py +15 -0
  140. sqlalchemy/inspection.py +174 -0
  141. sqlalchemy/log.py +288 -0
  142. sqlalchemy/orm/__init__.py +171 -0
  143. sqlalchemy/orm/_orm_constructors.py +2661 -0
  144. sqlalchemy/orm/_typing.py +179 -0
  145. sqlalchemy/orm/attributes.py +2845 -0
  146. sqlalchemy/orm/base.py +971 -0
  147. sqlalchemy/orm/bulk_persistence.py +2135 -0
  148. sqlalchemy/orm/clsregistry.py +571 -0
  149. sqlalchemy/orm/collections.py +1627 -0
  150. sqlalchemy/orm/context.py +3334 -0
  151. sqlalchemy/orm/decl_api.py +2004 -0
  152. sqlalchemy/orm/decl_base.py +2192 -0
  153. sqlalchemy/orm/dependency.py +1302 -0
  154. sqlalchemy/orm/descriptor_props.py +1092 -0
  155. sqlalchemy/orm/dynamic.py +300 -0
  156. sqlalchemy/orm/evaluator.py +379 -0
  157. sqlalchemy/orm/events.py +3252 -0
  158. sqlalchemy/orm/exc.py +237 -0
  159. sqlalchemy/orm/identity.py +302 -0
  160. sqlalchemy/orm/instrumentation.py +754 -0
  161. sqlalchemy/orm/interfaces.py +1496 -0
  162. sqlalchemy/orm/loading.py +1686 -0
  163. sqlalchemy/orm/mapped_collection.py +557 -0
  164. sqlalchemy/orm/mapper.py +4444 -0
  165. sqlalchemy/orm/path_registry.py +809 -0
  166. sqlalchemy/orm/persistence.py +1788 -0
  167. sqlalchemy/orm/properties.py +935 -0
  168. sqlalchemy/orm/query.py +3459 -0
  169. sqlalchemy/orm/relationships.py +3508 -0
  170. sqlalchemy/orm/scoping.py +2148 -0
  171. sqlalchemy/orm/session.py +5280 -0
  172. sqlalchemy/orm/state.py +1168 -0
  173. sqlalchemy/orm/state_changes.py +196 -0
  174. sqlalchemy/orm/strategies.py +3470 -0
  175. sqlalchemy/orm/strategy_options.py +2568 -0
  176. sqlalchemy/orm/sync.py +164 -0
  177. sqlalchemy/orm/unitofwork.py +796 -0
  178. sqlalchemy/orm/util.py +2403 -0
  179. sqlalchemy/orm/writeonly.py +674 -0
  180. sqlalchemy/pool/__init__.py +44 -0
  181. sqlalchemy/pool/base.py +1524 -0
  182. sqlalchemy/pool/events.py +375 -0
  183. sqlalchemy/pool/impl.py +588 -0
  184. sqlalchemy/py.typed +0 -0
  185. sqlalchemy/schema.py +69 -0
  186. sqlalchemy/sql/__init__.py +145 -0
  187. sqlalchemy/sql/_dml_constructors.py +132 -0
  188. sqlalchemy/sql/_elements_constructors.py +1872 -0
  189. sqlalchemy/sql/_orm_types.py +20 -0
  190. sqlalchemy/sql/_py_util.py +75 -0
  191. sqlalchemy/sql/_selectable_constructors.py +763 -0
  192. sqlalchemy/sql/_typing.py +482 -0
  193. sqlalchemy/sql/annotation.py +587 -0
  194. sqlalchemy/sql/base.py +2293 -0
  195. sqlalchemy/sql/cache_key.py +1057 -0
  196. sqlalchemy/sql/coercions.py +1404 -0
  197. sqlalchemy/sql/compiler.py +8081 -0
  198. sqlalchemy/sql/crud.py +1752 -0
  199. sqlalchemy/sql/ddl.py +1444 -0
  200. sqlalchemy/sql/default_comparator.py +551 -0
  201. sqlalchemy/sql/dml.py +1850 -0
  202. sqlalchemy/sql/elements.py +5589 -0
  203. sqlalchemy/sql/events.py +458 -0
  204. sqlalchemy/sql/expression.py +159 -0
  205. sqlalchemy/sql/functions.py +2158 -0
  206. sqlalchemy/sql/lambdas.py +1442 -0
  207. sqlalchemy/sql/naming.py +209 -0
  208. sqlalchemy/sql/operators.py +2623 -0
  209. sqlalchemy/sql/roles.py +323 -0
  210. sqlalchemy/sql/schema.py +6222 -0
  211. sqlalchemy/sql/selectable.py +7265 -0
  212. sqlalchemy/sql/sqltypes.py +3930 -0
  213. sqlalchemy/sql/traversals.py +1024 -0
  214. sqlalchemy/sql/type_api.py +2368 -0
  215. sqlalchemy/sql/util.py +1485 -0
  216. sqlalchemy/sql/visitors.py +1164 -0
  217. sqlalchemy/testing/__init__.py +96 -0
  218. sqlalchemy/testing/assertions.py +994 -0
  219. sqlalchemy/testing/assertsql.py +520 -0
  220. sqlalchemy/testing/asyncio.py +135 -0
  221. sqlalchemy/testing/config.py +434 -0
  222. sqlalchemy/testing/engines.py +483 -0
  223. sqlalchemy/testing/entities.py +117 -0
  224. sqlalchemy/testing/exclusions.py +476 -0
  225. sqlalchemy/testing/fixtures/__init__.py +28 -0
  226. sqlalchemy/testing/fixtures/base.py +384 -0
  227. sqlalchemy/testing/fixtures/mypy.py +332 -0
  228. sqlalchemy/testing/fixtures/orm.py +227 -0
  229. sqlalchemy/testing/fixtures/sql.py +482 -0
  230. sqlalchemy/testing/pickleable.py +155 -0
  231. sqlalchemy/testing/plugin/__init__.py +6 -0
  232. sqlalchemy/testing/plugin/bootstrap.py +51 -0
  233. sqlalchemy/testing/plugin/plugin_base.py +828 -0
  234. sqlalchemy/testing/plugin/pytestplugin.py +892 -0
  235. sqlalchemy/testing/profiling.py +329 -0
  236. sqlalchemy/testing/provision.py +603 -0
  237. sqlalchemy/testing/requirements.py +1945 -0
  238. sqlalchemy/testing/schema.py +198 -0
  239. sqlalchemy/testing/suite/__init__.py +19 -0
  240. sqlalchemy/testing/suite/test_cte.py +237 -0
  241. sqlalchemy/testing/suite/test_ddl.py +389 -0
  242. sqlalchemy/testing/suite/test_deprecations.py +153 -0
  243. sqlalchemy/testing/suite/test_dialect.py +776 -0
  244. sqlalchemy/testing/suite/test_insert.py +630 -0
  245. sqlalchemy/testing/suite/test_reflection.py +3557 -0
  246. sqlalchemy/testing/suite/test_results.py +504 -0
  247. sqlalchemy/testing/suite/test_rowcount.py +258 -0
  248. sqlalchemy/testing/suite/test_select.py +2010 -0
  249. sqlalchemy/testing/suite/test_sequence.py +317 -0
  250. sqlalchemy/testing/suite/test_types.py +2147 -0
  251. sqlalchemy/testing/suite/test_unicode_ddl.py +189 -0
  252. sqlalchemy/testing/suite/test_update_delete.py +139 -0
  253. sqlalchemy/testing/util.py +535 -0
  254. sqlalchemy/testing/warnings.py +52 -0
  255. sqlalchemy/types.py +74 -0
  256. sqlalchemy/util/__init__.py +162 -0
  257. sqlalchemy/util/_collections.py +712 -0
  258. sqlalchemy/util/_concurrency_py3k.py +288 -0
  259. sqlalchemy/util/_has_cy.py +40 -0
  260. sqlalchemy/util/_py_collections.py +541 -0
  261. sqlalchemy/util/compat.py +421 -0
  262. sqlalchemy/util/concurrency.py +110 -0
  263. sqlalchemy/util/deprecations.py +401 -0
  264. sqlalchemy/util/langhelpers.py +2203 -0
  265. sqlalchemy/util/preloaded.py +150 -0
  266. sqlalchemy/util/queue.py +322 -0
  267. sqlalchemy/util/tool_support.py +201 -0
  268. sqlalchemy/util/topological.py +120 -0
  269. sqlalchemy/util/typing.py +734 -0
  270. sqlalchemy-2.0.47.dist-info/METADATA +243 -0
  271. sqlalchemy-2.0.47.dist-info/RECORD +274 -0
  272. sqlalchemy-2.0.47.dist-info/WHEEL +5 -0
  273. sqlalchemy-2.0.47.dist-info/licenses/LICENSE +19 -0
  274. sqlalchemy-2.0.47.dist-info/top_level.txt +1 -0
@@ -0,0 +1,541 @@
1
+ # util/_py_collections.py
2
+ # Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
3
+ # <see AUTHORS file>
4
+ #
5
+ # This module is part of SQLAlchemy and is released under
6
+ # the MIT License: https://www.opensource.org/licenses/mit-license.php
7
+ # mypy: allow-untyped-defs, allow-untyped-calls
8
+
9
+ from __future__ import annotations
10
+
11
+ from itertools import filterfalse
12
+ from typing import AbstractSet
13
+ from typing import Any
14
+ from typing import Callable
15
+ from typing import cast
16
+ from typing import Collection
17
+ from typing import Dict
18
+ from typing import Iterable
19
+ from typing import Iterator
20
+ from typing import List
21
+ from typing import Mapping
22
+ from typing import NoReturn
23
+ from typing import Optional
24
+ from typing import Set
25
+ from typing import Tuple
26
+ from typing import TYPE_CHECKING
27
+ from typing import TypeVar
28
+ from typing import Union
29
+
30
+ from ..util.typing import Self
31
+
32
+ _T = TypeVar("_T", bound=Any)
33
+ _S = TypeVar("_S", bound=Any)
34
+ _KT = TypeVar("_KT", bound=Any)
35
+ _VT = TypeVar("_VT", bound=Any)
36
+
37
+
38
+ class ReadOnlyContainer:
39
+ __slots__ = ()
40
+
41
+ def _readonly(self, *arg: Any, **kw: Any) -> NoReturn:
42
+ raise TypeError(
43
+ "%s object is immutable and/or readonly" % self.__class__.__name__
44
+ )
45
+
46
+ def _immutable(self, *arg: Any, **kw: Any) -> NoReturn:
47
+ raise TypeError("%s object is immutable" % self.__class__.__name__)
48
+
49
+ def __delitem__(self, key: Any) -> NoReturn:
50
+ self._readonly()
51
+
52
+ def __setitem__(self, key: Any, value: Any) -> NoReturn:
53
+ self._readonly()
54
+
55
+ def __setattr__(self, key: str, value: Any) -> NoReturn:
56
+ self._readonly()
57
+
58
+
59
+ class ImmutableDictBase(ReadOnlyContainer, Dict[_KT, _VT]):
60
+ if TYPE_CHECKING:
61
+
62
+ def __new__(cls, *args: Any) -> Self: ...
63
+
64
+ def __init__(cls, *args: Any): ...
65
+
66
+ def _readonly(self, *arg: Any, **kw: Any) -> NoReturn:
67
+ self._immutable()
68
+
69
+ def clear(self) -> NoReturn:
70
+ self._readonly()
71
+
72
+ def pop(self, key: Any, default: Optional[Any] = None) -> NoReturn:
73
+ self._readonly()
74
+
75
+ def popitem(self) -> NoReturn:
76
+ self._readonly()
77
+
78
+ def setdefault(self, key: Any, default: Optional[Any] = None) -> NoReturn:
79
+ self._readonly()
80
+
81
+ def update(self, *arg: Any, **kw: Any) -> NoReturn:
82
+ self._readonly()
83
+
84
+
85
+ class immutabledict(ImmutableDictBase[_KT, _VT]):
86
+ def __new__(cls, *args):
87
+ new = ImmutableDictBase.__new__(cls)
88
+ dict.__init__(new, *args)
89
+ return new
90
+
91
+ def __init__(
92
+ self, *args: Union[Mapping[_KT, _VT], Iterable[Tuple[_KT, _VT]]]
93
+ ):
94
+ pass
95
+
96
+ def __reduce__(self):
97
+ return immutabledict, (dict(self),)
98
+
99
+ def union(
100
+ self, __d: Optional[Mapping[_KT, _VT]] = None
101
+ ) -> immutabledict[_KT, _VT]:
102
+ if not __d:
103
+ return self
104
+
105
+ new = ImmutableDictBase.__new__(self.__class__)
106
+ dict.__init__(new, self)
107
+ dict.update(new, __d)
108
+ return new
109
+
110
+ def _union_w_kw(
111
+ self, __d: Optional[Mapping[_KT, _VT]] = None, **kw: _VT
112
+ ) -> immutabledict[_KT, _VT]:
113
+ # not sure if C version works correctly w/ this yet
114
+ if not __d and not kw:
115
+ return self
116
+
117
+ new = ImmutableDictBase.__new__(self.__class__)
118
+ dict.__init__(new, self)
119
+ if __d:
120
+ dict.update(new, __d)
121
+ dict.update(new, kw)
122
+ return new
123
+
124
+ def merge_with(
125
+ self, *dicts: Optional[Mapping[_KT, _VT]]
126
+ ) -> immutabledict[_KT, _VT]:
127
+ new = None
128
+ for d in dicts:
129
+ if d:
130
+ if new is None:
131
+ new = ImmutableDictBase.__new__(self.__class__)
132
+ dict.__init__(new, self)
133
+ dict.update(new, d)
134
+ if new is None:
135
+ return self
136
+
137
+ return new
138
+
139
+ def __repr__(self) -> str:
140
+ return "immutabledict(%s)" % dict.__repr__(self)
141
+
142
+ # PEP 584
143
+ def __ior__(self, __value: Any) -> NoReturn: # type: ignore
144
+ self._readonly()
145
+
146
+ def __or__( # type: ignore[override]
147
+ self, __value: Mapping[_KT, _VT]
148
+ ) -> immutabledict[_KT, _VT]:
149
+ return immutabledict(
150
+ super().__or__(__value), # type: ignore[call-overload]
151
+ )
152
+
153
+ def __ror__( # type: ignore[override]
154
+ self, __value: Mapping[_KT, _VT]
155
+ ) -> immutabledict[_KT, _VT]:
156
+ return immutabledict(
157
+ super().__ror__(__value), # type: ignore[call-overload]
158
+ )
159
+
160
+
161
+ class OrderedSet(Set[_T]):
162
+ __slots__ = ("_list",)
163
+
164
+ _list: List[_T]
165
+
166
+ def __init__(self, d: Optional[Iterable[_T]] = None) -> None:
167
+ if d is not None:
168
+ self._list = unique_list(d)
169
+ super().update(self._list)
170
+ else:
171
+ self._list = []
172
+
173
+ def copy(self) -> OrderedSet[_T]:
174
+ cp = self.__class__()
175
+ cp._list = self._list.copy()
176
+ set.update(cp, cp._list)
177
+ return cp
178
+
179
+ def add(self, element: _T) -> None:
180
+ if element not in self:
181
+ self._list.append(element)
182
+ super().add(element)
183
+
184
+ def remove(self, element: _T) -> None:
185
+ super().remove(element)
186
+ self._list.remove(element)
187
+
188
+ def pop(self) -> _T:
189
+ try:
190
+ value = self._list.pop()
191
+ except IndexError:
192
+ raise KeyError("pop from an empty set") from None
193
+ super().remove(value)
194
+ return value
195
+
196
+ def insert(self, pos: int, element: _T) -> None:
197
+ if element not in self:
198
+ self._list.insert(pos, element)
199
+ super().add(element)
200
+
201
+ def discard(self, element: _T) -> None:
202
+ if element in self:
203
+ self._list.remove(element)
204
+ super().remove(element)
205
+
206
+ def clear(self) -> None:
207
+ super().clear()
208
+ self._list = []
209
+
210
+ def __getitem__(self, key: int) -> _T:
211
+ return self._list[key]
212
+
213
+ def __iter__(self) -> Iterator[_T]:
214
+ return iter(self._list)
215
+
216
+ def __add__(self, other: Iterator[_T]) -> OrderedSet[_T]:
217
+ return self.union(other)
218
+
219
+ def __repr__(self) -> str:
220
+ return "%s(%r)" % (self.__class__.__name__, self._list)
221
+
222
+ __str__ = __repr__
223
+
224
+ def update(self, *iterables: Iterable[_T]) -> None:
225
+ for iterable in iterables:
226
+ for e in iterable:
227
+ if e not in self:
228
+ self._list.append(e)
229
+ super().add(e)
230
+
231
+ def __ior__(self, other: AbstractSet[_S]) -> OrderedSet[Union[_T, _S]]:
232
+ self.update(other)
233
+ return self
234
+
235
+ def union(self, *other: Iterable[_S]) -> OrderedSet[Union[_T, _S]]:
236
+ result: OrderedSet[Union[_T, _S]] = self.copy()
237
+ result.update(*other)
238
+ return result
239
+
240
+ def __or__(self, other: AbstractSet[_S]) -> OrderedSet[Union[_T, _S]]:
241
+ return self.union(other)
242
+
243
+ def intersection(self, *other: Iterable[Any]) -> OrderedSet[_T]:
244
+ other_set: Set[Any] = set()
245
+ other_set.update(*other)
246
+ return self.__class__(a for a in self if a in other_set)
247
+
248
+ def __and__(self, other: AbstractSet[object]) -> OrderedSet[_T]:
249
+ return self.intersection(other)
250
+
251
+ def symmetric_difference(self, other: Iterable[_T]) -> OrderedSet[_T]:
252
+ collection: Collection[_T]
253
+ if isinstance(other, set):
254
+ collection = other_set = other
255
+ elif isinstance(other, Collection):
256
+ collection = other
257
+ other_set = set(other)
258
+ else:
259
+ collection = list(other)
260
+ other_set = set(collection)
261
+ result = self.__class__(a for a in self if a not in other_set)
262
+ result.update(a for a in collection if a not in self)
263
+ return result
264
+
265
+ def __xor__(self, other: AbstractSet[_S]) -> OrderedSet[Union[_T, _S]]:
266
+ return cast(OrderedSet[Union[_T, _S]], self).symmetric_difference(
267
+ other
268
+ )
269
+
270
+ def difference(self, *other: Iterable[Any]) -> OrderedSet[_T]:
271
+ other_set = super().difference(*other)
272
+ return self.__class__(a for a in self._list if a in other_set)
273
+
274
+ def __sub__(self, other: AbstractSet[Optional[_T]]) -> OrderedSet[_T]:
275
+ return self.difference(other)
276
+
277
+ def intersection_update(self, *other: Iterable[Any]) -> None:
278
+ super().intersection_update(*other)
279
+ self._list = [a for a in self._list if a in self]
280
+
281
+ def __iand__(self, other: AbstractSet[object]) -> OrderedSet[_T]:
282
+ self.intersection_update(other)
283
+ return self
284
+
285
+ def symmetric_difference_update(self, other: Iterable[Any]) -> None:
286
+ collection = other if isinstance(other, Collection) else list(other)
287
+ super().symmetric_difference_update(collection)
288
+ self._list = [a for a in self._list if a in self]
289
+ self._list += [a for a in collection if a in self]
290
+
291
+ def __ixor__(self, other: AbstractSet[_S]) -> OrderedSet[Union[_T, _S]]:
292
+ self.symmetric_difference_update(other)
293
+ return cast(OrderedSet[Union[_T, _S]], self)
294
+
295
+ def difference_update(self, *other: Iterable[Any]) -> None:
296
+ super().difference_update(*other)
297
+ self._list = [a for a in self._list if a in self]
298
+
299
+ def __isub__(self, other: AbstractSet[Optional[_T]]) -> OrderedSet[_T]: # type: ignore # noqa: E501
300
+ self.difference_update(other)
301
+ return self
302
+
303
+
304
+ class IdentitySet:
305
+ """A set that considers only object id() for uniqueness.
306
+
307
+ This strategy has edge cases for builtin types- it's possible to have
308
+ two 'foo' strings in one of these sets, for example. Use sparingly.
309
+
310
+ """
311
+
312
+ _members: Dict[int, Any]
313
+
314
+ def __init__(self, iterable: Optional[Iterable[Any]] = None):
315
+ self._members = dict()
316
+ if iterable:
317
+ self.update(iterable)
318
+
319
+ def add(self, value: Any) -> None:
320
+ self._members[id(value)] = value
321
+
322
+ def __contains__(self, value: Any) -> bool:
323
+ return id(value) in self._members
324
+
325
+ def remove(self, value: Any) -> None:
326
+ del self._members[id(value)]
327
+
328
+ def discard(self, value: Any) -> None:
329
+ try:
330
+ self.remove(value)
331
+ except KeyError:
332
+ pass
333
+
334
+ def pop(self) -> Any:
335
+ try:
336
+ pair = self._members.popitem()
337
+ return pair[1]
338
+ except KeyError:
339
+ raise KeyError("pop from an empty set")
340
+
341
+ def clear(self) -> None:
342
+ self._members.clear()
343
+
344
+ def __eq__(self, other: Any) -> bool:
345
+ if isinstance(other, IdentitySet):
346
+ return self._members == other._members
347
+ else:
348
+ return False
349
+
350
+ def __ne__(self, other: Any) -> bool:
351
+ if isinstance(other, IdentitySet):
352
+ return self._members != other._members
353
+ else:
354
+ return True
355
+
356
+ def issubset(self, iterable: Iterable[Any]) -> bool:
357
+ if isinstance(iterable, self.__class__):
358
+ other = iterable
359
+ else:
360
+ other = self.__class__(iterable)
361
+
362
+ if len(self) > len(other):
363
+ return False
364
+ for m in filterfalse(
365
+ other._members.__contains__, iter(self._members.keys())
366
+ ):
367
+ return False
368
+ return True
369
+
370
+ def __le__(self, other: Any) -> bool:
371
+ if not isinstance(other, IdentitySet):
372
+ return NotImplemented
373
+ return self.issubset(other)
374
+
375
+ def __lt__(self, other: Any) -> bool:
376
+ if not isinstance(other, IdentitySet):
377
+ return NotImplemented
378
+ return len(self) < len(other) and self.issubset(other)
379
+
380
+ def issuperset(self, iterable: Iterable[Any]) -> bool:
381
+ if isinstance(iterable, self.__class__):
382
+ other = iterable
383
+ else:
384
+ other = self.__class__(iterable)
385
+
386
+ if len(self) < len(other):
387
+ return False
388
+
389
+ for m in filterfalse(
390
+ self._members.__contains__, iter(other._members.keys())
391
+ ):
392
+ return False
393
+ return True
394
+
395
+ def __ge__(self, other: Any) -> bool:
396
+ if not isinstance(other, IdentitySet):
397
+ return NotImplemented
398
+ return self.issuperset(other)
399
+
400
+ def __gt__(self, other: Any) -> bool:
401
+ if not isinstance(other, IdentitySet):
402
+ return NotImplemented
403
+ return len(self) > len(other) and self.issuperset(other)
404
+
405
+ def union(self, iterable: Iterable[Any]) -> IdentitySet:
406
+ result = self.__class__()
407
+ members = self._members
408
+ result._members.update(members)
409
+ result._members.update((id(obj), obj) for obj in iterable)
410
+ return result
411
+
412
+ def __or__(self, other: Any) -> IdentitySet:
413
+ if not isinstance(other, IdentitySet):
414
+ return NotImplemented
415
+ return self.union(other)
416
+
417
+ def update(self, iterable: Iterable[Any]) -> None:
418
+ self._members.update((id(obj), obj) for obj in iterable)
419
+
420
+ def __ior__(self, other: Any) -> IdentitySet:
421
+ if not isinstance(other, IdentitySet):
422
+ return NotImplemented
423
+ self.update(other)
424
+ return self
425
+
426
+ def difference(self, iterable: Iterable[Any]) -> IdentitySet:
427
+ result = self.__new__(self.__class__)
428
+ other: Collection[Any]
429
+
430
+ if isinstance(iterable, self.__class__):
431
+ other = iterable._members
432
+ else:
433
+ other = {id(obj) for obj in iterable}
434
+ result._members = {
435
+ k: v for k, v in self._members.items() if k not in other
436
+ }
437
+ return result
438
+
439
+ def __sub__(self, other: IdentitySet) -> IdentitySet:
440
+ if not isinstance(other, IdentitySet):
441
+ return NotImplemented
442
+ return self.difference(other)
443
+
444
+ def difference_update(self, iterable: Iterable[Any]) -> None:
445
+ self._members = self.difference(iterable)._members
446
+
447
+ def __isub__(self, other: IdentitySet) -> IdentitySet:
448
+ if not isinstance(other, IdentitySet):
449
+ return NotImplemented
450
+ self.difference_update(other)
451
+ return self
452
+
453
+ def intersection(self, iterable: Iterable[Any]) -> IdentitySet:
454
+ result = self.__new__(self.__class__)
455
+
456
+ other: Collection[Any]
457
+
458
+ if isinstance(iterable, self.__class__):
459
+ other = iterable._members
460
+ else:
461
+ other = {id(obj) for obj in iterable}
462
+ result._members = {
463
+ k: v for k, v in self._members.items() if k in other
464
+ }
465
+ return result
466
+
467
+ def __and__(self, other: IdentitySet) -> IdentitySet:
468
+ if not isinstance(other, IdentitySet):
469
+ return NotImplemented
470
+ return self.intersection(other)
471
+
472
+ def intersection_update(self, iterable: Iterable[Any]) -> None:
473
+ self._members = self.intersection(iterable)._members
474
+
475
+ def __iand__(self, other: IdentitySet) -> IdentitySet:
476
+ if not isinstance(other, IdentitySet):
477
+ return NotImplemented
478
+ self.intersection_update(other)
479
+ return self
480
+
481
+ def symmetric_difference(self, iterable: Iterable[Any]) -> IdentitySet:
482
+ result = self.__new__(self.__class__)
483
+ if isinstance(iterable, self.__class__):
484
+ other = iterable._members
485
+ else:
486
+ other = {id(obj): obj for obj in iterable}
487
+ result._members = {
488
+ k: v for k, v in self._members.items() if k not in other
489
+ }
490
+ result._members.update(
491
+ (k, v) for k, v in other.items() if k not in self._members
492
+ )
493
+ return result
494
+
495
+ def __xor__(self, other: IdentitySet) -> IdentitySet:
496
+ if not isinstance(other, IdentitySet):
497
+ return NotImplemented
498
+ return self.symmetric_difference(other)
499
+
500
+ def symmetric_difference_update(self, iterable: Iterable[Any]) -> None:
501
+ self._members = self.symmetric_difference(iterable)._members
502
+
503
+ def __ixor__(self, other: IdentitySet) -> IdentitySet:
504
+ if not isinstance(other, IdentitySet):
505
+ return NotImplemented
506
+ self.symmetric_difference(other)
507
+ return self
508
+
509
+ def copy(self) -> IdentitySet:
510
+ result = self.__new__(self.__class__)
511
+ result._members = self._members.copy()
512
+ return result
513
+
514
+ __copy__ = copy
515
+
516
+ def __len__(self) -> int:
517
+ return len(self._members)
518
+
519
+ def __iter__(self) -> Iterator[Any]:
520
+ return iter(self._members.values())
521
+
522
+ def __hash__(self) -> NoReturn:
523
+ raise TypeError("set objects are unhashable")
524
+
525
+ def __repr__(self) -> str:
526
+ return "%s(%r)" % (type(self).__name__, list(self._members.values()))
527
+
528
+
529
+ def unique_list(
530
+ seq: Iterable[_T], hashfunc: Optional[Callable[[_T], int]] = None
531
+ ) -> List[_T]:
532
+ seen: Set[Any] = set()
533
+ seen_add = seen.add
534
+ if not hashfunc:
535
+ return [x for x in seq if x not in seen and not seen_add(x)]
536
+ else:
537
+ return [
538
+ x
539
+ for x in seq
540
+ if hashfunc(x) not in seen and not seen_add(hashfunc(x))
541
+ ]