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,590 @@
1
+ # sql/annotation.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
+
8
+ """The :class:`.Annotated` class and related routines; creates hash-equivalent
9
+ copies of SQL constructs which contain context-specific markers and
10
+ associations.
11
+
12
+ Note that the :class:`.Annotated` concept as implemented in this module is not
13
+ related in any way to the pep-593 concept of "Annotated".
14
+
15
+
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from operator import itemgetter
21
+ import typing
22
+ from typing import Any
23
+ from typing import Callable
24
+ from typing import cast
25
+ from typing import Dict
26
+ from typing import FrozenSet
27
+ from typing import Literal
28
+ from typing import Mapping
29
+ from typing import Optional
30
+ from typing import overload
31
+ from typing import Sequence
32
+ from typing import Tuple
33
+ from typing import Type
34
+ from typing import TYPE_CHECKING
35
+ from typing import TypeVar
36
+
37
+ from . import operators
38
+ from .cache_key import HasCacheKey
39
+ from .visitors import anon_map
40
+ from .visitors import ExternallyTraversible
41
+ from .visitors import InternalTraversal
42
+ from .. import util
43
+ from ..util.typing import Self
44
+
45
+ if TYPE_CHECKING:
46
+ from .base import _EntityNamespace
47
+ from .visitors import _TraverseInternalsType
48
+
49
+ _AnnotationDict = Mapping[str, Any]
50
+
51
+ EMPTY_ANNOTATIONS: util.immutabledict[str, Any] = util.EMPTY_DICT
52
+
53
+
54
+ class SupportsAnnotations(ExternallyTraversible):
55
+ __slots__ = ()
56
+
57
+ _annotations: util.immutabledict[str, Any] = EMPTY_ANNOTATIONS
58
+
59
+ proxy_set: util.generic_fn_descriptor[FrozenSet[Any]]
60
+
61
+ _is_immutable: bool
62
+
63
+ def _annotate(self, values: _AnnotationDict) -> Self:
64
+ raise NotImplementedError()
65
+
66
+ @overload
67
+ def _deannotate(
68
+ self,
69
+ values: Literal[None] = ...,
70
+ clone: bool = ...,
71
+ ) -> Self: ...
72
+
73
+ @overload
74
+ def _deannotate(
75
+ self,
76
+ values: Sequence[str] = ...,
77
+ clone: bool = ...,
78
+ ) -> SupportsAnnotations: ...
79
+
80
+ def _deannotate(
81
+ self,
82
+ values: Optional[Sequence[str]] = None,
83
+ clone: bool = False,
84
+ ) -> SupportsAnnotations:
85
+ raise NotImplementedError()
86
+
87
+ @util.memoized_property
88
+ def _annotations_cache_key(self) -> Tuple[Any, ...]:
89
+ anon_map_ = anon_map()
90
+
91
+ return self._gen_annotations_cache_key(anon_map_)
92
+
93
+ def _gen_annotations_cache_key(
94
+ self, anon_map: anon_map
95
+ ) -> Tuple[Any, ...]:
96
+ return (
97
+ "_annotations",
98
+ tuple(
99
+ (
100
+ key,
101
+ (
102
+ value._gen_cache_key(anon_map, [])
103
+ if isinstance(value, HasCacheKey)
104
+ else value
105
+ ),
106
+ )
107
+ for key, value in sorted(
108
+ self._annotations.items(), key=_get_item0
109
+ )
110
+ ),
111
+ )
112
+
113
+
114
+ _get_item0 = itemgetter(0)
115
+
116
+
117
+ class SupportsWrappingAnnotations(SupportsAnnotations):
118
+ __slots__ = ()
119
+
120
+ _constructor: Callable[..., SupportsWrappingAnnotations]
121
+
122
+ if TYPE_CHECKING:
123
+
124
+ @util.ro_non_memoized_property
125
+ def entity_namespace(self) -> _EntityNamespace: ...
126
+
127
+ def _annotate(self, values: _AnnotationDict) -> Self:
128
+ """return a copy of this ClauseElement with annotations
129
+ updated by the given dictionary.
130
+
131
+ """
132
+ return Annotated._as_annotated_instance(self, values) # type: ignore
133
+
134
+ def _with_annotations(self, values: _AnnotationDict) -> Self:
135
+ """return a copy of this ClauseElement with annotations
136
+ replaced by the given dictionary.
137
+
138
+ """
139
+ return Annotated._as_annotated_instance(self, values) # type: ignore
140
+
141
+ @overload
142
+ def _deannotate(
143
+ self,
144
+ values: Literal[None] = ...,
145
+ clone: bool = ...,
146
+ ) -> Self: ...
147
+
148
+ @overload
149
+ def _deannotate(
150
+ self,
151
+ values: Sequence[str] = ...,
152
+ clone: bool = ...,
153
+ ) -> SupportsAnnotations: ...
154
+
155
+ def _deannotate(
156
+ self,
157
+ values: Optional[Sequence[str]] = None,
158
+ clone: bool = False,
159
+ ) -> SupportsAnnotations:
160
+ """return a copy of this :class:`_expression.ClauseElement`
161
+ with annotations
162
+ removed.
163
+
164
+ :param values: optional tuple of individual values
165
+ to remove.
166
+
167
+ """
168
+ if clone:
169
+ s = self._clone()
170
+ return s
171
+ else:
172
+ return self
173
+
174
+
175
+ class SupportsCloneAnnotations(SupportsWrappingAnnotations):
176
+ # SupportsCloneAnnotations extends from SupportsWrappingAnnotations
177
+ # to support the structure of having the base ClauseElement
178
+ # be a subclass of SupportsWrappingAnnotations. Any ClauseElement
179
+ # subclass that wants to extend from SupportsCloneAnnotations
180
+ # will inherently also be subclassing SupportsWrappingAnnotations, so
181
+ # make that specific here.
182
+
183
+ if not typing.TYPE_CHECKING:
184
+ __slots__ = ()
185
+
186
+ _clone_annotations_traverse_internals: _TraverseInternalsType = [
187
+ ("_annotations", InternalTraversal.dp_annotations_key)
188
+ ]
189
+
190
+ def _annotate(self, values: _AnnotationDict) -> Self:
191
+ """return a copy of this ClauseElement with annotations
192
+ updated by the given dictionary.
193
+
194
+ """
195
+ new = self._clone()
196
+ new._annotations = new._annotations.union(values)
197
+ new.__dict__.pop("_annotations_cache_key", None)
198
+ new.__dict__.pop("_generate_cache_key", None)
199
+ return new
200
+
201
+ def _with_annotations(self, values: _AnnotationDict) -> Self:
202
+ """return a copy of this ClauseElement with annotations
203
+ replaced by the given dictionary.
204
+
205
+ """
206
+ new = self._clone()
207
+ new._annotations = util.immutabledict(values)
208
+ new.__dict__.pop("_annotations_cache_key", None)
209
+ new.__dict__.pop("_generate_cache_key", None)
210
+ return new
211
+
212
+ @overload
213
+ def _deannotate(
214
+ self,
215
+ values: Literal[None] = ...,
216
+ clone: bool = ...,
217
+ ) -> Self: ...
218
+
219
+ @overload
220
+ def _deannotate(
221
+ self,
222
+ values: Sequence[str] = ...,
223
+ clone: bool = ...,
224
+ ) -> SupportsAnnotations: ...
225
+
226
+ def _deannotate(
227
+ self,
228
+ values: Optional[Sequence[str]] = None,
229
+ clone: bool = False,
230
+ ) -> SupportsAnnotations:
231
+ """return a copy of this :class:`_expression.ClauseElement`
232
+ with annotations
233
+ removed.
234
+
235
+ :param values: optional tuple of individual values
236
+ to remove.
237
+
238
+ """
239
+ if clone or self._annotations:
240
+ # clone is used when we are also copying
241
+ # the expression for a deep deannotation
242
+ new = self._clone()
243
+ new._annotations = util.EMPTY_DICT
244
+ new.__dict__.pop("_annotations_cache_key", None)
245
+ return new
246
+ else:
247
+ return self
248
+
249
+
250
+ class Annotated(SupportsAnnotations):
251
+ """clones a SupportsAnnotations and applies an 'annotations' dictionary.
252
+
253
+ Unlike regular clones, this clone also mimics __hash__() and
254
+ __eq__() of the original element so that it takes its place
255
+ in hashed collections.
256
+
257
+ A reference to the original element is maintained, for the important
258
+ reason of keeping its hash value current. When GC'ed, the
259
+ hash value may be reused, causing conflicts.
260
+
261
+ .. note:: The rationale for Annotated producing a brand new class,
262
+ rather than placing the functionality directly within ClauseElement,
263
+ is **performance**. The __hash__() method is absent on plain
264
+ ClauseElement which leads to significantly reduced function call
265
+ overhead, as the use of sets and dictionaries against ClauseElement
266
+ objects is prevalent, but most are not "annotated".
267
+
268
+ """
269
+
270
+ _is_column_operators = False
271
+
272
+ @classmethod
273
+ def _as_annotated_instance(
274
+ cls, element: SupportsWrappingAnnotations, values: _AnnotationDict
275
+ ) -> Annotated:
276
+ try:
277
+ cls = annotated_classes[element.__class__]
278
+ except KeyError:
279
+ cls = _new_annotation_type(element.__class__, cls)
280
+ return cls(element, values)
281
+
282
+ _annotations: util.immutabledict[str, Any]
283
+ __element: SupportsWrappingAnnotations
284
+ _hash: int
285
+
286
+ def __new__(cls: Type[Self], *args: Any) -> Self:
287
+ return object.__new__(cls)
288
+
289
+ def __init__(
290
+ self, element: SupportsWrappingAnnotations, values: _AnnotationDict
291
+ ):
292
+ self.__dict__ = element.__dict__.copy()
293
+ self.__dict__.pop("_annotations_cache_key", None)
294
+ self.__dict__.pop("_generate_cache_key", None)
295
+ self.__element = element
296
+ self._annotations = util.immutabledict(values)
297
+ self._hash = hash(element)
298
+
299
+ def _annotate(self, values: _AnnotationDict) -> Self:
300
+ _values = self._annotations.union(values)
301
+ new = self._with_annotations(_values)
302
+ return new
303
+
304
+ def _with_annotations(self, values: _AnnotationDict) -> Self:
305
+ clone = self.__class__.__new__(self.__class__)
306
+ clone.__dict__ = self.__dict__.copy()
307
+ clone.__dict__.pop("_annotations_cache_key", None)
308
+ clone.__dict__.pop("_generate_cache_key", None)
309
+ clone._annotations = util.immutabledict(values)
310
+ return clone
311
+
312
+ @overload
313
+ def _deannotate(
314
+ self,
315
+ values: Literal[None] = ...,
316
+ clone: bool = ...,
317
+ ) -> Self: ...
318
+
319
+ @overload
320
+ def _deannotate(
321
+ self,
322
+ values: Sequence[str] = ...,
323
+ clone: bool = ...,
324
+ ) -> Annotated: ...
325
+
326
+ def _deannotate(
327
+ self,
328
+ values: Optional[Sequence[str]] = None,
329
+ clone: bool = True,
330
+ ) -> SupportsAnnotations:
331
+ if values is None:
332
+ return self.__element
333
+ else:
334
+ return self._with_annotations(
335
+ util.immutabledict(
336
+ {
337
+ key: value
338
+ for key, value in self._annotations.items()
339
+ if key not in values
340
+ }
341
+ )
342
+ )
343
+
344
+ if not typing.TYPE_CHECKING:
345
+ # manually proxy some methods that need extra attention
346
+ def _compiler_dispatch(self, visitor: Any, **kw: Any) -> Any:
347
+ return self.__element.__class__._compiler_dispatch(
348
+ self, visitor, **kw
349
+ )
350
+
351
+ @property
352
+ def _constructor(self):
353
+ return self.__element._constructor
354
+
355
+ def _clone(self, **kw: Any) -> Self:
356
+ clone = self.__element._clone(**kw)
357
+ if clone is self.__element:
358
+ # detect immutable, don't change anything
359
+ return self
360
+ else:
361
+ # update the clone with any changes that have occurred
362
+ # to this object's __dict__.
363
+ clone.__dict__.update(self.__dict__)
364
+ return self.__class__(clone, self._annotations)
365
+
366
+ def __reduce__(self) -> Tuple[Type[Annotated], Tuple[Any, ...]]:
367
+ return self.__class__, (self.__element, self._annotations)
368
+
369
+ def __hash__(self) -> int:
370
+ return self._hash
371
+
372
+ def __eq__(self, other: Any) -> bool:
373
+ if self._is_column_operators:
374
+ return self.__element.__class__.__eq__(self, other)
375
+ else:
376
+ return hash(other) == hash(self)
377
+
378
+ @util.ro_non_memoized_property
379
+ def entity_namespace(self) -> _EntityNamespace:
380
+ if "entity_namespace" in self._annotations:
381
+ return cast(
382
+ SupportsWrappingAnnotations,
383
+ self._annotations["entity_namespace"],
384
+ ).entity_namespace
385
+ else:
386
+ return self.__element.entity_namespace
387
+
388
+
389
+ # hard-generate Annotated subclasses. this technique
390
+ # is used instead of on-the-fly types (i.e. type.__new__())
391
+ # so that the resulting objects are pickleable; additionally, other
392
+ # decisions can be made up front about the type of object being annotated
393
+ # just once per class rather than per-instance.
394
+ annotated_classes: Dict[Type[SupportsWrappingAnnotations], Type[Annotated]] = (
395
+ {}
396
+ )
397
+
398
+ _SA = TypeVar("_SA", bound="SupportsAnnotations")
399
+
400
+
401
+ def _safe_annotate(to_annotate: _SA, annotations: _AnnotationDict) -> _SA:
402
+ try:
403
+ _annotate = to_annotate._annotate
404
+ except AttributeError:
405
+ # skip objects that don't actually have an `_annotate`
406
+ # attribute, namely QueryableAttribute inside of a join
407
+ # condition
408
+ return to_annotate
409
+ else:
410
+ return _annotate(annotations)
411
+
412
+
413
+ def _deep_annotate(
414
+ element: _SA,
415
+ annotations: _AnnotationDict,
416
+ exclude: Optional[Sequence[SupportsAnnotations]] = None,
417
+ *,
418
+ detect_subquery_cols: bool = False,
419
+ ind_cols_on_fromclause: bool = False,
420
+ annotate_callable: Optional[
421
+ Callable[[SupportsAnnotations, _AnnotationDict], SupportsAnnotations]
422
+ ] = None,
423
+ ) -> _SA:
424
+ """Deep copy the given ClauseElement, annotating each element
425
+ with the given annotations dictionary.
426
+
427
+ Elements within the exclude collection will be cloned but not annotated.
428
+
429
+ """
430
+
431
+ # annotated objects hack the __hash__() method so if we want to
432
+ # uniquely process them we have to use id()
433
+
434
+ cloned_ids: Dict[int, SupportsAnnotations] = {}
435
+
436
+ def clone(elem: SupportsAnnotations, **kw: Any) -> SupportsAnnotations:
437
+ # ind_cols_on_fromclause means make sure an AnnotatedFromClause
438
+ # has its own .c collection independent of that which its proxying.
439
+ # this is used specifically by orm.LoaderCriteriaOption to break
440
+ # a reference cycle that it's otherwise prone to building,
441
+ # see test_relationship_criteria->
442
+ # test_loader_criteria_subquery_w_same_entity. logic here was
443
+ # changed for #8796 and made explicit; previously it occurred
444
+ # by accident
445
+
446
+ kw["detect_subquery_cols"] = detect_subquery_cols
447
+ id_ = id(elem)
448
+
449
+ if id_ in cloned_ids:
450
+ return cloned_ids[id_]
451
+
452
+ if (
453
+ exclude
454
+ and hasattr(elem, "proxy_set")
455
+ and elem.proxy_set.intersection(exclude)
456
+ ):
457
+ newelem = elem._clone(clone=clone, **kw)
458
+ elif annotations != elem._annotations:
459
+ if detect_subquery_cols and elem._is_immutable:
460
+ to_annotate = elem._clone(clone=clone, **kw)
461
+ else:
462
+ to_annotate = elem
463
+ if annotate_callable:
464
+ newelem = annotate_callable(to_annotate, annotations)
465
+ else:
466
+ newelem = _safe_annotate(to_annotate, annotations)
467
+ else:
468
+ newelem = elem
469
+
470
+ newelem._copy_internals(
471
+ clone=clone,
472
+ ind_cols_on_fromclause=ind_cols_on_fromclause,
473
+ _annotations_traversal=True,
474
+ )
475
+
476
+ cloned_ids[id_] = newelem
477
+ return newelem
478
+
479
+ if element is not None:
480
+ element = cast(_SA, clone(element))
481
+ clone = None # type: ignore # remove gc cycles
482
+ return element
483
+
484
+
485
+ @overload
486
+ def _deep_deannotate(
487
+ element: Literal[None], values: Optional[Sequence[str]] = None
488
+ ) -> Literal[None]: ...
489
+
490
+
491
+ @overload
492
+ def _deep_deannotate(
493
+ element: _SA, values: Optional[Sequence[str]] = None
494
+ ) -> _SA: ...
495
+
496
+
497
+ def _deep_deannotate(
498
+ element: Optional[_SA], values: Optional[Sequence[str]] = None
499
+ ) -> Optional[_SA]:
500
+ """Deep copy the given element, removing annotations."""
501
+
502
+ cloned: Dict[Any, SupportsAnnotations] = {}
503
+
504
+ def clone(elem: SupportsAnnotations, **kw: Any) -> SupportsAnnotations:
505
+ key: Any
506
+ if values:
507
+ key = id(elem)
508
+ else:
509
+ key = elem
510
+
511
+ if key not in cloned:
512
+ newelem = elem._deannotate(values=values, clone=True)
513
+ newelem._copy_internals(clone=clone, _annotations_traversal=True)
514
+ cloned[key] = newelem
515
+ return newelem
516
+ else:
517
+ return cloned[key]
518
+
519
+ if element is not None:
520
+ element = cast(_SA, clone(element))
521
+ clone = None # type: ignore # remove gc cycles
522
+ return element
523
+
524
+
525
+ def _shallow_annotate(element: _SA, annotations: _AnnotationDict) -> _SA:
526
+ """Annotate the given ClauseElement and copy its internals so that
527
+ internal objects refer to the new annotated object.
528
+
529
+ Basically used to apply a "don't traverse" annotation to a
530
+ selectable, without digging throughout the whole
531
+ structure wasting time.
532
+ """
533
+ element = element._annotate(annotations)
534
+ element._copy_internals(_annotations_traversal=True)
535
+ return element
536
+
537
+
538
+ def _new_annotation_type(
539
+ cls: Type[SupportsWrappingAnnotations], base_cls: Type[Annotated]
540
+ ) -> Type[Annotated]:
541
+ """Generates a new class that subclasses Annotated and proxies a given
542
+ element type.
543
+
544
+ """
545
+ if issubclass(cls, Annotated):
546
+ return cls
547
+ elif cls in annotated_classes:
548
+ return annotated_classes[cls]
549
+
550
+ for super_ in cls.__mro__:
551
+ # check if an Annotated subclass more specific than
552
+ # the given base_cls is already registered, such
553
+ # as AnnotatedColumnElement.
554
+ if super_ in annotated_classes:
555
+ base_cls = annotated_classes[super_]
556
+ break
557
+
558
+ annotated_classes[cls] = anno_cls = cast(
559
+ Type[Annotated],
560
+ type("Annotated%s" % cls.__name__, (base_cls, cls), {}),
561
+ )
562
+ globals()["Annotated%s" % cls.__name__] = anno_cls
563
+
564
+ if "_traverse_internals" in cls.__dict__:
565
+ anno_cls._traverse_internals = list(cls._traverse_internals) + [
566
+ ("_annotations", InternalTraversal.dp_annotations_key)
567
+ ]
568
+ elif cls.__dict__.get("inherit_cache", False):
569
+ anno_cls._traverse_internals = list(cls._traverse_internals) + [
570
+ ("_annotations", InternalTraversal.dp_annotations_key)
571
+ ]
572
+
573
+ # some classes include this even if they have traverse_internals
574
+ # e.g. BindParameter, add it if present.
575
+ if cls.__dict__.get("inherit_cache", False):
576
+ anno_cls.inherit_cache = True # type: ignore
577
+ elif "inherit_cache" in cls.__dict__:
578
+ anno_cls.inherit_cache = cls.__dict__["inherit_cache"] # type: ignore
579
+
580
+ anno_cls._is_column_operators = issubclass(cls, operators.ColumnOperators)
581
+
582
+ return anno_cls
583
+
584
+
585
+ def _prepare_annotations(
586
+ target_hierarchy: Type[SupportsWrappingAnnotations],
587
+ base_cls: Type[Annotated],
588
+ ) -> None:
589
+ for cls in util.walk_subclasses(target_hierarchy):
590
+ _new_annotation_type(cls, base_cls)