SQLAlchemy 2.1.0b2__cp313-cp313t-win_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. sqlalchemy/__init__.py +298 -0
  2. sqlalchemy/connectors/__init__.py +18 -0
  3. sqlalchemy/connectors/aioodbc.py +171 -0
  4. sqlalchemy/connectors/asyncio.py +476 -0
  5. sqlalchemy/connectors/pyodbc.py +250 -0
  6. sqlalchemy/dialects/__init__.py +62 -0
  7. sqlalchemy/dialects/_typing.py +30 -0
  8. sqlalchemy/dialects/mssql/__init__.py +89 -0
  9. sqlalchemy/dialects/mssql/aioodbc.py +63 -0
  10. sqlalchemy/dialects/mssql/base.py +4166 -0
  11. sqlalchemy/dialects/mssql/information_schema.py +285 -0
  12. sqlalchemy/dialects/mssql/json.py +140 -0
  13. sqlalchemy/dialects/mssql/mssqlpython.py +220 -0
  14. sqlalchemy/dialects/mssql/provision.py +196 -0
  15. sqlalchemy/dialects/mssql/pymssql.py +126 -0
  16. sqlalchemy/dialects/mssql/pyodbc.py +698 -0
  17. sqlalchemy/dialects/mysql/__init__.py +106 -0
  18. sqlalchemy/dialects/mysql/_mariadb_shim.py +312 -0
  19. sqlalchemy/dialects/mysql/aiomysql.py +226 -0
  20. sqlalchemy/dialects/mysql/asyncmy.py +214 -0
  21. sqlalchemy/dialects/mysql/base.py +3877 -0
  22. sqlalchemy/dialects/mysql/cymysql.py +106 -0
  23. sqlalchemy/dialects/mysql/dml.py +279 -0
  24. sqlalchemy/dialects/mysql/enumerated.py +277 -0
  25. sqlalchemy/dialects/mysql/expression.py +146 -0
  26. sqlalchemy/dialects/mysql/json.py +92 -0
  27. sqlalchemy/dialects/mysql/mariadb.py +67 -0
  28. sqlalchemy/dialects/mysql/mariadbconnector.py +330 -0
  29. sqlalchemy/dialects/mysql/mysqlconnector.py +296 -0
  30. sqlalchemy/dialects/mysql/mysqldb.py +312 -0
  31. sqlalchemy/dialects/mysql/provision.py +153 -0
  32. sqlalchemy/dialects/mysql/pymysql.py +157 -0
  33. sqlalchemy/dialects/mysql/pyodbc.py +156 -0
  34. sqlalchemy/dialects/mysql/reflection.py +724 -0
  35. sqlalchemy/dialects/mysql/reserved_words.py +570 -0
  36. sqlalchemy/dialects/mysql/types.py +845 -0
  37. sqlalchemy/dialects/oracle/__init__.py +85 -0
  38. sqlalchemy/dialects/oracle/base.py +3977 -0
  39. sqlalchemy/dialects/oracle/cx_oracle.py +1601 -0
  40. sqlalchemy/dialects/oracle/dictionary.py +507 -0
  41. sqlalchemy/dialects/oracle/json.py +158 -0
  42. sqlalchemy/dialects/oracle/oracledb.py +909 -0
  43. sqlalchemy/dialects/oracle/provision.py +288 -0
  44. sqlalchemy/dialects/oracle/types.py +367 -0
  45. sqlalchemy/dialects/oracle/vector.py +368 -0
  46. sqlalchemy/dialects/postgresql/__init__.py +171 -0
  47. sqlalchemy/dialects/postgresql/_psycopg_common.py +229 -0
  48. sqlalchemy/dialects/postgresql/array.py +534 -0
  49. sqlalchemy/dialects/postgresql/asyncpg.py +1323 -0
  50. sqlalchemy/dialects/postgresql/base.py +5789 -0
  51. sqlalchemy/dialects/postgresql/bitstring.py +327 -0
  52. sqlalchemy/dialects/postgresql/dml.py +360 -0
  53. sqlalchemy/dialects/postgresql/ext.py +593 -0
  54. sqlalchemy/dialects/postgresql/hstore.py +423 -0
  55. sqlalchemy/dialects/postgresql/json.py +408 -0
  56. sqlalchemy/dialects/postgresql/named_types.py +521 -0
  57. sqlalchemy/dialects/postgresql/operators.py +130 -0
  58. sqlalchemy/dialects/postgresql/pg8000.py +670 -0
  59. sqlalchemy/dialects/postgresql/pg_catalog.py +344 -0
  60. sqlalchemy/dialects/postgresql/provision.py +184 -0
  61. sqlalchemy/dialects/postgresql/psycopg.py +799 -0
  62. sqlalchemy/dialects/postgresql/psycopg2.py +860 -0
  63. sqlalchemy/dialects/postgresql/psycopg2cffi.py +61 -0
  64. sqlalchemy/dialects/postgresql/ranges.py +1002 -0
  65. sqlalchemy/dialects/postgresql/types.py +388 -0
  66. sqlalchemy/dialects/sqlite/__init__.py +57 -0
  67. sqlalchemy/dialects/sqlite/aiosqlite.py +321 -0
  68. sqlalchemy/dialects/sqlite/base.py +3063 -0
  69. sqlalchemy/dialects/sqlite/dml.py +279 -0
  70. sqlalchemy/dialects/sqlite/json.py +100 -0
  71. sqlalchemy/dialects/sqlite/provision.py +229 -0
  72. sqlalchemy/dialects/sqlite/pysqlcipher.py +161 -0
  73. sqlalchemy/dialects/sqlite/pysqlite.py +754 -0
  74. sqlalchemy/dialects/type_migration_guidelines.txt +145 -0
  75. sqlalchemy/engine/__init__.py +62 -0
  76. sqlalchemy/engine/_processors_cy.cp313t-win_arm64.pyd +0 -0
  77. sqlalchemy/engine/_processors_cy.py +92 -0
  78. sqlalchemy/engine/_result_cy.cp313t-win_arm64.pyd +0 -0
  79. sqlalchemy/engine/_result_cy.py +633 -0
  80. sqlalchemy/engine/_row_cy.cp313t-win_arm64.pyd +0 -0
  81. sqlalchemy/engine/_row_cy.py +232 -0
  82. sqlalchemy/engine/_util_cy.cp313t-win_arm64.pyd +0 -0
  83. sqlalchemy/engine/_util_cy.py +136 -0
  84. sqlalchemy/engine/base.py +3354 -0
  85. sqlalchemy/engine/characteristics.py +155 -0
  86. sqlalchemy/engine/create.py +877 -0
  87. sqlalchemy/engine/cursor.py +2421 -0
  88. sqlalchemy/engine/default.py +2402 -0
  89. sqlalchemy/engine/events.py +965 -0
  90. sqlalchemy/engine/interfaces.py +3495 -0
  91. sqlalchemy/engine/mock.py +134 -0
  92. sqlalchemy/engine/processors.py +82 -0
  93. sqlalchemy/engine/reflection.py +2100 -0
  94. sqlalchemy/engine/result.py +1966 -0
  95. sqlalchemy/engine/row.py +397 -0
  96. sqlalchemy/engine/strategies.py +16 -0
  97. sqlalchemy/engine/url.py +922 -0
  98. sqlalchemy/engine/util.py +156 -0
  99. sqlalchemy/event/__init__.py +26 -0
  100. sqlalchemy/event/api.py +220 -0
  101. sqlalchemy/event/attr.py +674 -0
  102. sqlalchemy/event/base.py +472 -0
  103. sqlalchemy/event/legacy.py +258 -0
  104. sqlalchemy/event/registry.py +390 -0
  105. sqlalchemy/events.py +17 -0
  106. sqlalchemy/exc.py +922 -0
  107. sqlalchemy/ext/__init__.py +11 -0
  108. sqlalchemy/ext/associationproxy.py +2072 -0
  109. sqlalchemy/ext/asyncio/__init__.py +29 -0
  110. sqlalchemy/ext/asyncio/base.py +281 -0
  111. sqlalchemy/ext/asyncio/engine.py +1487 -0
  112. sqlalchemy/ext/asyncio/exc.py +21 -0
  113. sqlalchemy/ext/asyncio/result.py +994 -0
  114. sqlalchemy/ext/asyncio/scoping.py +1679 -0
  115. sqlalchemy/ext/asyncio/session.py +2007 -0
  116. sqlalchemy/ext/automap.py +1701 -0
  117. sqlalchemy/ext/baked.py +559 -0
  118. sqlalchemy/ext/compiler.py +600 -0
  119. sqlalchemy/ext/declarative/__init__.py +65 -0
  120. sqlalchemy/ext/declarative/extensions.py +560 -0
  121. sqlalchemy/ext/horizontal_shard.py +481 -0
  122. sqlalchemy/ext/hybrid.py +1877 -0
  123. sqlalchemy/ext/indexable.py +364 -0
  124. sqlalchemy/ext/instrumentation.py +450 -0
  125. sqlalchemy/ext/mutable.py +1081 -0
  126. sqlalchemy/ext/orderinglist.py +439 -0
  127. sqlalchemy/ext/serializer.py +185 -0
  128. sqlalchemy/future/__init__.py +16 -0
  129. sqlalchemy/future/engine.py +15 -0
  130. sqlalchemy/inspection.py +174 -0
  131. sqlalchemy/log.py +283 -0
  132. sqlalchemy/orm/__init__.py +176 -0
  133. sqlalchemy/orm/_orm_constructors.py +2694 -0
  134. sqlalchemy/orm/_typing.py +179 -0
  135. sqlalchemy/orm/attributes.py +2868 -0
  136. sqlalchemy/orm/base.py +976 -0
  137. sqlalchemy/orm/bulk_persistence.py +2152 -0
  138. sqlalchemy/orm/clsregistry.py +582 -0
  139. sqlalchemy/orm/collections.py +1568 -0
  140. sqlalchemy/orm/context.py +3471 -0
  141. sqlalchemy/orm/decl_api.py +2280 -0
  142. sqlalchemy/orm/decl_base.py +2309 -0
  143. sqlalchemy/orm/dependency.py +1306 -0
  144. sqlalchemy/orm/descriptor_props.py +1183 -0
  145. sqlalchemy/orm/dynamic.py +307 -0
  146. sqlalchemy/orm/evaluator.py +379 -0
  147. sqlalchemy/orm/events.py +3386 -0
  148. sqlalchemy/orm/exc.py +237 -0
  149. sqlalchemy/orm/identity.py +302 -0
  150. sqlalchemy/orm/instrumentation.py +746 -0
  151. sqlalchemy/orm/interfaces.py +1589 -0
  152. sqlalchemy/orm/loading.py +1684 -0
  153. sqlalchemy/orm/mapped_collection.py +557 -0
  154. sqlalchemy/orm/mapper.py +4411 -0
  155. sqlalchemy/orm/path_registry.py +829 -0
  156. sqlalchemy/orm/persistence.py +1789 -0
  157. sqlalchemy/orm/properties.py +973 -0
  158. sqlalchemy/orm/query.py +3528 -0
  159. sqlalchemy/orm/relationships.py +3570 -0
  160. sqlalchemy/orm/scoping.py +2232 -0
  161. sqlalchemy/orm/session.py +5403 -0
  162. sqlalchemy/orm/state.py +1175 -0
  163. sqlalchemy/orm/state_changes.py +196 -0
  164. sqlalchemy/orm/strategies.py +3492 -0
  165. sqlalchemy/orm/strategy_options.py +2562 -0
  166. sqlalchemy/orm/sync.py +164 -0
  167. sqlalchemy/orm/unitofwork.py +798 -0
  168. sqlalchemy/orm/util.py +2438 -0
  169. sqlalchemy/orm/writeonly.py +694 -0
  170. sqlalchemy/pool/__init__.py +41 -0
  171. sqlalchemy/pool/base.py +1522 -0
  172. sqlalchemy/pool/events.py +375 -0
  173. sqlalchemy/pool/impl.py +582 -0
  174. sqlalchemy/py.typed +0 -0
  175. sqlalchemy/schema.py +74 -0
  176. sqlalchemy/sql/__init__.py +156 -0
  177. sqlalchemy/sql/_annotated_cols.py +397 -0
  178. sqlalchemy/sql/_dml_constructors.py +132 -0
  179. sqlalchemy/sql/_elements_constructors.py +2164 -0
  180. sqlalchemy/sql/_orm_types.py +20 -0
  181. sqlalchemy/sql/_selectable_constructors.py +840 -0
  182. sqlalchemy/sql/_typing.py +487 -0
  183. sqlalchemy/sql/_util_cy.cp313t-win_arm64.pyd +0 -0
  184. sqlalchemy/sql/_util_cy.py +127 -0
  185. sqlalchemy/sql/annotation.py +590 -0
  186. sqlalchemy/sql/base.py +2699 -0
  187. sqlalchemy/sql/cache_key.py +1066 -0
  188. sqlalchemy/sql/coercions.py +1373 -0
  189. sqlalchemy/sql/compiler.py +8327 -0
  190. sqlalchemy/sql/crud.py +1815 -0
  191. sqlalchemy/sql/ddl.py +1928 -0
  192. sqlalchemy/sql/default_comparator.py +654 -0
  193. sqlalchemy/sql/dml.py +1977 -0
  194. sqlalchemy/sql/elements.py +6033 -0
  195. sqlalchemy/sql/events.py +458 -0
  196. sqlalchemy/sql/expression.py +172 -0
  197. sqlalchemy/sql/functions.py +2305 -0
  198. sqlalchemy/sql/lambdas.py +1443 -0
  199. sqlalchemy/sql/naming.py +209 -0
  200. sqlalchemy/sql/operators.py +2897 -0
  201. sqlalchemy/sql/roles.py +332 -0
  202. sqlalchemy/sql/schema.py +6703 -0
  203. sqlalchemy/sql/selectable.py +7553 -0
  204. sqlalchemy/sql/sqltypes.py +4093 -0
  205. sqlalchemy/sql/traversals.py +1042 -0
  206. sqlalchemy/sql/type_api.py +2446 -0
  207. sqlalchemy/sql/util.py +1495 -0
  208. sqlalchemy/sql/visitors.py +1157 -0
  209. sqlalchemy/testing/__init__.py +96 -0
  210. sqlalchemy/testing/assertions.py +1007 -0
  211. sqlalchemy/testing/assertsql.py +519 -0
  212. sqlalchemy/testing/asyncio.py +128 -0
  213. sqlalchemy/testing/config.py +440 -0
  214. sqlalchemy/testing/engines.py +483 -0
  215. sqlalchemy/testing/entities.py +117 -0
  216. sqlalchemy/testing/exclusions.py +476 -0
  217. sqlalchemy/testing/fixtures/__init__.py +30 -0
  218. sqlalchemy/testing/fixtures/base.py +384 -0
  219. sqlalchemy/testing/fixtures/mypy.py +247 -0
  220. sqlalchemy/testing/fixtures/orm.py +227 -0
  221. sqlalchemy/testing/fixtures/sql.py +538 -0
  222. sqlalchemy/testing/pickleable.py +155 -0
  223. sqlalchemy/testing/plugin/__init__.py +6 -0
  224. sqlalchemy/testing/plugin/bootstrap.py +51 -0
  225. sqlalchemy/testing/plugin/plugin_base.py +828 -0
  226. sqlalchemy/testing/plugin/pytestplugin.py +892 -0
  227. sqlalchemy/testing/profiling.py +329 -0
  228. sqlalchemy/testing/provision.py +613 -0
  229. sqlalchemy/testing/requirements.py +1978 -0
  230. sqlalchemy/testing/schema.py +198 -0
  231. sqlalchemy/testing/suite/__init__.py +19 -0
  232. sqlalchemy/testing/suite/test_cte.py +237 -0
  233. sqlalchemy/testing/suite/test_ddl.py +420 -0
  234. sqlalchemy/testing/suite/test_dialect.py +776 -0
  235. sqlalchemy/testing/suite/test_insert.py +630 -0
  236. sqlalchemy/testing/suite/test_reflection.py +3557 -0
  237. sqlalchemy/testing/suite/test_results.py +660 -0
  238. sqlalchemy/testing/suite/test_rowcount.py +258 -0
  239. sqlalchemy/testing/suite/test_select.py +2112 -0
  240. sqlalchemy/testing/suite/test_sequence.py +317 -0
  241. sqlalchemy/testing/suite/test_table_via_select.py +686 -0
  242. sqlalchemy/testing/suite/test_types.py +2271 -0
  243. sqlalchemy/testing/suite/test_unicode_ddl.py +189 -0
  244. sqlalchemy/testing/suite/test_update_delete.py +139 -0
  245. sqlalchemy/testing/util.py +535 -0
  246. sqlalchemy/testing/warnings.py +52 -0
  247. sqlalchemy/types.py +76 -0
  248. sqlalchemy/util/__init__.py +158 -0
  249. sqlalchemy/util/_collections.py +688 -0
  250. sqlalchemy/util/_collections_cy.cp313t-win_arm64.pyd +0 -0
  251. sqlalchemy/util/_collections_cy.pxd +8 -0
  252. sqlalchemy/util/_collections_cy.py +516 -0
  253. sqlalchemy/util/_has_cython.py +46 -0
  254. sqlalchemy/util/_immutabledict_cy.cp313t-win_arm64.pyd +0 -0
  255. sqlalchemy/util/_immutabledict_cy.py +240 -0
  256. sqlalchemy/util/compat.py +299 -0
  257. sqlalchemy/util/concurrency.py +322 -0
  258. sqlalchemy/util/cython.py +79 -0
  259. sqlalchemy/util/deprecations.py +401 -0
  260. sqlalchemy/util/langhelpers.py +2320 -0
  261. sqlalchemy/util/preloaded.py +152 -0
  262. sqlalchemy/util/queue.py +304 -0
  263. sqlalchemy/util/tool_support.py +201 -0
  264. sqlalchemy/util/topological.py +120 -0
  265. sqlalchemy/util/typing.py +711 -0
  266. sqlalchemy-2.1.0b2.dist-info/METADATA +269 -0
  267. sqlalchemy-2.1.0b2.dist-info/RECORD +270 -0
  268. sqlalchemy-2.1.0b2.dist-info/WHEEL +5 -0
  269. sqlalchemy-2.1.0b2.dist-info/licenses/LICENSE +19 -0
  270. sqlalchemy-2.1.0b2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,516 @@
