SQLAlchemy 2.0.47__cp313-cp313t-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. sqlalchemy/__init__.py +283 -0
  2. sqlalchemy/connectors/__init__.py +18 -0
  3. sqlalchemy/connectors/aioodbc.py +184 -0
  4. sqlalchemy/connectors/asyncio.py +429 -0
  5. sqlalchemy/connectors/pyodbc.py +250 -0
  6. sqlalchemy/cyextension/__init__.py +6 -0
  7. sqlalchemy/cyextension/collections.cp313t-win32.pyd +0 -0
  8. sqlalchemy/cyextension/collections.pyx +409 -0
  9. sqlalchemy/cyextension/immutabledict.cp313t-win32.pyd +0 -0
  10. sqlalchemy/cyextension/immutabledict.pxd +8 -0
  11. sqlalchemy/cyextension/immutabledict.pyx +133 -0
  12. sqlalchemy/cyextension/processors.cp313t-win32.pyd +0 -0
  13. sqlalchemy/cyextension/processors.pyx +68 -0
  14. sqlalchemy/cyextension/resultproxy.cp313t-win32.pyd +0 -0
  15. sqlalchemy/cyextension/resultproxy.pyx +102 -0
  16. sqlalchemy/cyextension/util.cp313t-win32.pyd +0 -0
  17. sqlalchemy/cyextension/util.pyx +90 -0
  18. sqlalchemy/dialects/__init__.py +62 -0
  19. sqlalchemy/dialects/_typing.py +30 -0
  20. sqlalchemy/dialects/mssql/__init__.py +88 -0
  21. sqlalchemy/dialects/mssql/aioodbc.py +63 -0
  22. sqlalchemy/dialects/mssql/base.py +4093 -0
  23. sqlalchemy/dialects/mssql/information_schema.py +285 -0
  24. sqlalchemy/dialects/mssql/json.py +129 -0
  25. sqlalchemy/dialects/mssql/provision.py +185 -0
  26. sqlalchemy/dialects/mssql/pymssql.py +126 -0
  27. sqlalchemy/dialects/mssql/pyodbc.py +760 -0
  28. sqlalchemy/dialects/mysql/__init__.py +104 -0
  29. sqlalchemy/dialects/mysql/aiomysql.py +250 -0
  30. sqlalchemy/dialects/mysql/asyncmy.py +231 -0
  31. sqlalchemy/dialects/mysql/base.py +3949 -0
  32. sqlalchemy/dialects/mysql/cymysql.py +106 -0
  33. sqlalchemy/dialects/mysql/dml.py +225 -0
  34. sqlalchemy/dialects/mysql/enumerated.py +282 -0
  35. sqlalchemy/dialects/mysql/expression.py +146 -0
  36. sqlalchemy/dialects/mysql/json.py +91 -0
  37. sqlalchemy/dialects/mysql/mariadb.py +72 -0
  38. sqlalchemy/dialects/mysql/mariadbconnector.py +322 -0
  39. sqlalchemy/dialects/mysql/mysqlconnector.py +302 -0
  40. sqlalchemy/dialects/mysql/mysqldb.py +314 -0
  41. sqlalchemy/dialects/mysql/provision.py +153 -0
  42. sqlalchemy/dialects/mysql/pymysql.py +158 -0
  43. sqlalchemy/dialects/mysql/pyodbc.py +157 -0
  44. sqlalchemy/dialects/mysql/reflection.py +727 -0
  45. sqlalchemy/dialects/mysql/reserved_words.py +570 -0
  46. sqlalchemy/dialects/mysql/types.py +835 -0
  47. sqlalchemy/dialects/oracle/__init__.py +81 -0
  48. sqlalchemy/dialects/oracle/base.py +3802 -0
  49. sqlalchemy/dialects/oracle/cx_oracle.py +1555 -0
  50. sqlalchemy/dialects/oracle/dictionary.py +507 -0
  51. sqlalchemy/dialects/oracle/oracledb.py +941 -0
  52. sqlalchemy/dialects/oracle/provision.py +297 -0
  53. sqlalchemy/dialects/oracle/types.py +316 -0
  54. sqlalchemy/dialects/oracle/vector.py +365 -0
  55. sqlalchemy/dialects/postgresql/__init__.py +167 -0
  56. sqlalchemy/dialects/postgresql/_psycopg_common.py +189 -0
  57. sqlalchemy/dialects/postgresql/array.py +519 -0
  58. sqlalchemy/dialects/postgresql/asyncpg.py +1284 -0
  59. sqlalchemy/dialects/postgresql/base.py +5378 -0
  60. sqlalchemy/dialects/postgresql/dml.py +339 -0
  61. sqlalchemy/dialects/postgresql/ext.py +540 -0
  62. sqlalchemy/dialects/postgresql/hstore.py +406 -0
  63. sqlalchemy/dialects/postgresql/json.py +404 -0
  64. sqlalchemy/dialects/postgresql/named_types.py +524 -0
  65. sqlalchemy/dialects/postgresql/operators.py +129 -0
  66. sqlalchemy/dialects/postgresql/pg8000.py +669 -0
  67. sqlalchemy/dialects/postgresql/pg_catalog.py +326 -0
  68. sqlalchemy/dialects/postgresql/provision.py +183 -0
  69. sqlalchemy/dialects/postgresql/psycopg.py +862 -0
  70. sqlalchemy/dialects/postgresql/psycopg2.py +892 -0
  71. sqlalchemy/dialects/postgresql/psycopg2cffi.py +61 -0
  72. sqlalchemy/dialects/postgresql/ranges.py +1031 -0
  73. sqlalchemy/dialects/postgresql/types.py +313 -0
  74. sqlalchemy/dialects/sqlite/__init__.py +57 -0
  75. sqlalchemy/dialects/sqlite/aiosqlite.py +482 -0
  76. sqlalchemy/dialects/sqlite/base.py +3056 -0
  77. sqlalchemy/dialects/sqlite/dml.py +263 -0
  78. sqlalchemy/dialects/sqlite/json.py +92 -0
  79. sqlalchemy/dialects/sqlite/provision.py +229 -0
  80. sqlalchemy/dialects/sqlite/pysqlcipher.py +157 -0
  81. sqlalchemy/dialects/sqlite/pysqlite.py +756 -0
  82. sqlalchemy/dialects/type_migration_guidelines.txt +145 -0
  83. sqlalchemy/engine/__init__.py +62 -0
  84. sqlalchemy/engine/_py_processors.py +136 -0
  85. sqlalchemy/engine/_py_row.py +128 -0
  86. sqlalchemy/engine/_py_util.py +74 -0
  87. sqlalchemy/engine/base.py +3390 -0
  88. sqlalchemy/engine/characteristics.py +155 -0
  89. sqlalchemy/engine/create.py +893 -0
  90. sqlalchemy/engine/cursor.py +2298 -0
  91. sqlalchemy/engine/default.py +2394 -0
  92. sqlalchemy/engine/events.py +965 -0
  93. sqlalchemy/engine/interfaces.py +3471 -0
  94. sqlalchemy/engine/mock.py +134 -0
  95. sqlalchemy/engine/processors.py +61 -0
  96. sqlalchemy/engine/reflection.py +2102 -0
  97. sqlalchemy/engine/result.py +2399 -0
  98. sqlalchemy/engine/row.py +400 -0
  99. sqlalchemy/engine/strategies.py +16 -0
  100. sqlalchemy/engine/url.py +924 -0
  101. sqlalchemy/engine/util.py +167 -0
  102. sqlalchemy/event/__init__.py +26 -0
  103. sqlalchemy/event/api.py +220 -0
  104. sqlalchemy/event/attr.py +676 -0
  105. sqlalchemy/event/base.py +472 -0
  106. sqlalchemy/event/legacy.py +258 -0
  107. sqlalchemy/event/registry.py +390 -0
  108. sqlalchemy/events.py +17 -0
  109. sqlalchemy/exc.py +832 -0
  110. sqlalchemy/ext/__init__.py +11 -0
  111. sqlalchemy/ext/associationproxy.py +2027 -0
  112. sqlalchemy/ext/asyncio/__init__.py +25 -0
  113. sqlalchemy/ext/asyncio/base.py +281 -0
  114. sqlalchemy/ext/asyncio/engine.py +1471 -0
  115. sqlalchemy/ext/asyncio/exc.py +21 -0
  116. sqlalchemy/ext/asyncio/result.py +965 -0
  117. sqlalchemy/ext/asyncio/scoping.py +1599 -0
  118. sqlalchemy/ext/asyncio/session.py +1947 -0
  119. sqlalchemy/ext/automap.py +1701 -0
  120. sqlalchemy/ext/baked.py +570 -0
  121. sqlalchemy/ext/compiler.py +600 -0
  122. sqlalchemy/ext/declarative/__init__.py +65 -0
  123. sqlalchemy/ext/declarative/extensions.py +564 -0
  124. sqlalchemy/ext/horizontal_shard.py +478 -0
  125. sqlalchemy/ext/hybrid.py +1535 -0
  126. sqlalchemy/ext/indexable.py +364 -0
  127. sqlalchemy/ext/instrumentation.py +450 -0
  128. sqlalchemy/ext/mutable.py +1085 -0
  129. sqlalchemy/ext/mypy/__init__.py +6 -0
  130. sqlalchemy/ext/mypy/apply.py +324 -0
  131. sqlalchemy/ext/mypy/decl_class.py +515 -0
  132. sqlalchemy/ext/mypy/infer.py +590 -0
  133. sqlalchemy/ext/mypy/names.py +335 -0
  134. sqlalchemy/ext/mypy/plugin.py +303 -0
  135. sqlalchemy/ext/mypy/util.py +357 -0
  136. sqlalchemy/ext/orderinglist.py +439 -0
  137. sqlalchemy/ext/serializer.py +185 -0
  138. sqlalchemy/future/__init__.py +16 -0
  139. sqlalchemy/future/engine.py +15 -0
  140. sqlalchemy/inspection.py +174 -0
  141. sqlalchemy/log.py +288 -0
  142. sqlalchemy/orm/__init__.py +171 -0
  143. sqlalchemy/orm/_orm_constructors.py +2661 -0
  144. sqlalchemy/orm/_typing.py +179 -0
  145. sqlalchemy/orm/attributes.py +2845 -0
  146. sqlalchemy/orm/base.py +971 -0
  147. sqlalchemy/orm/bulk_persistence.py +2135 -0
  148. sqlalchemy/orm/clsregistry.py +571 -0
  149. sqlalchemy/orm/collections.py +1627 -0
  150. sqlalchemy/orm/context.py +3334 -0
  151. sqlalchemy/orm/decl_api.py +2004 -0
  152. sqlalchemy/orm/decl_base.py +2192 -0
  153. sqlalchemy/orm/dependency.py +1302 -0
  154. sqlalchemy/orm/descriptor_props.py +1092 -0
  155. sqlalchemy/orm/dynamic.py +300 -0
  156. sqlalchemy/orm/evaluator.py +379 -0
  157. sqlalchemy/orm/events.py +3252 -0
  158. sqlalchemy/orm/exc.py +237 -0
  159. sqlalchemy/orm/identity.py +302 -0
  160. sqlalchemy/orm/instrumentation.py +754 -0
  161. sqlalchemy/orm/interfaces.py +1496 -0
  162. sqlalchemy/orm/loading.py +1686 -0
  163. sqlalchemy/orm/mapped_collection.py +557 -0
  164. sqlalchemy/orm/mapper.py +4444 -0
  165. sqlalchemy/orm/path_registry.py +809 -0
  166. sqlalchemy/orm/persistence.py +1788 -0
  167. sqlalchemy/orm/properties.py +935 -0
  168. sqlalchemy/orm/query.py +3459 -0
  169. sqlalchemy/orm/relationships.py +3508 -0
  170. sqlalchemy/orm/scoping.py +2148 -0
  171. sqlalchemy/orm/session.py +5280 -0
  172. sqlalchemy/orm/state.py +1168 -0
  173. sqlalchemy/orm/state_changes.py +196 -0
  174. sqlalchemy/orm/strategies.py +3470 -0
  175. sqlalchemy/orm/strategy_options.py +2568 -0
  176. sqlalchemy/orm/sync.py +164 -0
  177. sqlalchemy/orm/unitofwork.py +796 -0
  178. sqlalchemy/orm/util.py +2403 -0
  179. sqlalchemy/orm/writeonly.py +674 -0
  180. sqlalchemy/pool/__init__.py +44 -0
  181. sqlalchemy/pool/base.py +1524 -0
  182. sqlalchemy/pool/events.py +375 -0
  183. sqlalchemy/pool/impl.py +588 -0
  184. sqlalchemy/py.typed +0 -0
  185. sqlalchemy/schema.py +69 -0
  186. sqlalchemy/sql/__init__.py +145 -0
  187. sqlalchemy/sql/_dml_constructors.py +132 -0
  188. sqlalchemy/sql/_elements_constructors.py +1872 -0
  189. sqlalchemy/sql/_orm_types.py +20 -0
  190. sqlalchemy/sql/_py_util.py +75 -0
  191. sqlalchemy/sql/_selectable_constructors.py +763 -0
  192. sqlalchemy/sql/_typing.py +482 -0
  193. sqlalchemy/sql/annotation.py +587 -0
  194. sqlalchemy/sql/base.py +2293 -0
  195. sqlalchemy/sql/cache_key.py +1057 -0
  196. sqlalchemy/sql/coercions.py +1404 -0
  197. sqlalchemy/sql/compiler.py +8081 -0
  198. sqlalchemy/sql/crud.py +1752 -0
  199. sqlalchemy/sql/ddl.py +1444 -0
  200. sqlalchemy/sql/default_comparator.py +551 -0
  201. sqlalchemy/sql/dml.py +1850 -0
  202. sqlalchemy/sql/elements.py +5589 -0
  203. sqlalchemy/sql/events.py +458 -0
  204. sqlalchemy/sql/expression.py +159 -0
  205. sqlalchemy/sql/functions.py +2158 -0
  206. sqlalchemy/sql/lambdas.py +1442 -0
  207. sqlalchemy/sql/naming.py +209 -0
  208. sqlalchemy/sql/operators.py +2623 -0
  209. sqlalchemy/sql/roles.py +323 -0
  210. sqlalchemy/sql/schema.py +6222 -0
  211. sqlalchemy/sql/selectable.py +7265 -0
  212. sqlalchemy/sql/sqltypes.py +3930 -0
  213. sqlalchemy/sql/traversals.py +1024 -0
  214. sqlalchemy/sql/type_api.py +2368 -0
  215. sqlalchemy/sql/util.py +1485 -0
  216. sqlalchemy/sql/visitors.py +1164 -0
  217. sqlalchemy/testing/__init__.py +96 -0
  218. sqlalchemy/testing/assertions.py +994 -0
  219. sqlalchemy/testing/assertsql.py +520 -0
  220. sqlalchemy/testing/asyncio.py +135 -0
  221. sqlalchemy/testing/config.py +434 -0
  222. sqlalchemy/testing/engines.py +483 -0
  223. sqlalchemy/testing/entities.py +117 -0
  224. sqlalchemy/testing/exclusions.py +476 -0
  225. sqlalchemy/testing/fixtures/__init__.py +28 -0
  226. sqlalchemy/testing/fixtures/base.py +384 -0
  227. sqlalchemy/testing/fixtures/mypy.py +332 -0
  228. sqlalchemy/testing/fixtures/orm.py +227 -0
  229. sqlalchemy/testing/fixtures/sql.py +482 -0
  230. sqlalchemy/testing/pickleable.py +155 -0
  231. sqlalchemy/testing/plugin/__init__.py +6 -0
  232. sqlalchemy/testing/plugin/bootstrap.py +51 -0
  233. sqlalchemy/testing/plugin/plugin_base.py +828 -0
  234. sqlalchemy/testing/plugin/pytestplugin.py +892 -0
  235. sqlalchemy/testing/profiling.py +329 -0
  236. sqlalchemy/testing/provision.py +603 -0
  237. sqlalchemy/testing/requirements.py +1945 -0
  238. sqlalchemy/testing/schema.py +198 -0
  239. sqlalchemy/testing/suite/__init__.py +19 -0
  240. sqlalchemy/testing/suite/test_cte.py +237 -0
  241. sqlalchemy/testing/suite/test_ddl.py +389 -0
  242. sqlalchemy/testing/suite/test_deprecations.py +153 -0
  243. sqlalchemy/testing/suite/test_dialect.py +776 -0
  244. sqlalchemy/testing/suite/test_insert.py +630 -0
  245. sqlalchemy/testing/suite/test_reflection.py +3557 -0
  246. sqlalchemy/testing/suite/test_results.py +504 -0
  247. sqlalchemy/testing/suite/test_rowcount.py +258 -0
  248. sqlalchemy/testing/suite/test_select.py +2010 -0
  249. sqlalchemy/testing/suite/test_sequence.py +317 -0
  250. sqlalchemy/testing/suite/test_types.py +2147 -0
  251. sqlalchemy/testing/suite/test_unicode_ddl.py +189 -0
  252. sqlalchemy/testing/suite/test_update_delete.py +139 -0
  253. sqlalchemy/testing/util.py +535 -0
  254. sqlalchemy/testing/warnings.py +52 -0
  255. sqlalchemy/types.py +74 -0
  256. sqlalchemy/util/__init__.py +162 -0
  257. sqlalchemy/util/_collections.py +712 -0
  258. sqlalchemy/util/_concurrency_py3k.py +288 -0
  259. sqlalchemy/util/_has_cy.py +40 -0
  260. sqlalchemy/util/_py_collections.py +541 -0
  261. sqlalchemy/util/compat.py +421 -0
  262. sqlalchemy/util/concurrency.py +110 -0
  263. sqlalchemy/util/deprecations.py +401 -0
  264. sqlalchemy/util/langhelpers.py +2203 -0
  265. sqlalchemy/util/preloaded.py +150 -0
  266. sqlalchemy/util/queue.py +322 -0
  267. sqlalchemy/util/tool_support.py +201 -0
  268. sqlalchemy/util/topological.py +120 -0
  269. sqlalchemy/util/typing.py +734 -0
  270. sqlalchemy-2.0.47.dist-info/METADATA +243 -0
  271. sqlalchemy-2.0.47.dist-info/RECORD +274 -0
  272. sqlalchemy-2.0.47.dist-info/WHEEL +5 -0
  273. sqlalchemy-2.0.47.dist-info/licenses/LICENSE +19 -0
  274. sqlalchemy-2.0.47.dist-info/top_level.txt +1 -0
