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,240 @@
1
+ # util/_immutabledict_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, arg-type, type-arg, untyped-decorator"
8
+ from __future__ import annotations
9
+
10
+ from typing import Any
11
+ from typing import Dict
12
+ from typing import Hashable
13
+ from typing import Literal
14
+ from typing import Mapping
15
+ from typing import NoReturn
16
+ from typing import Optional
17
+ from typing import TypeVar
18
+
19
+ from .typing import Self
20
+
21
+ # START GENERATED CYTHON IMPORT
22
+ # This section is automatically generated by the script tools/cython_imports.py
23
+ try:
24
+ # NOTE: the cython compiler needs this "import cython" in the file, it
25
+ # can't be only "from sqlalchemy.util import cython" with the fallback
26
+ # in that module
27
+ import cython
28
+ except ModuleNotFoundError:
29
+ from sqlalchemy.util import cython
30
+
31
+
32
+ def _is_compiled() -> bool:
33
+ """Utility function to indicate if this module is compiled or not."""
34
+ return cython.compiled # type: ignore[no-any-return,unused-ignore]
35
+
36
+
37
+ # END GENERATED CYTHON IMPORT
38
+
39
+ if cython.compiled:
40
+ from cython.cimports.cpython.dict import PyDict_Update
41
+ else:
42
+ PyDict_Update = dict.update
43
+
44
+
45
+ def _immutable_fn(obj: object) -> NoReturn:
46
+ raise TypeError(f"{obj.__class__.__name__} object is immutable")
47
+
48
+
49
+ class ReadOnlyContainer:
50
+ __slots__ = ()
51
+
52
+ def _readonly(self) -> NoReturn:
53
+ raise TypeError(
54
+ f"{self.__class__.__name__} object is immutable and/or readonly"
55
+ )
56
+
57
+ def __delitem__(self, key: Any) -> NoReturn:
58
+ self._readonly()
59
+
60
+ def __setitem__(self, key: Any, value: Any) -> NoReturn:
61
+ self._readonly()
62
+
63
+ def __setattr__(self, key: Any, value: Any) -> NoReturn:
64
+ self._readonly()
65
+
66
+
67
+ _KT = TypeVar("_KT", bound=Hashable)
68
+ _VT = TypeVar("_VT", bound=Any)
69
+
70
+
71
+ @cython.cclass
72
+ class ImmutableDictBase(Dict[_KT, _VT]):
73
+ # NOTE: this method is required in 3.9 and speeds up the use case
74
+ # ImmutableDictBase[str,int](a_dict) significantly
75
+ @classmethod
76
+ def __class_getitem__( # type: ignore[override]
77
+ cls, key: Any
78
+ ) -> type[Self]:
79
+ return cls
80
+
81
+ def __delitem__(self, key: Any) -> NoReturn:
82
+ _immutable_fn(self)
83
+
84
+ def __setitem__(self, key: Any, value: Any) -> NoReturn:
85
+ _immutable_fn(self)
86
+
87
+ def __setattr__(self, key: Any, value: Any) -> NoReturn:
88
+ _immutable_fn(self)
89
+
90
+ def clear(self) -> NoReturn:
91
+ _immutable_fn(self)
92
+
93
+ def pop(self, key: Any, default: Optional[Any] = None) -> NoReturn:
94
+ _immutable_fn(self)
95
+
96
+ def popitem(self) -> NoReturn:
97
+ _immutable_fn(self)
98
+
99
+ def setdefault(self, key: Any, default: Optional[Any] = None) -> NoReturn:
100
+ _immutable_fn(self)
101
+
102
+ def update(self, *arg: Any, **kw: Any) -> NoReturn:
103
+ _immutable_fn(self)
104
+
105
+
106
+ # NOTE: can't extend from ImmutableDictBase[_KT, _VT] due to a compiler
107
+ # crash in doing so. Extending from ImmutableDictBase is ok, but requires
108
+ # a type checking section and other workaround for the crash
109
+ @cython.cclass
110
+ class immutabledict(Dict[_KT, _VT]):
111
+ """An immutable version of a dict."""
112
+
113
+ # ImmutableDictBase start
114
+ @classmethod
115
+ def __class_getitem__( # type: ignore[override]
116
+ cls, key: Any
117
+ ) -> type[Self]:
118
+ return cls
119
+
120
+ def __delitem__(self, key: Any) -> NoReturn:
121
+ _immutable_fn(self)
122
+
123
+ def __setitem__(self, key: Any, value: Any) -> NoReturn:
124
+ _immutable_fn(self)
125
+
126
+ def __setattr__(self, key: Any, value: Any) -> NoReturn:
127
+ _immutable_fn(self)
128
+
129
+ def clear(self) -> NoReturn:
130
+ _immutable_fn(self)
131
+
132
+ def pop(self, key: Any, default: Optional[Any] = None) -> NoReturn:
133
+ _immutable_fn(self)
134
+
135
+ def popitem(self) -> NoReturn:
136
+ _immutable_fn(self)
137
+
138
+ def setdefault(self, key: Any, default: Optional[Any] = None) -> NoReturn:
139
+ _immutable_fn(self)
140
+
141
+ def update(self, *arg: Any, **kw: Any) -> NoReturn:
142
+ _immutable_fn(self)
143
+
144
+ # ImmutableDictBase end
145
+
146
+ def __repr__(self) -> str:
147
+ return f"immutabledict({dict.__repr__(self)})"
148
+
149
+ @cython.annotation_typing(False) # avoid cython crash from generic return
150
+ def union(
151
+ self, *dicts: Optional[Mapping[_KT, _VT]]
152
+ ) -> immutabledict[_KT, _VT]:
153
+ return self._union_other(dicts) # type: ignore[no-any-return]
154
+
155
+ @cython.annotation_typing(False) # avoid cython crash from generic return
156
+ def merge_with(
157
+ self, *dicts: Optional[Mapping[_KT, _VT]]
158
+ ) -> immutabledict[_KT, _VT]:
159
+ # this is an alias of union
160
+ return self._union_other(dicts) # type: ignore[no-any-return]
161
+
162
+ @cython.cfunc
163
+ @cython.inline
164
+ def _union_other(self, others: tuple) -> immutabledict:
165
+ size = len(others)
166
+ if size == 0:
167
+ return self
168
+
169
+ # only_one == immutabledict : we found exactly one immutabledict that
170
+ # has contents; no other dict / immutabledict has any contents
171
+ #
172
+ # only_one is None : we found more than one dict / immutabledict that
173
+ # has contents
174
+ #
175
+ # only_one is False : we've found nothing that is not an empty
176
+ # immutabledict
177
+ only_one: immutabledict | None | Literal[False]
178
+
179
+ if self:
180
+ self_is_empty = False
181
+ only_one = self
182
+ else:
183
+ only_one = False
184
+ self_is_empty = True
185
+
186
+ for i in range(size):
187
+ d = others[i]
188
+ if not d:
189
+ continue
190
+
191
+ if only_one is False and isinstance(d, immutabledict):
192
+ only_one = d
193
+ else:
194
+ only_one = None
195
+ break
196
+
197
+ if only_one is False:
198
+ return self
199
+ elif only_one is not None:
200
+ return only_one
201
+
202
+ result: immutabledict = immutabledict()
203
+ if not self_is_empty:
204
+ PyDict_Update(result, self)
205
+
206
+ for i in range(size):
207
+ d = others[i]
208
+ if not d:
209
+ continue
210
+ if isinstance(d, dict):
211
+ # c version of PyDict_Update supports only dicts
212
+ PyDict_Update(result, d)
213
+ else:
214
+ dict.update(result, d)
215
+
216
+ return result
217
+
218
+ def copy(self) -> Self:
219
+ return self
220
+
221
+ def __reduce__(self) -> Any:
222
+ return immutabledict, (dict(self),)
223
+
224
+ # PEP 584
225
+ def __ior__(self, __value: Any, /) -> NoReturn:
226
+ _immutable_fn(self)
227
+
228
+ def __or__( # type: ignore[override]
229
+ self, __value: Mapping[_KT, _VT], /
230
+ ) -> immutabledict[_KT, _VT]:
231
+ return immutabledict(
232
+ dict.__or__(self, __value), # type: ignore[call-overload,operator,unused-ignore] # noqa: E501
233
+ )
234
+
235
+ def __ror__( # type: ignore[override]
236
+ self, __value: Mapping[_KT, _VT], /
237
+ ) -> immutabledict[_KT, _VT]:
238
+ return immutabledict(
239
+ dict.__ror__(self, __value), # type: ignore[call-overload,operator,unused-ignore] # noqa: E501
240
+ )
@@ -0,0 +1,299 @@
1
+ # util/compat.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
+ """Handle Python version/platform incompatibilities."""
10
+
11
+ from __future__ import annotations
12
+
13
+ import base64
14
+ import dataclasses
15
+ import hashlib
16
+ from importlib import metadata as importlib_metadata
17
+ import inspect
18
+ import operator
19
+ import platform
20
+ import sys
21
+ import sysconfig
22
+ import typing
23
+ from typing import Any
24
+ from typing import Callable
25
+ from typing import Dict
26
+ from typing import Iterable
27
+ from typing import List
28
+ from typing import Mapping
29
+ from typing import Optional
30
+ from typing import Sequence
31
+ from typing import Set
32
+ from typing import Tuple
33
+ from typing import Type
34
+
35
+ py314b1 = sys.version_info >= (3, 14, 0, "beta", 1)
36
+ py314 = sys.version_info >= (3, 14)
37
+ py313 = sys.version_info >= (3, 13)
38
+ py312 = sys.version_info >= (3, 12)
39
+ py311 = sys.version_info >= (3, 11)
40
+ pypy = platform.python_implementation() == "PyPy"
41
+ cpython = platform.python_implementation() == "CPython"
42
+ freethreading = bool(sysconfig.get_config_var("Py_GIL_DISABLED"))
43
+
44
+ win32 = sys.platform.startswith("win")
45
+ osx = sys.platform.startswith("darwin")
46
+ arm = "aarch" in platform.machine().lower()
47
+ is64bit = sys.maxsize > 2**32
48
+
49
+ has_refcount_gc = bool(cpython)
50
+
51
+ dottedgetter = operator.attrgetter
52
+
53
+
54
+ # use sys.version_info to enable mypy version narrowing
55
+ if sys.version_info >= (3, 14):
56
+
57
+ import annotationlib
58
+ from string.templatelib import Template as Template
59
+
60
+ def get_annotations(obj: Any) -> Mapping[str, Any]:
61
+ return annotationlib.get_annotations(
62
+ obj, format=annotationlib.Format.FORWARDREF
63
+ )
64
+
65
+ else:
66
+
67
+ def get_annotations(obj: Any) -> Mapping[str, Any]:
68
+ return inspect.get_annotations(obj)
69
+
70
+ class Template:
71
+ """Minimal Template for Python < 3.14 (test usage only)."""
72
+
73
+ def __init__(self, *parts: Any):
74
+ self._parts = parts
75
+
76
+ @property
77
+ def strings(self) -> Tuple[str, ...]:
78
+ return tuple(p for p in self._parts if isinstance(p, str))
79
+
80
+ @property
81
+ def interpolations(self) -> Tuple[Any, ...]:
82
+ return tuple(p for p in self._parts if not isinstance(p, str))
83
+
84
+ def __iter__(self) -> Any:
85
+ return iter(self._parts)
86
+
87
+
88
+ class FullArgSpec(typing.NamedTuple):
89
+ args: List[str]
90
+ varargs: Optional[str]
91
+ varkw: Optional[str]
92
+ defaults: Optional[Tuple[Any, ...]]
93
+ kwonlyargs: List[str]
94
+ kwonlydefaults: Optional[Dict[str, Any]]
95
+ annotations: Mapping[str, Any]
96
+
97
+
98
+ def inspect_getfullargspec(func: Callable[..., Any]) -> FullArgSpec:
99
+ """Fully vendored version of getfullargspec from Python 3.3."""
100
+
101
+ if inspect.ismethod(func):
102
+ func = func.__func__
103
+ if not inspect.isfunction(func):
104
+ raise TypeError(f"{func!r} is not a Python function")
105
+
106
+ co = func.__code__
107
+ if not inspect.iscode(co):
108
+ raise TypeError(f"{co!r} is not a code object")
109
+
110
+ nargs = co.co_argcount
111
+ names = co.co_varnames
112
+ nkwargs = co.co_kwonlyargcount
113
+ args = list(names[:nargs])
114
+ kwonlyargs = list(names[nargs : nargs + nkwargs])
115
+
116
+ nargs += nkwargs
117
+ varargs = None
118
+ if co.co_flags & inspect.CO_VARARGS:
119
+ varargs = co.co_varnames[nargs]
120
+ nargs = nargs + 1
121
+ varkw = None
122
+ if co.co_flags & inspect.CO_VARKEYWORDS:
123
+ varkw = co.co_varnames[nargs]
124
+
125
+ return FullArgSpec(
126
+ args,
127
+ varargs,
128
+ varkw,
129
+ func.__defaults__,
130
+ kwonlyargs,
131
+ func.__kwdefaults__,
132
+ get_annotations(func),
133
+ )
134
+
135
+
136
+ # python stubs don't have a public type for this. not worth
137
+ # making a protocol
138
+ def md5_not_for_security() -> Any:
139
+ return hashlib.md5(usedforsecurity=False)
140
+
141
+
142
+ def importlib_metadata_get(group):
143
+ ep = importlib_metadata.entry_points()
144
+ if typing.TYPE_CHECKING or hasattr(ep, "select"):
145
+ return ep.select(group=group)
146
+ else:
147
+ return ep.get(group, ())
148
+
149
+
150
+ def b(s):
151
+ return s.encode("latin-1")
152
+
153
+
154
+ def b64decode(x: str) -> bytes:
155
+ return base64.b64decode(x.encode("ascii"))
156
+
157
+
158
+ def b64encode(x: bytes) -> str:
159
+ return base64.b64encode(x).decode("ascii")
160
+
161
+
162
+ def decode_backslashreplace(text: bytes, encoding: str) -> str:
163
+ return text.decode(encoding, errors="backslashreplace")
164
+
165
+
166
+ def cmp(a, b):
167
+ return (a > b) - (a < b)
168
+
169
+
170
+ def _formatannotation(annotation, base_module=None):
171
+ """vendored from python 3.7"""
172
+
173
+ if isinstance(annotation, str):
174
+ return annotation
175
+
176
+ if getattr(annotation, "__module__", None) == "typing":
177
+ return repr(annotation).replace("typing.", "").replace("~", "")
178
+ if isinstance(annotation, type):
179
+ if annotation.__module__ in ("builtins", base_module):
180
+ return repr(annotation.__qualname__)
181
+ return annotation.__module__ + "." + annotation.__qualname__
182
+ elif isinstance(annotation, typing.TypeVar):
183
+ return repr(annotation).replace("~", "")
184
+ return repr(annotation).replace("~", "")
185
+
186
+
187
+ def inspect_formatargspec(
188
+ args: List[str],
189
+ varargs: Optional[str] = None,
190
+ varkw: Optional[str] = None,
191
+ defaults: Optional[Sequence[Any]] = None,
192
+ kwonlyargs: Optional[Sequence[str]] = (),
193
+ kwonlydefaults: Optional[Mapping[str, Any]] = {},
194
+ annotations: Mapping[str, Any] = {},
195
+ formatarg: Callable[[str], str] = str,
196
+ formatvarargs: Callable[[str], str] = lambda name: "*" + name,
197
+ formatvarkw: Callable[[str], str] = lambda name: "**" + name,
198
+ formatvalue: Callable[[Any], str] = lambda value: "=" + repr(value),
199
+ formatreturns: Callable[[Any], str] = lambda text: " -> " + str(text),
200
+ formatannotation: Callable[[Any], str] = _formatannotation,
201
+ ) -> str:
202
+ """Copy formatargspec from python 3.7 standard library.
203
+
204
+ Python 3 has deprecated formatargspec and requested that Signature
205
+ be used instead, however this requires a full reimplementation
206
+ of formatargspec() in terms of creating Parameter objects and such.
207
+ Instead of introducing all the object-creation overhead and having
208
+ to reinvent from scratch, just copy their compatibility routine.
209
+
210
+ Ultimately we would need to rewrite our "decorator" routine completely
211
+ which is not really worth it right now, until all Python 2.x support
212
+ is dropped.
213
+
214
+ """
215
+
216
+ kwonlydefaults = kwonlydefaults or {}
217
+ annotations = annotations or {}
218
+
219
+ def formatargandannotation(arg):
220
+ result = formatarg(arg)
221
+ if arg in annotations:
222
+ result += ": " + formatannotation(annotations[arg])
223
+ return result
224
+
225
+ specs = []
226
+ if defaults:
227
+ firstdefault = len(args) - len(defaults)
228
+ else:
229
+ firstdefault = -1
230
+
231
+ for i, arg in enumerate(args):
232
+ spec = formatargandannotation(arg)
233
+ if defaults and i >= firstdefault:
234
+ spec = spec + formatvalue(defaults[i - firstdefault])
235
+ specs.append(spec)
236
+
237
+ if varargs is not None:
238
+ specs.append(formatvarargs(formatargandannotation(varargs)))
239
+ else:
240
+ if kwonlyargs:
241
+ specs.append("*")
242
+
243
+ if kwonlyargs:
244
+ for kwonlyarg in kwonlyargs:
245
+ spec = formatargandannotation(kwonlyarg)
246
+ if kwonlydefaults and kwonlyarg in kwonlydefaults:
247
+ spec += formatvalue(kwonlydefaults[kwonlyarg])
248
+ specs.append(spec)
249
+
250
+ if varkw is not None:
251
+ specs.append(formatvarkw(formatargandannotation(varkw)))
252
+
253
+ result = "(" + ", ".join(specs) + ")"
254
+ if "return" in annotations:
255
+ result += formatreturns(formatannotation(annotations["return"]))
256
+ return result
257
+
258
+
259
+ def dataclass_fields(cls: Type[Any]) -> Iterable[dataclasses.Field[Any]]:
260
+ """Return a sequence of all dataclasses.Field objects associated
261
+ with a class as an already processed dataclass.
262
+
263
+ The class must **already be a dataclass** for Field objects to be returned.
264
+
265
+ """
266
+
267
+ if dataclasses.is_dataclass(cls):
268
+ return dataclasses.fields(cls)
269
+ else:
270
+ return []
271
+
272
+
273
+ def local_dataclass_fields(cls: Type[Any]) -> Iterable[dataclasses.Field[Any]]:
274
+ """Return a sequence of all dataclasses.Field objects associated with
275
+ an already processed dataclass, excluding those that originate from a
276
+ superclass.
277
+
278
+ The class must **already be a dataclass** for Field objects to be returned.
279
+
280
+ """
281
+
282
+ if dataclasses.is_dataclass(cls):
283
+ super_fields: Set[dataclasses.Field[Any]] = set()
284
+ for sup in cls.__bases__:
285
+ super_fields.update(dataclass_fields(sup))
286
+ return [f for f in dataclasses.fields(cls) if f not in super_fields]
287
+ else:
288
+ return []
289
+
290
+
291
+ if freethreading:
292
+ import threading
293
+
294
+ mini_gil = threading.RLock()
295
+ """provide a threading.RLock() under python freethreading only"""
296
+ else:
297
+ import contextlib
298
+
299
+ mini_gil = contextlib.nullcontext() # type: ignore[assignment]