1
+ # util/_collections_cy.py
2
+ # Copyright (C) 2010-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: disable-error-code="misc, no-any-return, no-untyped-def, override"
8
+ # mypy: disable-error-code="untyped-decorator"
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import AbstractSet
13
+ from typing import Any
14
+ from typing import Dict
15
+ from typing import Hashable
16
+ from typing import Iterable
17
+ from typing import Iterator
18
+ from typing import List
19
+ from typing import NoReturn
20
+ from typing import Optional
21
+ from typing import Set
22
+ from typing import Tuple
23
+ from typing import TypeVar
24
+ from typing import Union
25
+
26
+ from .typing import Self
27
+
28
+ # START GENERATED CYTHON IMPORT
29
+ # This section is automatically generated by the script tools/cython_imports.py
30
+ try:
31
+ # NOTE: the cython compiler needs this "import cython" in the file, it
32
+ # can't be only "from sqlalchemy.util import cython" with the fallback
33
+ # in that module
34
+ import cython
35
+ except ModuleNotFoundError:
36
+ from sqlalchemy.util import cython
37
+
38
+
39
+ def _is_compiled() -> bool:
40
+ """Utility function to indicate if this module is compiled or not."""
41
+ return cython.compiled # type: ignore[no-any-return,unused-ignore]
42
+
43
+
44
+ # END GENERATED CYTHON IMPORT
45
+ _T = TypeVar("_T")
46
+ _S = TypeVar("_S")
47
+
48
+
49
+ @cython.ccall
50
+ def unique_list(seq: Iterable[_T]) -> List[_T]:
51
+ # this version seems somewhat faster for smaller sizes, but it's
52
+ # significantly slower on larger sizes
53
+ # w = {x:None for x in seq}
54
+ # return PyDict_Keys(w) if cython.compiled else list(w)
55
+ if cython.compiled:
56
+ seen: Set[_T] = set()
57
+ return [x for x in seq if x not in seen and not set.add(seen, x)]
58
+ else:
59
+ return list(dict.fromkeys(seq))
60
+
61
+ # In case passing an hashfunc is required in the future two version were
62
+ # tested:
63
+ # - this version is faster but returns the *last* element matching the
64
+ # hash.
65
+ # from cython.cimports.cpython.dict import PyDict_Values
66
+ # w: dict = {hashfunc(x): x for x in seq}
67
+ # return PyDict_Values(w) if cython.compiled else list(w.values())
68
+ # - this version is slower but returns the *first* element matching the
69
+ # hash.
70
+ # seen: set = set()
71
+ # res: list = []
72
+ # for x in seq:
73
+ # h = hashfunc(x)
74
+ # if h not in seen:
75
+ # res.append(x)
76
+ # seen.add(h)
77
+ # return res
78
+
79
+
80
+ @cython.cclass
81
+ class OrderedSet(Set[_T]):
82
+ """A set implementation that maintains insertion order."""
83
+
84
+ __slots__ = ("_list",)
85
+ _list: List[_T]
86
+
87
+ @classmethod
88
+ def __class_getitem__(cls, key: Any) -> type[Self]:
89
+ return cls
90
+
91
+ def __init__(self, d: Optional[Iterable[_T]] = None) -> None:
92
+ if d is not None:
93
+ if isinstance(d, set) or isinstance(d, dict):
94
+ self._list = list(d)
95
+ else:
96
+ self._list = unique_list(d)
97
+ set.__init__(self, self._list)
98
+ else:
99
+ self._list = []
100
+ set.__init__(self)
101
+
102
+ def copy(self) -> OrderedSet[_T]:
103
+ return self._from_list(list(self._list))
104
+
105
+ @cython.final
106
+ @cython.cfunc
107
+ @cython.inline
108
+ def _from_list(self, new_list: List[_T]) -> OrderedSet: # type: ignore[type-arg] # noqa: E501
109
+ new: OrderedSet = OrderedSet.__new__(OrderedSet) # type: ignore[type-arg] # noqa: E501
110
+ new._list = new_list
111
+ set.update(new, new_list)
112
+ return new
113
+
114
+ def add(self, element: _T, /) -> None:
115
+ if element not in self:
116
+ self._list.append(element)
117
+ set.add(self, element)
118
+
119
+ def remove(self, element: _T, /) -> None:
120
+ # set.remove will raise if element is not in self
121
+ set.remove(self, element)
122
+ self._list.remove(element)
123
+
124
+ def pop(self) -> _T:
125
+ try:
126
+ value = self._list.pop()
127
+ except IndexError:
128
+ raise KeyError("pop from an empty set") from None
129
+ set.remove(self, value)
130
+ return value
131
+
132
+ def insert(self, pos: cython.Py_ssize_t, element: _T, /) -> None:
133
+ if element not in self:
134
+ self._list.insert(pos, element)
135
+ set.add(self, element)
136
+
137
+ def discard(self, element: _T, /) -> None:
138
+ if element in self:
139
+ set.remove(self, element)
140
+ self._list.remove(element)
141
+
142
+ def clear(self) -> None:
143
+ set.clear(self)
144
+ self._list = []
145
+
146
+ def __getitem__(self, key: cython.Py_ssize_t) -> _T:
147
+ return self._list[key]
148
+
149
+ def __iter__(self) -> Iterator[_T]:
150
+ return iter(self._list)
151
+
152
+ def __add__(self, other: Iterator[_T]) -> OrderedSet[_T]:
153
+ return self.union(other)
154
+
155
+ def __repr__(self) -> str:
156
+ return "%s(%r)" % (self.__class__.__name__, self._list)
157
+
158
+ __str__ = __repr__
159
+
160
+ # @cython.ccall # cdef function cannot have star argument
161
+ def update(self, *iterables: Iterable[_T]) -> None:
162
+ for iterable in iterables:
163
+ for element in iterable:
164
+ # inline of add. mainly for python, since for cython we
165
+ # could create an @cfunc @inline _add function that would
166
+ # perform the same
167
+ if element not in self:
168
+ self._list.append(element)
169
+ set.add(self, element)
170
+
171
+ def __ior__(
172
+ self: OrderedSet[Union[_T, _S]], iterable: AbstractSet[_S]
173
+ ) -> OrderedSet[Union[_T, _S]]:
174
+ self.update(iterable)
175
+ return self
176
+
177
+ # @cython.ccall # cdef function cannot have star argument
178
+ def union(self, *other: Iterable[_S]) -> OrderedSet[Union[_T, _S]]:
179
+ result: OrderedSet[Union[_T, _S]] = self._from_list(list(self._list))
180
+ result.update(*other)
181
+ return result
182
+
183
+ def __or__(self, other: AbstractSet[_S]) -> OrderedSet[Union[_T, _S]]:
184
+ return self.union(other)
185
+
186
+ # @cython.ccall # cdef function cannot have star argument
187
+ def intersection(self, *other: Iterable[Hashable]) -> OrderedSet[_T]:
188
+ other_set: Set[Any] = set.intersection(self, *other)
189
+ return self._from_list([a for a in self._list if a in other_set])
190
+
191
+ def __and__(self, other: AbstractSet[Hashable]) -> OrderedSet[_T]:
192
+ return self.intersection(other)
193
+
194
+ @cython.ccall
195
+ @cython.annotation_typing(False) # avoid cython crash from generic return
196
+ def symmetric_difference(
197
+ self, other: Iterable[_S], /
198
+ ) -> OrderedSet[Union[_T, _S]]:
199
+ collection: Iterable[Any]
200
+ other_set: Set[_S]
201
+ if isinstance(other, set):
202
+ other_set = cython.cast(set, other)
203
+ collection = other_set
204
+ elif hasattr(other, "__len__"):
205
+ collection = other
206
+ other_set = set(other)
207
+ else:
208
+ collection = list(other)
209
+ other_set = set(collection)
210
+ result: OrderedSet[Union[_T, _S]] = self._from_list(
211
+ [a for a in self._list if a not in other_set]
212
+ )
213
+ result.update([a for a in collection if a not in self])
214
+ return result
215
+
216
+ def __xor__(self, other: AbstractSet[_S]) -> OrderedSet[Union[_T, _S]]:
217
+ return self.symmetric_difference(other)
218
+
219
+ # @cython.ccall # cdef function cannot have star argument
220
+ def difference(self, *other: Iterable[Hashable]) -> OrderedSet[_T]:
221
+ other_set: Set[Any] = set.difference(self, *other)
222
+ return self._from_list([a for a in self._list if a in other_set])
223
+
224
+ def __sub__(self, other: AbstractSet[Hashable]) -> OrderedSet[_T]:
225
+ return self.difference(other)
226
+
227
+ # @cython.ccall # cdef function cannot have star argument
228
+ def intersection_update(self, *other: Iterable[Hashable]) -> None:
229
+ set.intersection_update(self, *other)
230
+ self._list = [a for a in self._list if a in self]
231
+
232
+ def __iand__(self, other: AbstractSet[Hashable]) -> OrderedSet[_T]:
233
+ self.intersection_update(other)
234
+ return self
235
+
236
+ @cython.ccall
237
+ @cython.annotation_typing(False) # avoid cython crash from generic return
238
+ def symmetric_difference_update(self, other: Iterable[_T], /) -> None:
239
+ collection = other if hasattr(other, "__len__") else list(other)
240
+ set.symmetric_difference_update(self, collection)
241
+ self._list = [a for a in self._list if a in self]
242
+ self._list += [a for a in collection if a in self]
243
+
244
+ def __ixor__(
245
+ self: OrderedSet[Union[_T, _S]], other: AbstractSet[_S]
246
+ ) -> OrderedSet[Union[_T, _S]]:
247
+ self.symmetric_difference_update(other)
248
+ return self
249
+
250
+ # @cython.ccall # cdef function cannot have star argument
251
+ def difference_update(self, *other: Iterable[Hashable]) -> None:
252
+ set.difference_update(self, *other)
253
+ self._list = [a for a in self._list if a in self]
254
+
255
+ def __isub__(self, other: AbstractSet[Hashable]) -> OrderedSet[_T]:
256
+ self.difference_update(other)
257
+ return self
258
+
259
+
260
+ if cython.compiled:
261
+
262
+ @cython.cfunc
263
+ @cython.inline
264
+ def _get_id(item: object, /) -> cython.ulonglong:
265
+ return cython.cast(
266
+ cython.ulonglong,
267
+ cython.cast(cython.pointer(cython.void), item),
268
+ )
269
+
270
+ else:
271
+ _get_id = id
272
+
273
+
274
+ @cython.cclass
275
+ class IdentitySet:
276
+ """A set that considers only object id() for uniqueness.
277
+
278
+ This strategy has edge cases for builtin types- it's possible to have
279
+ two 'foo' strings in one of these sets, for example. Use sparingly.
280
+
281
+ """
282
+
283
+ __slots__ = ("_members",)
284
+ _members: Dict[int, Any]
285
+
286
+ def __init__(self, iterable: Optional[Iterable[Any]] = None):
287
+ # the code assumes this class is ordered
288
+ self._members = {}
289
+ if iterable:
290
+ self.update(iterable)
291
+
292
+ def add(self, value: Any, /) -> None:
293
+ self._members[_get_id(value)] = value
294
+
295
+ def __contains__(self, value) -> bool:
296
+ return _get_id(value) in self._members
297
+
298
+ @cython.ccall
299
+ def remove(self, value: Any, /):
300
+ del self._members[_get_id(value)]
301
+
302
+ def discard(self, value, /) -> None:
303
+ try:
304
+ self.remove(value)
305
+ except KeyError:
306
+ pass
307
+
308
+ def pop(self) -> Any:
309
+ pair: Tuple[Any, Any]
310
+ try:
311
+ pair = self._members.popitem()
312
+ return pair[1]
313
+ except KeyError:
314
+ raise KeyError("pop from an empty set")
315
+
316
+ def clear(self) -> None:
317
+ self._members.clear()
318
+
319
+ def __eq__(self, other: Any) -> bool:
320
+ other_: IdentitySet
321
+ if isinstance(other, IdentitySet):
322
+ other_ = other
323
+ return self._members == other_._members
324
+ else:
325
+ return False
326
+
327
+ def __ne__(self, other: Any) -> bool:
328
+ other_: IdentitySet
329
+ if isinstance(other, IdentitySet):
330
+ other_ = other
331
+ return self._members != other_._members
332
+ else:
333
+ return True
334
+
335
+ @cython.ccall
336
+ def issubset(self, iterable: Iterable[Any], /) -> cython.bint:
337
+ other: IdentitySet
338
+ if isinstance(iterable, IdentitySet):
339
+ other = iterable
340
+ else:
341
+ other = self.__class__(iterable)
342
+
343
+ return self._members.keys() <= other._members.keys()
344
+
345
+ def __le__(self, other: Any) -> bool:
346
+ if not isinstance(other, IdentitySet):
347
+ return NotImplemented
348
+ return self.issubset(other)
349
+
350
+ def __lt__(self, other: Any) -> bool:
351
+ if not isinstance(other, IdentitySet):
352
+ return NotImplemented
353
+ return len(self) < len(other) and self.issubset(other)
354
+
355
+ @cython.ccall
356
+ def issuperset(self, iterable: Iterable[Any], /) -> cython.bint:
357
+ other: IdentitySet
358
+ if isinstance(iterable, IdentitySet):
359
+ other = iterable
360
+ else:
361
+ other = self.__class__(iterable)
362
+
363
+ return self._members.keys() >= other._members.keys()
364
+
365
+ def __ge__(self, other: Any) -> bool:
366
+ if not isinstance(other, IdentitySet):
367
+ return NotImplemented
368
+ return self.issuperset(other)
369
+
370
+ def __gt__(self, other: Any) -> bool:
371
+ if not isinstance(other, IdentitySet):
372
+ return NotImplemented
373
+ return len(self) > len(other) and self.issuperset(other)
374
+
375
+ @cython.ccall
376
+ def union(self, iterable: Iterable[Any], /) -> IdentitySet:
377
+ result: IdentitySet = self.__class__()
378
+ result._members.update(self._members)
379
+ result.update(iterable)
380
+ return result
381
+
382
+ def __or__(self, other: Any) -> IdentitySet:
383
+ if not isinstance(other, IdentitySet):
384
+ return NotImplemented
385
+ return self.union(other)
386
+
387
+ @cython.ccall
388
+ def update(self, iterable: Iterable[Any], /):
389
+ members: Dict[int, Any] = self._members
390
+ if isinstance(iterable, IdentitySet):
391
+ members.update(cython.cast(IdentitySet, iterable)._members)
392
+ else:
393
+ for obj in iterable:
394
+ members[_get_id(obj)] = obj
395
+
396
+ def __ior__(self, other: Any) -> IdentitySet:
397
+ if not isinstance(other, IdentitySet):
398
+ return NotImplemented
399
+ self.update(other)
400
+ return self
401
+
402
+ @cython.ccall
403
+ def difference(self, iterable: Iterable[Any], /) -> IdentitySet:
404
+ result: IdentitySet = self.__new__(self.__class__)
405
+ if isinstance(iterable, IdentitySet):
406
+ other = cython.cast(IdentitySet, iterable)._members.keys()
407
+ else:
408
+ other = {_get_id(obj) for obj in iterable}
409
+
410
+ result._members = {
411
+ k: v for k, v in self._members.items() if k not in other
412
+ }
413
+ return result
414
+
415
+ def __sub__(self, other: IdentitySet) -> IdentitySet:
416
+ if not isinstance(other, IdentitySet):
417
+ return NotImplemented
418
+ return self.difference(other)
419
+
420
+ # def difference_update(self, iterable: Iterable[Any]) -> None:
421
+ @cython.ccall
422
+ def difference_update(self, iterable: Iterable[Any], /):
423
+ other: IdentitySet = self.difference(iterable)
424
+ self._members = other._members
425
+
426
+ def __isub__(self, other: IdentitySet) -> IdentitySet:
427
+ if not isinstance(other, IdentitySet):
428
+ return NotImplemented
429
+ self.difference_update(other)
430
+ return self
431
+
432
+ @cython.ccall
433
+ def intersection(self, iterable: Iterable[Any], /) -> IdentitySet:
434
+ result: IdentitySet = self.__new__(self.__class__)
435
+ if isinstance(iterable, IdentitySet):
436
+ other = cython.cast(IdentitySet, iterable)._members
437
+ else:
438
+ other = {_get_id(obj) for obj in iterable}
439
+ result._members = {
440
+ k: v for k, v in self._members.items() if k in other
441
+ }
442
+ return result
443
+
444
+ def __and__(self, other):
445
+ if not isinstance(other, IdentitySet):
446
+ return NotImplemented
447
+ return self.intersection(other)
448
+
449
+ # def intersection_update(self, iterable: Iterable[Any]) -> None:
450
+ @cython.ccall
451
+ def intersection_update(self, iterable: Iterable[Any], /):
452
+ other: IdentitySet = self.intersection(iterable)
453
+ self._members = other._members
454
+
455
+ def __iand__(self, other: IdentitySet) -> IdentitySet:
456
+ if not isinstance(other, IdentitySet):
457
+ return NotImplemented
458
+ self.intersection_update(other)
459
+ return self
460
+
461
+ @cython.ccall
462
+ def symmetric_difference(self, iterable: Iterable[Any], /) -> IdentitySet:
463
+ result: IdentitySet = self.__new__(self.__class__)
464
+ other: Dict[int, Any]
465
+ if isinstance(iterable, IdentitySet):
466
+ other = cython.cast(IdentitySet, iterable)._members
467
+ else:
468
+ other = {_get_id(obj): obj for obj in iterable}
469
+ result._members = {
470
+ k: v for k, v in self._members.items() if k not in other
471
+ }
472
+ result._members.update(
473
+ [(k, v) for k, v in other.items() if k not in self._members]
474
+ )
475
+ return result
476
+
477
+ def __xor__(self, other: IdentitySet) -> IdentitySet:
478
+ if not isinstance(other, IdentitySet):
479
+ return NotImplemented
480
+ return self.symmetric_difference(other)
481
+
482
+ # def symmetric_difference_update(self, iterable: Iterable[Any]) -> None:
483
+ @cython.ccall
484
+ def symmetric_difference_update(self, iterable: Iterable[Any], /):
485
+ other: IdentitySet = self.symmetric_difference(iterable)
486
+ self._members = other._members
487
+
488
+ def __ixor__(self, other: IdentitySet) -> IdentitySet:
489
+ if not isinstance(other, IdentitySet):
490
+ return NotImplemented
491
+ self.symmetric_difference(other)
492
+ return self
493
+
494
+ @cython.ccall
495
+ def copy(self) -> IdentitySet:
496
+ cp: IdentitySet = self.__new__(self.__class__)
497
+ cp._members = self._members.copy()
498
+ return cp
499
+
500
+ def __copy__(self) -> IdentitySet:
501
+ return self.copy()
502
+
503
+ def __len__(self) -> int:
504
+ return len(self._members)
505
+
506
+ def __iter__(self) -> Iterator[Any]:
507
+ return iter(self._members.values())
508
+
509
+ def __hash__(self) -> NoReturn:
510
+ raise TypeError("set objects are unhashable")
511
+
512
+ def __repr__(self) -> str:
513
+ return "%s(%r)" % (
514
+ self.__class__.__name__,
515
+ list(self._members.values()),
516
+ )
@@ -0,0 +1,46 @@
1
+ # util/_has_cython.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: ignore-errors
8
+
9
+ import typing
10
+
11
+
12
+ def _all_cython_modules():
13
+ """Returns all modules that can be compiled using cython.
14
+ Call ``_is_compiled()`` to check if the module is compiled or not.
15
+ """
16
+ from . import _collections_cy
17
+ from . import _immutabledict_cy
18
+ from ..engine import _processors_cy
19
+ from ..engine import _result_cy
20
+ from ..engine import _row_cy
21
+ from ..engine import _util_cy as engine_util
22
+ from ..sql import _util_cy as sql_util
23
+
24
+ return (
25
+ _collections_cy,
26
+ _immutabledict_cy,
27
+ _processors_cy,
28
+ _result_cy,
29
+ _row_cy,
30
+ engine_util,
31
+ sql_util,
32
+ )
33
+
34
+
35
+ _CYEXTENSION_MSG: str
36
+ if not typing.TYPE_CHECKING:
37
+ HAS_CYEXTENSION = all(m._is_compiled() for m in _all_cython_modules())
38
+ if HAS_CYEXTENSION:
39
+ _CYEXTENSION_MSG = "Loaded"
40
+ else:
41
+ _CYEXTENSION_MSG = ", ".join(
42
+ m.__name__ for m in _all_cython_modules() if not m._is_compiled()
43
+ )
44
+ _CYEXTENSION_MSG = f"Modules {_CYEXTENSION_MSG} are not compiled"
45
+ else:
46
+ HAS_CYEXTENSION = False