@@ -0,0 +1,174 @@
1
+ # inspection.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 inspection module provides the :func:`_sa.inspect` function,
9
+ which delivers runtime information about a wide variety
10
+ of SQLAlchemy objects, both within the Core as well as the
11
+ ORM.
12
+
13
+ The :func:`_sa.inspect` function is the entry point to SQLAlchemy's
14
+ public API for viewing the configuration and construction
15
+ of in-memory objects. Depending on the type of object
16
+ passed to :func:`_sa.inspect`, the return value will either be
17
+ a related object which provides a known interface, or in many
18
+ cases it will return the object itself.
19
+
20
+ The rationale for :func:`_sa.inspect` is twofold. One is that
21
+ it replaces the need to be aware of a large variety of "information
22
+ getting" functions in SQLAlchemy, such as
23
+ :meth:`_reflection.Inspector.from_engine` (deprecated in 1.4),
24
+ :func:`.orm.attributes.instance_state`, :func:`_orm.class_mapper`,
25
+ and others. The other is that the return value of :func:`_sa.inspect`
26
+ is guaranteed to obey a documented API, thus allowing third party
27
+ tools which build on top of SQLAlchemy configurations to be constructed
28
+ in a forwards-compatible way.
29
+
30
+ """
31
+ from __future__ import annotations
32
+
33
+ from typing import Any
34
+ from typing import Callable
35
+ from typing import Dict
36
+ from typing import Generic
37
+ from typing import Optional
38
+ from typing import overload
39
+ from typing import Type
40
+ from typing import TypeVar
41
+ from typing import Union
42
+
43
+ from . import exc
44
+ from .util.typing import Literal
45
+ from .util.typing import Protocol
46
+
47
+ _T = TypeVar("_T", bound=Any)
48
+ _TCov = TypeVar("_TCov", bound=Any, covariant=True)
49
+ _F = TypeVar("_F", bound=Callable[..., Any])
50
+
51
+ _IN = TypeVar("_IN", bound=Any)
52
+
53
+ _registrars: Dict[type, Union[Literal[True], Callable[[Any], Any]]] = {}
54
+
55
+
56
+ class Inspectable(Generic[_T]):
57
+ """define a class as inspectable.
58
+
59
+ This allows typing to set up a linkage between an object that
60
+ can be inspected and the type of inspection it returns.
61
+
62
+ Unfortunately we cannot at the moment get all classes that are
63
+ returned by inspection to suit this interface as we get into
64
+ MRO issues.
65
+
66
+ """
67
+
68
+ __slots__ = ()
69
+
70
+
71
+ class _InspectableTypeProtocol(Protocol[_TCov]):
72
+ """a protocol defining a method that's used when a type (ie the class
73
+ itself) is passed to inspect().
74
+
75
+ """
76
+
77
+ def _sa_inspect_type(self) -> _TCov: ...
78
+
79
+
80
+ class _InspectableProtocol(Protocol[_TCov]):
81
+ """a protocol defining a method that's used when an instance is
82
+ passed to inspect().
83
+
84
+ """
85
+
86
+ def _sa_inspect_instance(self) -> _TCov: ...
87
+
88
+
89
+ @overload
90
+ def inspect(
91
+ subject: Type[_InspectableTypeProtocol[_IN]], raiseerr: bool = True
92
+ ) -> _IN: ...
93
+
94
+
95
+ @overload
96
+ def inspect(
97
+ subject: _InspectableProtocol[_IN], raiseerr: bool = True
98
+ ) -> _IN: ...
99
+
100
+
101
+ @overload
102
+ def inspect(subject: Inspectable[_IN], raiseerr: bool = True) -> _IN: ...
103
+
104
+
105
+ @overload
106
+ def inspect(subject: Any, raiseerr: Literal[False] = ...) -> Optional[Any]: ...
107
+
108
+
109
+ @overload
110
+ def inspect(subject: Any, raiseerr: bool = True) -> Any: ...
111
+
112
+
113
+ def inspect(subject: Any, raiseerr: bool = True) -> Any:
114
+ """Produce an inspection object for the given target.
115
+
116
+ The returned value in some cases may be the
117
+ same object as the one given, such as if a
118
+ :class:`_orm.Mapper` object is passed. In other
119
+ cases, it will be an instance of the registered
120
+ inspection type for the given object, such as
121
+ if an :class:`_engine.Engine` is passed, an
122
+ :class:`_reflection.Inspector` object is returned.
123
+
124
+ :param subject: the subject to be inspected.
125
+ :param raiseerr: When ``True``, if the given subject
126
+ does not
127
+ correspond to a known SQLAlchemy inspected type,
128
+ :class:`sqlalchemy.exc.NoInspectionAvailable`
129
+ is raised. If ``False``, ``None`` is returned.
130
+
131
+ """
132
+ type_ = type(subject)
133
+ for cls in type_.__mro__:
134
+ if cls in _registrars:
135
+ reg = _registrars.get(cls, None)
136
+ if reg is None:
137
+ continue
138
+ elif reg is True:
139
+ return subject
140
+ ret = reg(subject)
141
+ if ret is not None:
142
+ return ret
143
+ else:
144
+ reg = ret = None
145
+
146
+ if raiseerr and (reg is None or ret is None):
147
+ raise exc.NoInspectionAvailable(
148
+ "No inspection system is "
149
+ "available for object of type %s" % type_
150
+ )
151
+ return ret
152
+
153
+
154
+ def _inspects(
155
+ *types: Type[Any],
156
+ ) -> Callable[[_F], _F]:
157
+ def decorate(fn_or_cls: _F) -> _F:
158
+ for type_ in types:
159
+ if type_ in _registrars:
160
+ raise AssertionError("Type %s is already registered" % type_)
161
+ _registrars[type_] = fn_or_cls
162
+ return fn_or_cls
163
+
164
+ return decorate
165
+
166
+
167
+ _TT = TypeVar("_TT", bound="Type[Any]")
168
+
169
+
170
+ def _self_inspects(cls: _TT) -> _TT:
171
+ if cls in _registrars:
172
+ raise AssertionError("Type %s is already registered" % cls)
173
+ _registrars[cls] = True
174
+ return cls
sqlalchemy/log.py ADDED
@@ -0,0 +1,288 @@
1
+ # log.py
2
+ # Copyright (C) 2006-2026 the SQLAlchemy authors and contributors
3
+ # <see AUTHORS file>
4
+ # Includes alterations by Vinay Sajip vinay_sajip@yahoo.co.uk
5
+ #
6
+ # This module is part of SQLAlchemy and is released under
7
+ # the MIT License: https://www.opensource.org/licenses/mit-license.php
8
+
9
+ """Logging control and utilities.
10
+
11
+ Control of logging for SA can be performed from the regular python logging
12
+ module. The regular dotted module namespace is used, starting at
13
+ 'sqlalchemy'. For class-level logging, the class name is appended.
14
+
15
+ The "echo" keyword parameter, available on SQLA :class:`_engine.Engine`
16
+ and :class:`_pool.Pool` objects, corresponds to a logger specific to that
17
+ instance only.
18
+
19
+ """
20
+ from __future__ import annotations
21
+
22
+ import logging
23
+ import sys
24
+ from typing import Any
25
+ from typing import Optional
26
+ from typing import overload
27
+ from typing import Set
28
+ from typing import Type
29
+ from typing import TypeVar
30
+ from typing import Union
31
+
32
+ from .util import py311
33
+ from .util import py38
34
+ from .util.typing import Literal
35
+
36
+
37
+ if py38:
38
+ STACKLEVEL = True
39
+ # needed as of py3.11.0b1
40
+ # #8019
41
+ STACKLEVEL_OFFSET = 2 if py311 else 1
42
+ else:
43
+ STACKLEVEL = False
44
+ STACKLEVEL_OFFSET = 0
45
+
46
+ _IT = TypeVar("_IT", bound="Identified")
47
+
48
+ _EchoFlagType = Union[None, bool, Literal["debug"]]
49
+
50
+ # set initial level to WARN. This so that
51
+ # log statements don't occur in the absence of explicit
52
+ # logging being enabled for 'sqlalchemy'.
53
+ rootlogger = logging.getLogger("sqlalchemy")
54
+ if rootlogger.level == logging.NOTSET:
55
+ rootlogger.setLevel(logging.WARN)
56
+
57
+
58
+ def _add_default_handler(logger: logging.Logger) -> None:
59
+ handler = logging.StreamHandler(sys.stdout)
60
+ handler.setFormatter(
61
+ logging.Formatter("%(asctime)s %(levelname)s %(name)s %(message)s")
62
+ )
63
+ logger.addHandler(handler)
64
+
65
+
66
+ _logged_classes: Set[Type[Identified]] = set()
67
+
68
+
69
+ def _qual_logger_name_for_cls(cls: Type[Identified]) -> str:
70
+ return (
71
+ getattr(cls, "_sqla_logger_namespace", None)
72
+ or cls.__module__ + "." + cls.__name__
73
+ )
74
+
75
+
76
+ def class_logger(cls: Type[_IT]) -> Type[_IT]:
77
+ logger = logging.getLogger(_qual_logger_name_for_cls(cls))
78
+ cls._should_log_debug = lambda self: logger.isEnabledFor( # type: ignore[method-assign] # noqa: E501
79
+ logging.DEBUG
80
+ )
81
+ cls._should_log_info = lambda self: logger.isEnabledFor( # type: ignore[method-assign] # noqa: E501
82
+ logging.INFO
83
+ )
84
+ cls.logger = logger
85
+ _logged_classes.add(cls)
86
+ return cls
87
+
88
+
89
+ _IdentifiedLoggerType = Union[logging.Logger, "InstanceLogger"]
90
+
91
+
92
+ class Identified:
93
+ __slots__ = ()
94
+
95
+ logging_name: Optional[str] = None
96
+
97
+ logger: _IdentifiedLoggerType
98
+
99
+ _echo: _EchoFlagType
100
+
101
+ def _should_log_debug(self) -> bool:
102
+ return self.logger.isEnabledFor(logging.DEBUG)
103
+
104
+ def _should_log_info(self) -> bool:
105
+ return self.logger.isEnabledFor(logging.INFO)
106
+
107
+
108
+ class InstanceLogger:
109
+ """A logger adapter (wrapper) for :class:`.Identified` subclasses.
110
+
111
+ This allows multiple instances (e.g. Engine or Pool instances)
112
+ to share a logger, but have its verbosity controlled on a
113
+ per-instance basis.
114
+
115
+ The basic functionality is to return a logging level
116
+ which is based on an instance's echo setting.
117
+
118
+ Default implementation is:
119
+
120
+ 'debug' -> logging.DEBUG
121
+ True -> logging.INFO
122
+ False -> Effective level of underlying logger (
123
+ logging.WARNING by default)
124
+ None -> same as False
125
+ """
126
+
127
+ # Map echo settings to logger levels
128
+ _echo_map = {
129
+ None: logging.NOTSET,
130
+ False: logging.NOTSET,
131
+ True: logging.INFO,
132
+ "debug": logging.DEBUG,
133
+ }
134
+
135
+ _echo: _EchoFlagType
136
+
137
+ __slots__ = ("echo", "logger")
138
+
139
+ def __init__(self, echo: _EchoFlagType, name: str):
140
+ self.echo = echo
141
+ self.logger = logging.getLogger(name)
142
+
143
+ # if echo flag is enabled and no handlers,
144
+ # add a handler to the list
145
+ if self._echo_map[echo] <= logging.INFO and not self.logger.handlers:
146
+ _add_default_handler(self.logger)
147
+
148
+ #
149
+ # Boilerplate convenience methods
150
+ #
151
+ def debug(self, msg: str, *args: Any, **kwargs: Any) -> None:
152
+ """Delegate a debug call to the underlying logger."""
153
+
154
+ self.log(logging.DEBUG, msg, *args, **kwargs)
155
+
156
+ def info(self, msg: str, *args: Any, **kwargs: Any) -> None:
157
+ """Delegate an info call to the underlying logger."""
158
+
159
+ self.log(logging.INFO, msg, *args, **kwargs)
160
+
161
+ def warning(self, msg: str, *args: Any, **kwargs: Any) -> None:
162
+ """Delegate a warning call to the underlying logger."""
163
+
164
+ self.log(logging.WARNING, msg, *args, **kwargs)
165
+
166
+ warn = warning
167
+
168
+ def error(self, msg: str, *args: Any, **kwargs: Any) -> None:
169
+ """
170
+ Delegate an error call to the underlying logger.
171
+ """
172
+ self.log(logging.ERROR, msg, *args, **kwargs)
173
+
174
+ def exception(self, msg: str, *args: Any, **kwargs: Any) -> None:
175
+ """Delegate an exception call to the underlying logger."""
176
+
177
+ kwargs["exc_info"] = 1
178
+ self.log(logging.ERROR, msg, *args, **kwargs)
179
+
180
+ def critical(self, msg: str, *args: Any, **kwargs: Any) -> None:
181
+ """Delegate a critical call to the underlying logger."""
182
+
183
+ self.log(logging.CRITICAL, msg, *args, **kwargs)
184
+
185
+ def log(self, level: int, msg: str, *args: Any, **kwargs: Any) -> None:
186
+ """Delegate a log call to the underlying logger.
187
+
188
+ The level here is determined by the echo
189
+ flag as well as that of the underlying logger, and
190
+ logger._log() is called directly.
191
+
192
+ """
193
+
194
+ # inline the logic from isEnabledFor(),
195
+ # getEffectiveLevel(), to avoid overhead.
196
+
197
+ if self.logger.manager.disable >= level:
198
+ return
199
+
200
+ selected_level = self._echo_map[self.echo]
201
+ if selected_level == logging.NOTSET:
202
+ selected_level = self.logger.getEffectiveLevel()
203
+
204
+ if level >= selected_level:
205
+ if STACKLEVEL:
206
+ kwargs["stacklevel"] = (
207
+ kwargs.get("stacklevel", 1) + STACKLEVEL_OFFSET
208
+ )
209
+
210
+ self.logger._log(level, msg, args, **kwargs)
211
+
212
+ def isEnabledFor(self, level: int) -> bool:
213
+ """Is this logger enabled for level 'level'?"""
214
+
215
+ if self.logger.manager.disable >= level:
216
+ return False
217
+ return level >= self.getEffectiveLevel()
218
+
219
+ def getEffectiveLevel(self) -> int:
220
+ """What's the effective level for this logger?"""
221
+
222
+ level = self._echo_map[self.echo]
223
+ if level == logging.NOTSET:
224
+ level = self.logger.getEffectiveLevel()
225
+ return level
226
+
227
+
228
+ def instance_logger(
229
+ instance: Identified, echoflag: _EchoFlagType = None
230
+ ) -> None:
231
+ """create a logger for an instance that implements :class:`.Identified`."""
232
+
233
+ if instance.logging_name:
234
+ name = "%s.%s" % (
235
+ _qual_logger_name_for_cls(instance.__class__),
236
+ instance.logging_name,
237
+ )
238
+ else:
239
+ name = _qual_logger_name_for_cls(instance.__class__)
240
+
241
+ instance._echo = echoflag # type: ignore
242
+
243
+ logger: Union[logging.Logger, InstanceLogger]
244
+
245
+ if echoflag in (False, None):
246
+ # if no echo setting or False, return a Logger directly,
247
+ # avoiding overhead of filtering
248
+ logger = logging.getLogger(name)
249
+ else:
250
+ # if a specified echo flag, return an EchoLogger,
251
+ # which checks the flag, overrides normal log
252
+ # levels by calling logger._log()
253
+ logger = InstanceLogger(echoflag, name)
254
+
255
+ instance.logger = logger # type: ignore
256
+
257
+
258
+ class echo_property:
259
+ __doc__ = """\
260
+ When ``True``, enable log output for this element.
261
+
262
+ This has the effect of setting the Python logging level for the namespace
263
+ of this element's class and object reference. A value of boolean ``True``
264
+ indicates that the loglevel ``logging.INFO`` will be set for the logger,
265
+ whereas the string value ``debug`` will set the loglevel to
266
+ ``logging.DEBUG``.
267
+ """
268
+
269
+ @overload
270
+ def __get__(
271
+ self, instance: Literal[None], owner: Type[Identified]
272
+ ) -> echo_property: ...
273
+
274
+ @overload
275
+ def __get__(
276
+ self, instance: Identified, owner: Type[Identified]
277
+ ) -> _EchoFlagType: ...
278
+
279
+ def __get__(
280
+ self, instance: Optional[Identified], owner: Type[Identified]
281
+ ) -> Union[echo_property, _EchoFlagType]:
282
+ if instance is None:
283
+ return self
284
+ else:
285
+ return instance._echo
286
+
287
+ def __set__(self, instance: Identified, value: _EchoFlagType) -> None:
288
+ instance_logger(instance, echoflag=value)
@@ -0,0 +1,171 @@
1
+ # orm/__init__.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
+ """
9
+ Functional constructs for ORM configuration.
10
+
11
+ See the SQLAlchemy object relational tutorial and mapper configuration
12
+ documentation for an overview of how this module is used.
13
+
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ from typing import Any
19
+
20
+ from . import exc as exc
21
+ from . import mapper as mapperlib
22
+ from . import strategy_options as strategy_options
23
+ from ._orm_constructors import _mapper_fn as mapper
24
+ from ._orm_constructors import aliased as aliased
25
+ from ._orm_constructors import backref as backref
26
+ from ._orm_constructors import clear_mappers as clear_mappers
27
+ from ._orm_constructors import column_property as column_property
28
+ from ._orm_constructors import composite as composite
29
+ from ._orm_constructors import contains_alias as contains_alias
30
+ from ._orm_constructors import create_session as create_session
31
+ from ._orm_constructors import deferred as deferred
32
+ from ._orm_constructors import dynamic_loader as dynamic_loader
33
+ from ._orm_constructors import join as join
34
+ from ._orm_constructors import mapped_column as mapped_column
35
+ from ._orm_constructors import orm_insert_sentinel as orm_insert_sentinel
36
+ from ._orm_constructors import outerjoin as outerjoin
37
+ from ._orm_constructors import query_expression as query_expression
38
+ from ._orm_constructors import relationship as relationship
39
+ from ._orm_constructors import synonym as synonym
40
+ from ._orm_constructors import with_loader_criteria as with_loader_criteria
41
+ from ._orm_constructors import with_polymorphic as with_polymorphic
42
+ from .attributes import AttributeEventToken as AttributeEventToken
43
+ from .attributes import InstrumentedAttribute as InstrumentedAttribute
44
+ from .attributes import QueryableAttribute as QueryableAttribute
45
+ from .base import class_mapper as class_mapper
46
+ from .base import DynamicMapped as DynamicMapped
47
+ from .base import InspectionAttrExtensionType as InspectionAttrExtensionType
48
+ from .base import LoaderCallableStatus as LoaderCallableStatus
49
+ from .base import Mapped as Mapped
50
+ from .base import NotExtension as NotExtension
51
+ from .base import ORMDescriptor as ORMDescriptor
52
+ from .base import PassiveFlag as PassiveFlag
53
+ from .base import SQLORMExpression as SQLORMExpression
54
+ from .base import WriteOnlyMapped as WriteOnlyMapped
55
+ from .context import FromStatement as FromStatement
56
+ from .context import QueryContext as QueryContext
57
+ from .decl_api import add_mapped_attribute as add_mapped_attribute
58
+ from .decl_api import as_declarative as as_declarative
59
+ from .decl_api import declarative_base as declarative_base
60
+ from .decl_api import declarative_mixin as declarative_mixin
61
+ from .decl_api import DeclarativeBase as DeclarativeBase
62
+ from .decl_api import DeclarativeBaseNoMeta as DeclarativeBaseNoMeta
63
+ from .decl_api import DeclarativeMeta as DeclarativeMeta
64
+ from .decl_api import declared_attr as declared_attr
65
+ from .decl_api import has_inherited_table as has_inherited_table
66
+ from .decl_api import mapped_as_dataclass as mapped_as_dataclass
67
+ from .decl_api import MappedAsDataclass as MappedAsDataclass
68
+ from .decl_api import registry as registry
69
+ from .decl_api import synonym_for as synonym_for
70
+ from .decl_base import MappedClassProtocol as MappedClassProtocol
71
+ from .descriptor_props import Composite as Composite
72
+ from .descriptor_props import CompositeProperty as CompositeProperty
73
+ from .descriptor_props import Synonym as Synonym
74
+ from .descriptor_props import SynonymProperty as SynonymProperty
75
+ from .dynamic import AppenderQuery as AppenderQuery
76
+ from .events import AttributeEvents as AttributeEvents
77
+ from .events import InstanceEvents as InstanceEvents
78
+ from .events import InstrumentationEvents as InstrumentationEvents
79
+ from .events import MapperEvents as MapperEvents
80
+ from .events import QueryEvents as QueryEvents
81
+ from .events import SessionEvents as SessionEvents
82
+ from .identity import IdentityMap as IdentityMap
83
+ from .instrumentation import ClassManager as ClassManager
84
+ from .interfaces import EXT_CONTINUE as EXT_CONTINUE
85
+ from .interfaces import EXT_SKIP as EXT_SKIP
86
+ from .interfaces import EXT_STOP as EXT_STOP
87
+ from .interfaces import InspectionAttr as InspectionAttr
88
+ from .interfaces import InspectionAttrInfo as InspectionAttrInfo
89
+ from .interfaces import MANYTOMANY as MANYTOMANY
90
+ from .interfaces import MANYTOONE as MANYTOONE
91
+ from .interfaces import MapperProperty as MapperProperty
92
+ from .interfaces import NO_KEY as NO_KEY
93
+ from .interfaces import NO_VALUE as NO_VALUE
94
+ from .interfaces import ONETOMANY as ONETOMANY
95
+ from .interfaces import PropComparator as PropComparator
96
+ from .interfaces import RelationshipDirection as RelationshipDirection
97
+ from .interfaces import UserDefinedOption as UserDefinedOption
98
+ from .loading import merge_frozen_result as merge_frozen_result
99
+ from .loading import merge_result as merge_result
100
+ from .mapped_collection import attribute_keyed_dict as attribute_keyed_dict
101
+ from .mapped_collection import (
102
+ attribute_mapped_collection as attribute_mapped_collection,
103
+ )
104
+ from .mapped_collection import column_keyed_dict as column_keyed_dict
105
+ from .mapped_collection import (
106
+ column_mapped_collection as column_mapped_collection,
107
+ )
108
+ from .mapped_collection import keyfunc_mapping as keyfunc_mapping
109
+ from .mapped_collection import KeyFuncDict as KeyFuncDict
110
+ from .mapped_collection import mapped_collection as mapped_collection
111
+ from .mapped_collection import MappedCollection as MappedCollection
112
+ from .mapper import configure_mappers as configure_mappers
113
+ from .mapper import Mapper as Mapper
114
+ from .mapper import reconstructor as reconstructor
115
+ from .mapper import validates as validates
116
+ from .properties import ColumnProperty as ColumnProperty
117
+ from .properties import MappedColumn as MappedColumn
118
+ from .properties import MappedSQLExpression as MappedSQLExpression
119
+ from .query import AliasOption as AliasOption
120
+ from .query import Query as Query
121
+ from .relationships import foreign as foreign
122
+ from .relationships import Relationship as Relationship
123
+ from .relationships import RelationshipProperty as RelationshipProperty
124
+ from .relationships import remote as remote
125
+ from .scoping import QueryPropertyDescriptor as QueryPropertyDescriptor
126
+ from .scoping import scoped_session as scoped_session
127
+ from .session import close_all_sessions as close_all_sessions
128
+ from .session import make_transient as make_transient
129
+ from .session import make_transient_to_detached as make_transient_to_detached
130
+ from .session import object_session as object_session
131
+ from .session import ORMExecuteState as ORMExecuteState
132
+ from .session import Session as Session
133
+ from .session import sessionmaker as sessionmaker
134
+ from .session import SessionTransaction as SessionTransaction
135
+ from .session import SessionTransactionOrigin as SessionTransactionOrigin
136
+ from .state import AttributeState as AttributeState
137
+ from .state import InstanceState as InstanceState
138
+ from .strategy_options import contains_eager as contains_eager
139
+ from .strategy_options import defaultload as defaultload
140
+ from .strategy_options import defer as defer
141
+ from .strategy_options import immediateload as immediateload
142
+ from .strategy_options import joinedload as joinedload
143
+ from .strategy_options import lazyload as lazyload
144
+ from .strategy_options import Load as Load
145
+ from .strategy_options import load_only as load_only
146
+ from .strategy_options import noload as noload
147
+ from .strategy_options import raiseload as raiseload
148
+ from .strategy_options import selectin_polymorphic as selectin_polymorphic
149
+ from .strategy_options import selectinload as selectinload
150
+ from .strategy_options import subqueryload as subqueryload
151
+ from .strategy_options import undefer as undefer
152
+ from .strategy_options import undefer_group as undefer_group
153
+ from .strategy_options import with_expression as with_expression
154
+ from .unitofwork import UOWTransaction as UOWTransaction
155
+ from .util import Bundle as Bundle
156
+ from .util import CascadeOptions as CascadeOptions
157
+ from .util import LoaderCriteriaOption as LoaderCriteriaOption
158
+ from .util import object_mapper as object_mapper
159
+ from .util import polymorphic_union as polymorphic_union
160
+ from .util import was_deleted as was_deleted
161
+ from .util import with_parent as with_parent
162
+ from .writeonly import WriteOnlyCollection as WriteOnlyCollection
163
+ from .. import util as _sa_util
164
+
165
+
166
+ def __go(lcls: Any) -> None:
167
+ _sa_util.preloaded.import_prefix("sqlalchemy.orm")
168
+ _sa_util.preloaded.import_prefix("sqlalchemy.ext")
169
+
170
+
171
+ __go(locals())