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.
- sqlalchemy/__init__.py +298 -0
- sqlalchemy/connectors/__init__.py +18 -0
- sqlalchemy/connectors/aioodbc.py +171 -0
- sqlalchemy/connectors/asyncio.py +476 -0
- sqlalchemy/connectors/pyodbc.py +250 -0
- sqlalchemy/dialects/__init__.py +62 -0
- sqlalchemy/dialects/_typing.py +30 -0
- sqlalchemy/dialects/mssql/__init__.py +89 -0
- sqlalchemy/dialects/mssql/aioodbc.py +63 -0
- sqlalchemy/dialects/mssql/base.py +4166 -0
- sqlalchemy/dialects/mssql/information_schema.py +285 -0
- sqlalchemy/dialects/mssql/json.py +140 -0
- sqlalchemy/dialects/mssql/mssqlpython.py +220 -0
- sqlalchemy/dialects/mssql/provision.py +196 -0
- sqlalchemy/dialects/mssql/pymssql.py +126 -0
- sqlalchemy/dialects/mssql/pyodbc.py +698 -0
- sqlalchemy/dialects/mysql/__init__.py +106 -0
- sqlalchemy/dialects/mysql/_mariadb_shim.py +312 -0
- sqlalchemy/dialects/mysql/aiomysql.py +226 -0
- sqlalchemy/dialects/mysql/asyncmy.py +214 -0
- sqlalchemy/dialects/mysql/base.py +3877 -0
- sqlalchemy/dialects/mysql/cymysql.py +106 -0
- sqlalchemy/dialects/mysql/dml.py +279 -0
- sqlalchemy/dialects/mysql/enumerated.py +277 -0
- sqlalchemy/dialects/mysql/expression.py +146 -0
- sqlalchemy/dialects/mysql/json.py +92 -0
- sqlalchemy/dialects/mysql/mariadb.py +67 -0
- sqlalchemy/dialects/mysql/mariadbconnector.py +330 -0
- sqlalchemy/dialects/mysql/mysqlconnector.py +296 -0
- sqlalchemy/dialects/mysql/mysqldb.py +312 -0
- sqlalchemy/dialects/mysql/provision.py +153 -0
- sqlalchemy/dialects/mysql/pymysql.py +157 -0
- sqlalchemy/dialects/mysql/pyodbc.py +156 -0
- sqlalchemy/dialects/mysql/reflection.py +724 -0
- sqlalchemy/dialects/mysql/reserved_words.py +570 -0
- sqlalchemy/dialects/mysql/types.py +845 -0
- sqlalchemy/dialects/oracle/__init__.py +85 -0
- sqlalchemy/dialects/oracle/base.py +3977 -0
- sqlalchemy/dialects/oracle/cx_oracle.py +1601 -0
- sqlalchemy/dialects/oracle/dictionary.py +507 -0
- sqlalchemy/dialects/oracle/json.py +158 -0
- sqlalchemy/dialects/oracle/oracledb.py +909 -0
- sqlalchemy/dialects/oracle/provision.py +288 -0
- sqlalchemy/dialects/oracle/types.py +367 -0
- sqlalchemy/dialects/oracle/vector.py +368 -0
- sqlalchemy/dialects/postgresql/__init__.py +171 -0
- sqlalchemy/dialects/postgresql/_psycopg_common.py +229 -0
- sqlalchemy/dialects/postgresql/array.py +534 -0
- sqlalchemy/dialects/postgresql/asyncpg.py +1323 -0
- sqlalchemy/dialects/postgresql/base.py +5789 -0
- sqlalchemy/dialects/postgresql/bitstring.py +327 -0
- sqlalchemy/dialects/postgresql/dml.py +360 -0
- sqlalchemy/dialects/postgresql/ext.py +593 -0
- sqlalchemy/dialects/postgresql/hstore.py +423 -0
- sqlalchemy/dialects/postgresql/json.py +408 -0
- sqlalchemy/dialects/postgresql/named_types.py +521 -0
- sqlalchemy/dialects/postgresql/operators.py +130 -0
- sqlalchemy/dialects/postgresql/pg8000.py +670 -0
- sqlalchemy/dialects/postgresql/pg_catalog.py +344 -0
- sqlalchemy/dialects/postgresql/provision.py +184 -0
- sqlalchemy/dialects/postgresql/psycopg.py +799 -0
- sqlalchemy/dialects/postgresql/psycopg2.py +860 -0
- sqlalchemy/dialects/postgresql/psycopg2cffi.py +61 -0
- sqlalchemy/dialects/postgresql/ranges.py +1002 -0
- sqlalchemy/dialects/postgresql/types.py +388 -0
- sqlalchemy/dialects/sqlite/__init__.py +57 -0
- sqlalchemy/dialects/sqlite/aiosqlite.py +321 -0
- sqlalchemy/dialects/sqlite/base.py +3063 -0
- sqlalchemy/dialects/sqlite/dml.py +279 -0
- sqlalchemy/dialects/sqlite/json.py +100 -0
- sqlalchemy/dialects/sqlite/provision.py +229 -0
- sqlalchemy/dialects/sqlite/pysqlcipher.py +161 -0
- sqlalchemy/dialects/sqlite/pysqlite.py +754 -0
- sqlalchemy/dialects/type_migration_guidelines.txt +145 -0
- sqlalchemy/engine/__init__.py +62 -0
- sqlalchemy/engine/_processors_cy.cp313t-win_arm64.pyd +0 -0
- sqlalchemy/engine/_processors_cy.py +92 -0
- sqlalchemy/engine/_result_cy.cp313t-win_arm64.pyd +0 -0
- sqlalchemy/engine/_result_cy.py +633 -0
- sqlalchemy/engine/_row_cy.cp313t-win_arm64.pyd +0 -0
- sqlalchemy/engine/_row_cy.py +232 -0
- sqlalchemy/engine/_util_cy.cp313t-win_arm64.pyd +0 -0
- sqlalchemy/engine/_util_cy.py +136 -0
- sqlalchemy/engine/base.py +3354 -0
- sqlalchemy/engine/characteristics.py +155 -0
- sqlalchemy/engine/create.py +877 -0
- sqlalchemy/engine/cursor.py +2421 -0
- sqlalchemy/engine/default.py +2402 -0
- sqlalchemy/engine/events.py +965 -0
- sqlalchemy/engine/interfaces.py +3495 -0
- sqlalchemy/engine/mock.py +134 -0
- sqlalchemy/engine/processors.py +82 -0
- sqlalchemy/engine/reflection.py +2100 -0
- sqlalchemy/engine/result.py +1966 -0
- sqlalchemy/engine/row.py +397 -0
- sqlalchemy/engine/strategies.py +16 -0
- sqlalchemy/engine/url.py +922 -0
- sqlalchemy/engine/util.py +156 -0
- sqlalchemy/event/__init__.py +26 -0
- sqlalchemy/event/api.py +220 -0
- sqlalchemy/event/attr.py +674 -0
- sqlalchemy/event/base.py +472 -0
- sqlalchemy/event/legacy.py +258 -0
- sqlalchemy/event/registry.py +390 -0
- sqlalchemy/events.py +17 -0
- sqlalchemy/exc.py +922 -0
- sqlalchemy/ext/__init__.py +11 -0
- sqlalchemy/ext/associationproxy.py +2072 -0
- sqlalchemy/ext/asyncio/__init__.py +29 -0
- sqlalchemy/ext/asyncio/base.py +281 -0
- sqlalchemy/ext/asyncio/engine.py +1487 -0
- sqlalchemy/ext/asyncio/exc.py +21 -0
- sqlalchemy/ext/asyncio/result.py +994 -0
- sqlalchemy/ext/asyncio/scoping.py +1679 -0
- sqlalchemy/ext/asyncio/session.py +2007 -0
- sqlalchemy/ext/automap.py +1701 -0
- sqlalchemy/ext/baked.py +559 -0
- sqlalchemy/ext/compiler.py +600 -0
- sqlalchemy/ext/declarative/__init__.py +65 -0
- sqlalchemy/ext/declarative/extensions.py +560 -0
- sqlalchemy/ext/horizontal_shard.py +481 -0
- sqlalchemy/ext/hybrid.py +1877 -0
- sqlalchemy/ext/indexable.py +364 -0
- sqlalchemy/ext/instrumentation.py +450 -0
- sqlalchemy/ext/mutable.py +1081 -0
- sqlalchemy/ext/orderinglist.py +439 -0
- sqlalchemy/ext/serializer.py +185 -0
- sqlalchemy/future/__init__.py +16 -0
- sqlalchemy/future/engine.py +15 -0
- sqlalchemy/inspection.py +174 -0
- sqlalchemy/log.py +283 -0
- sqlalchemy/orm/__init__.py +176 -0
- sqlalchemy/orm/_orm_constructors.py +2694 -0
- sqlalchemy/orm/_typing.py +179 -0
- sqlalchemy/orm/attributes.py +2868 -0
- sqlalchemy/orm/base.py +976 -0
- sqlalchemy/orm/bulk_persistence.py +2152 -0
- sqlalchemy/orm/clsregistry.py +582 -0
- sqlalchemy/orm/collections.py +1568 -0
- sqlalchemy/orm/context.py +3471 -0
- sqlalchemy/orm/decl_api.py +2280 -0
- sqlalchemy/orm/decl_base.py +2309 -0
- sqlalchemy/orm/dependency.py +1306 -0
- sqlalchemy/orm/descriptor_props.py +1183 -0
- sqlalchemy/orm/dynamic.py +307 -0
- sqlalchemy/orm/evaluator.py +379 -0
- sqlalchemy/orm/events.py +3386 -0
- sqlalchemy/orm/exc.py +237 -0
- sqlalchemy/orm/identity.py +302 -0
- sqlalchemy/orm/instrumentation.py +746 -0
- sqlalchemy/orm/interfaces.py +1589 -0
- sqlalchemy/orm/loading.py +1684 -0
- sqlalchemy/orm/mapped_collection.py +557 -0
- sqlalchemy/orm/mapper.py +4411 -0
- sqlalchemy/orm/path_registry.py +829 -0
- sqlalchemy/orm/persistence.py +1789 -0
- sqlalchemy/orm/properties.py +973 -0
- sqlalchemy/orm/query.py +3528 -0
- sqlalchemy/orm/relationships.py +3570 -0
- sqlalchemy/orm/scoping.py +2232 -0
- sqlalchemy/orm/session.py +5403 -0
- sqlalchemy/orm/state.py +1175 -0
- sqlalchemy/orm/state_changes.py +196 -0
- sqlalchemy/orm/strategies.py +3492 -0
- sqlalchemy/orm/strategy_options.py +2562 -0
- sqlalchemy/orm/sync.py +164 -0
- sqlalchemy/orm/unitofwork.py +798 -0
- sqlalchemy/orm/util.py +2438 -0
- sqlalchemy/orm/writeonly.py +694 -0
- sqlalchemy/pool/__init__.py +41 -0
- sqlalchemy/pool/base.py +1522 -0
- sqlalchemy/pool/events.py +375 -0
- sqlalchemy/pool/impl.py +582 -0
- sqlalchemy/py.typed +0 -0
- sqlalchemy/schema.py +74 -0
- sqlalchemy/sql/__init__.py +156 -0
- sqlalchemy/sql/_annotated_cols.py +397 -0
- sqlalchemy/sql/_dml_constructors.py +132 -0
- sqlalchemy/sql/_elements_constructors.py +2164 -0
- sqlalchemy/sql/_orm_types.py +20 -0
- sqlalchemy/sql/_selectable_constructors.py +840 -0
- sqlalchemy/sql/_typing.py +487 -0
- sqlalchemy/sql/_util_cy.cp313t-win_arm64.pyd +0 -0
- sqlalchemy/sql/_util_cy.py +127 -0
- sqlalchemy/sql/annotation.py +590 -0
- sqlalchemy/sql/base.py +2699 -0
- sqlalchemy/sql/cache_key.py +1066 -0
- sqlalchemy/sql/coercions.py +1373 -0
- sqlalchemy/sql/compiler.py +8327 -0
- sqlalchemy/sql/crud.py +1815 -0
- sqlalchemy/sql/ddl.py +1928 -0
- sqlalchemy/sql/default_comparator.py +654 -0
- sqlalchemy/sql/dml.py +1977 -0
- sqlalchemy/sql/elements.py +6033 -0
- sqlalchemy/sql/events.py +458 -0
- sqlalchemy/sql/expression.py +172 -0
- sqlalchemy/sql/functions.py +2305 -0
- sqlalchemy/sql/lambdas.py +1443 -0
- sqlalchemy/sql/naming.py +209 -0
- sqlalchemy/sql/operators.py +2897 -0
- sqlalchemy/sql/roles.py +332 -0
- sqlalchemy/sql/schema.py +6703 -0
- sqlalchemy/sql/selectable.py +7553 -0
- sqlalchemy/sql/sqltypes.py +4093 -0
- sqlalchemy/sql/traversals.py +1042 -0
- sqlalchemy/sql/type_api.py +2446 -0
- sqlalchemy/sql/util.py +1495 -0
- sqlalchemy/sql/visitors.py +1157 -0
- sqlalchemy/testing/__init__.py +96 -0
- sqlalchemy/testing/assertions.py +1007 -0
- sqlalchemy/testing/assertsql.py +519 -0
- sqlalchemy/testing/asyncio.py +128 -0
- sqlalchemy/testing/config.py +440 -0
- sqlalchemy/testing/engines.py +483 -0
- sqlalchemy/testing/entities.py +117 -0
- sqlalchemy/testing/exclusions.py +476 -0
- sqlalchemy/testing/fixtures/__init__.py +30 -0
- sqlalchemy/testing/fixtures/base.py +384 -0
- sqlalchemy/testing/fixtures/mypy.py +247 -0
- sqlalchemy/testing/fixtures/orm.py +227 -0
- sqlalchemy/testing/fixtures/sql.py +538 -0
- sqlalchemy/testing/pickleable.py +155 -0
- sqlalchemy/testing/plugin/__init__.py +6 -0
- sqlalchemy/testing/plugin/bootstrap.py +51 -0
- sqlalchemy/testing/plugin/plugin_base.py +828 -0
- sqlalchemy/testing/plugin/pytestplugin.py +892 -0
- sqlalchemy/testing/profiling.py +329 -0
- sqlalchemy/testing/provision.py +613 -0
- sqlalchemy/testing/requirements.py +1978 -0
- sqlalchemy/testing/schema.py +198 -0
- sqlalchemy/testing/suite/__init__.py +19 -0
- sqlalchemy/testing/suite/test_cte.py +237 -0
- sqlalchemy/testing/suite/test_ddl.py +420 -0
- sqlalchemy/testing/suite/test_dialect.py +776 -0
- sqlalchemy/testing/suite/test_insert.py +630 -0
- sqlalchemy/testing/suite/test_reflection.py +3557 -0
- sqlalchemy/testing/suite/test_results.py +660 -0
- sqlalchemy/testing/suite/test_rowcount.py +258 -0
- sqlalchemy/testing/suite/test_select.py +2112 -0
- sqlalchemy/testing/suite/test_sequence.py +317 -0
- sqlalchemy/testing/suite/test_table_via_select.py +686 -0
- sqlalchemy/testing/suite/test_types.py +2271 -0
- sqlalchemy/testing/suite/test_unicode_ddl.py +189 -0
- sqlalchemy/testing/suite/test_update_delete.py +139 -0
- sqlalchemy/testing/util.py +535 -0
- sqlalchemy/testing/warnings.py +52 -0
- sqlalchemy/types.py +76 -0
- sqlalchemy/util/__init__.py +158 -0
- sqlalchemy/util/_collections.py +688 -0
- sqlalchemy/util/_collections_cy.cp313t-win_arm64.pyd +0 -0
- sqlalchemy/util/_collections_cy.pxd +8 -0
- sqlalchemy/util/_collections_cy.py +516 -0
- sqlalchemy/util/_has_cython.py +46 -0
- sqlalchemy/util/_immutabledict_cy.cp313t-win_arm64.pyd +0 -0
- sqlalchemy/util/_immutabledict_cy.py +240 -0
- sqlalchemy/util/compat.py +299 -0
- sqlalchemy/util/concurrency.py +322 -0
- sqlalchemy/util/cython.py +79 -0
- sqlalchemy/util/deprecations.py +401 -0
- sqlalchemy/util/langhelpers.py +2320 -0
- sqlalchemy/util/preloaded.py +152 -0
- sqlalchemy/util/queue.py +304 -0
- sqlalchemy/util/tool_support.py +201 -0
- sqlalchemy/util/topological.py +120 -0
- sqlalchemy/util/typing.py +711 -0
- sqlalchemy-2.1.0b2.dist-info/METADATA +269 -0
- sqlalchemy-2.1.0b2.dist-info/RECORD +270 -0
- sqlalchemy-2.1.0b2.dist-info/WHEEL +5 -0
- sqlalchemy-2.1.0b2.dist-info/licenses/LICENSE +19 -0
- sqlalchemy-2.1.0b2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# engine/_row_cy.py
|
|
2
|
+
# Copyright (C) 2010-2026 the SQLAlchemy authors and contributors
|
|
3
|
+
# <see AUTHORS file>
|
|
4
|
+
#
|
|
5
|
+
# This module is part of SQLAlchemy and is released under
|
|
6
|
+
# the MIT License: https://www.opensource.org/licenses/mit-license.php
|
|
7
|
+
# mypy: disable-error-code="misc,no-redef,valid-type,no-untyped-call"
|
|
8
|
+
# mypy: disable-error-code="index,no-any-return,arg-type,assignment"
|
|
9
|
+
# mypy: disable-error-code="untyped-decorator"
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import Any
|
|
13
|
+
from typing import Dict
|
|
14
|
+
from typing import Iterator
|
|
15
|
+
from typing import List
|
|
16
|
+
from typing import NoReturn
|
|
17
|
+
from typing import Optional
|
|
18
|
+
from typing import Sequence
|
|
19
|
+
from typing import Tuple
|
|
20
|
+
from typing import Type
|
|
21
|
+
from typing import TYPE_CHECKING
|
|
22
|
+
|
|
23
|
+
if TYPE_CHECKING:
|
|
24
|
+
from .result import _KeyType
|
|
25
|
+
from .result import _ProcessorsType
|
|
26
|
+
from .result import ResultMetaData
|
|
27
|
+
|
|
28
|
+
# START GENERATED CYTHON IMPORT
|
|
29
|
+
# This section is automatically generated by the script tools/cython_imports.py
|
|
30
|
+
try:
|
|
31
|
+
# NOTE: the cython compiler needs this "import cython" in the file, it
|
|
32
|
+
# can't be only "from sqlalchemy.util import cython" with the fallback
|
|
33
|
+
# in that module
|
|
34
|
+
import cython
|
|
35
|
+
except ModuleNotFoundError:
|
|
36
|
+
from sqlalchemy.util import cython
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _is_compiled() -> bool:
|
|
40
|
+
"""Utility function to indicate if this module is compiled or not."""
|
|
41
|
+
return cython.compiled # type: ignore[no-any-return,unused-ignore]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# END GENERATED CYTHON IMPORT
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@cython.cclass
|
|
48
|
+
class BaseRow:
|
|
49
|
+
__slots__ = ("_parent", "_data", "_key_to_index")
|
|
50
|
+
|
|
51
|
+
if cython.compiled:
|
|
52
|
+
_parent: ResultMetaData = cython.declare(object, visibility="readonly")
|
|
53
|
+
_key_to_index: Dict[_KeyType, int] = cython.declare(
|
|
54
|
+
dict, visibility="readonly"
|
|
55
|
+
)
|
|
56
|
+
_data: Tuple[Any, ...] = cython.declare(tuple, visibility="readonly")
|
|
57
|
+
|
|
58
|
+
def __init__(
|
|
59
|
+
self,
|
|
60
|
+
parent: ResultMetaData,
|
|
61
|
+
processors: Optional[_ProcessorsType],
|
|
62
|
+
key_to_index: Dict[_KeyType, int],
|
|
63
|
+
data: Sequence[Any],
|
|
64
|
+
) -> None:
|
|
65
|
+
"""Row objects are constructed by CursorResult objects."""
|
|
66
|
+
self._set_attrs(
|
|
67
|
+
parent,
|
|
68
|
+
key_to_index,
|
|
69
|
+
(
|
|
70
|
+
_apply_processors(processors, data)
|
|
71
|
+
if processors is not None
|
|
72
|
+
else data if isinstance(data, tuple) else tuple(data)
|
|
73
|
+
),
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
@cython.cfunc
|
|
77
|
+
@cython.inline
|
|
78
|
+
def _set_attrs( # type: ignore[no-untyped-def] # cython crashes
|
|
79
|
+
self,
|
|
80
|
+
parent: ResultMetaData,
|
|
81
|
+
key_to_index: Dict[_KeyType, int],
|
|
82
|
+
data: Tuple[Any, ...],
|
|
83
|
+
):
|
|
84
|
+
if cython.compiled:
|
|
85
|
+
# cython does not use __setattr__
|
|
86
|
+
self._parent = parent
|
|
87
|
+
self._key_to_index = key_to_index
|
|
88
|
+
self._data = data
|
|
89
|
+
else:
|
|
90
|
+
# python does, so use object.__setattr__
|
|
91
|
+
object.__setattr__(self, "_parent", parent)
|
|
92
|
+
object.__setattr__(self, "_key_to_index", key_to_index)
|
|
93
|
+
object.__setattr__(self, "_data", data)
|
|
94
|
+
|
|
95
|
+
def __reduce__(self) -> Tuple[Any, Any]:
|
|
96
|
+
return (
|
|
97
|
+
rowproxy_reconstructor,
|
|
98
|
+
(self.__class__, self.__getstate__()),
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
def __getstate__(self) -> Dict[str, Any]:
|
|
102
|
+
return {"_parent": self._parent, "_data": self._data}
|
|
103
|
+
|
|
104
|
+
def __setstate__(self, state: Dict[str, Any]) -> None:
|
|
105
|
+
parent = state["_parent"]
|
|
106
|
+
self._set_attrs(parent, parent._key_to_index, state["_data"])
|
|
107
|
+
|
|
108
|
+
def _values_impl(self) -> List[Any]:
|
|
109
|
+
return list(self._data)
|
|
110
|
+
|
|
111
|
+
def __iter__(self) -> Iterator[Any]:
|
|
112
|
+
return iter(self._data)
|
|
113
|
+
|
|
114
|
+
def __len__(self) -> int:
|
|
115
|
+
return len(self._data)
|
|
116
|
+
|
|
117
|
+
def __hash__(self) -> int:
|
|
118
|
+
return hash(self._data)
|
|
119
|
+
|
|
120
|
+
if not TYPE_CHECKING:
|
|
121
|
+
|
|
122
|
+
def __getitem__(self, key: Any) -> Any:
|
|
123
|
+
return self._data[key]
|
|
124
|
+
|
|
125
|
+
def _get_by_key_impl_mapping(self, key: _KeyType) -> Any:
|
|
126
|
+
return self._get_by_key_impl(key, False)
|
|
127
|
+
|
|
128
|
+
@cython.cfunc
|
|
129
|
+
@cython.inline
|
|
130
|
+
def _get_by_key_impl(self, key: _KeyType, attr_err: cython.bint) -> object:
|
|
131
|
+
# NOTE: don't type index since there is no advantage in making cython
|
|
132
|
+
# do a type check
|
|
133
|
+
index = self._key_to_index.get(key)
|
|
134
|
+
if index is not None:
|
|
135
|
+
return self._data[index]
|
|
136
|
+
self._parent._key_not_found(key, attr_err)
|
|
137
|
+
|
|
138
|
+
if cython.compiled:
|
|
139
|
+
|
|
140
|
+
@cython.annotation_typing(False)
|
|
141
|
+
def __getattribute__(self, name: str) -> Any:
|
|
142
|
+
# this optimizes getattr access on cython, that's otherwise
|
|
143
|
+
# quite slow compared with python. The assumption is that
|
|
144
|
+
# most columns will not start with _. If they do they will
|
|
145
|
+
# fallback on __getattr__ in any case.
|
|
146
|
+
if name != "" and name[0] != "_":
|
|
147
|
+
# inline of _get_by_key_impl. Attribute on the class
|
|
148
|
+
# take precedence over column names.
|
|
149
|
+
index = self._key_to_index.get(name)
|
|
150
|
+
if index is not None and not hasattr(type(self), name):
|
|
151
|
+
return self._data[index]
|
|
152
|
+
|
|
153
|
+
return object.__getattribute__(self, name)
|
|
154
|
+
|
|
155
|
+
@cython.annotation_typing(False)
|
|
156
|
+
def __getattr__(self, name: str) -> Any:
|
|
157
|
+
return self._get_by_key_impl(name, True)
|
|
158
|
+
|
|
159
|
+
def __setattr__(self, name: str, value: Any) -> NoReturn:
|
|
160
|
+
raise AttributeError("can't set attribute")
|
|
161
|
+
|
|
162
|
+
def __delattr__(self, name: str) -> NoReturn:
|
|
163
|
+
raise AttributeError("can't delete attribute")
|
|
164
|
+
|
|
165
|
+
def _to_tuple_instance(self) -> Tuple[Any, ...]:
|
|
166
|
+
return self._data
|
|
167
|
+
|
|
168
|
+
def __contains__(self, key: Any) -> cython.bint:
|
|
169
|
+
return key in self._data
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
if cython.compiled:
|
|
173
|
+
|
|
174
|
+
from cython.cimports.cpython import PyTuple_New
|
|
175
|
+
from cython.cimports.cpython import Py_INCREF
|
|
176
|
+
from cython.cimports.cpython import PyTuple_SET_ITEM
|
|
177
|
+
|
|
178
|
+
@cython.inline
|
|
179
|
+
@cython.cfunc
|
|
180
|
+
@cython.wraparound(False)
|
|
181
|
+
@cython.boundscheck(False)
|
|
182
|
+
@cython.locals(
|
|
183
|
+
res=tuple,
|
|
184
|
+
proc_size=cython.Py_ssize_t,
|
|
185
|
+
i=cython.Py_ssize_t,
|
|
186
|
+
p=object,
|
|
187
|
+
value=object,
|
|
188
|
+
)
|
|
189
|
+
def _apply_processors(
|
|
190
|
+
proc: Sequence[Any], data: Sequence[Any]
|
|
191
|
+
) -> Tuple[Any, ...]:
|
|
192
|
+
proc_size = len(proc)
|
|
193
|
+
# TODO: would be nice to do this only on the fist row
|
|
194
|
+
assert len(data) == proc_size
|
|
195
|
+
res = PyTuple_New(proc_size)
|
|
196
|
+
for i in range(proc_size):
|
|
197
|
+
p = proc[i]
|
|
198
|
+
if p is not None:
|
|
199
|
+
value = p(data[i])
|
|
200
|
+
else:
|
|
201
|
+
value = data[i]
|
|
202
|
+
Py_INCREF(value)
|
|
203
|
+
PyTuple_SET_ITEM(res, i, value)
|
|
204
|
+
return res
|
|
205
|
+
|
|
206
|
+
else:
|
|
207
|
+
|
|
208
|
+
def _apply_processors(
|
|
209
|
+
proc: _ProcessorsType, data: Sequence[Any]
|
|
210
|
+
) -> Tuple[Any, ...]:
|
|
211
|
+
res: List[Any] = list(data)
|
|
212
|
+
proc_size = len(proc)
|
|
213
|
+
# TODO: would be nice to do this only on the fist row
|
|
214
|
+
assert len(res) == proc_size
|
|
215
|
+
for i in range(proc_size):
|
|
216
|
+
p = proc[i]
|
|
217
|
+
if p is not None:
|
|
218
|
+
res[i] = p(res[i])
|
|
219
|
+
return tuple(res)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
# This reconstructor is necessary so that pickles with the Cy extension or
|
|
223
|
+
# without use the same Binary format.
|
|
224
|
+
# Turn off annotation typing so the compiled version accepts the python
|
|
225
|
+
# class too.
|
|
226
|
+
@cython.annotation_typing(False)
|
|
227
|
+
def rowproxy_reconstructor(
|
|
228
|
+
cls: Type[BaseRow], state: Dict[str, Any]
|
|
229
|
+
) -> BaseRow:
|
|
230
|
+
obj = cls.__new__(cls)
|
|
231
|
+
obj.__setstate__(state)
|
|
232
|
+
return obj
|
|
Binary file
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# engine/_util_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, type-arg, untyped-decorator"
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from collections.abc import Mapping
|
|
11
|
+
import operator
|
|
12
|
+
from typing import Any
|
|
13
|
+
from typing import Optional
|
|
14
|
+
from typing import Tuple
|
|
15
|
+
from typing import TYPE_CHECKING
|
|
16
|
+
|
|
17
|
+
from .. import exc
|
|
18
|
+
from ..util import warn_deprecated
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from .interfaces import _CoreAnyExecuteParams
|
|
22
|
+
from .interfaces import _CoreMultiExecuteParams
|
|
23
|
+
from .interfaces import _DBAPIAnyExecuteParams
|
|
24
|
+
from .interfaces import _DBAPIMultiExecuteParams
|
|
25
|
+
from .result import _TupleGetterType
|
|
26
|
+
|
|
27
|
+
# START GENERATED CYTHON IMPORT
|
|
28
|
+
# This section is automatically generated by the script tools/cython_imports.py
|
|
29
|
+
try:
|
|
30
|
+
# NOTE: the cython compiler needs this "import cython" in the file, it
|
|
31
|
+
# can't be only "from sqlalchemy.util import cython" with the fallback
|
|
32
|
+
# in that module
|
|
33
|
+
import cython
|
|
34
|
+
except ModuleNotFoundError:
|
|
35
|
+
from sqlalchemy.util import cython
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _is_compiled() -> bool:
|
|
39
|
+
"""Utility function to indicate if this module is compiled or not."""
|
|
40
|
+
return cython.compiled # type: ignore[no-any-return,unused-ignore]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# END GENERATED CYTHON IMPORT
|
|
44
|
+
|
|
45
|
+
_Empty_Tuple: Tuple[Any, ...] = cython.declare(tuple, ())
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@cython.inline
|
|
49
|
+
@cython.cfunc
|
|
50
|
+
def _is_mapping_or_tuple(value: object, /) -> cython.bint:
|
|
51
|
+
return (
|
|
52
|
+
isinstance(value, dict)
|
|
53
|
+
or isinstance(value, tuple)
|
|
54
|
+
or isinstance(value, Mapping)
|
|
55
|
+
# only do immutabledict or abc.__instancecheck__ for Mapping after
|
|
56
|
+
# we've checked for plain dictionaries and would otherwise raise
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@cython.inline
|
|
61
|
+
@cython.cfunc
|
|
62
|
+
def _is_mapping(value: object, /) -> cython.bint:
|
|
63
|
+
return (
|
|
64
|
+
isinstance(value, dict)
|
|
65
|
+
or isinstance(value, Mapping)
|
|
66
|
+
# only do immutabledict or abc.__instancecheck__ for Mapping after
|
|
67
|
+
# we've checked for plain dictionaries and would otherwise raise
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _distill_params_20(
|
|
72
|
+
params: Optional[_CoreAnyExecuteParams],
|
|
73
|
+
) -> _CoreMultiExecuteParams:
|
|
74
|
+
if params is None:
|
|
75
|
+
return _Empty_Tuple
|
|
76
|
+
# Assume list is more likely than tuple
|
|
77
|
+
elif isinstance(params, list) or isinstance(params, tuple):
|
|
78
|
+
# collections_abc.MutableSequence # avoid abc.__instancecheck__
|
|
79
|
+
if len(params) == 0:
|
|
80
|
+
warn_deprecated(
|
|
81
|
+
"Empty parameter sequence passed to execute(). "
|
|
82
|
+
"This use is deprecated and will raise an exception in a "
|
|
83
|
+
"future SQLAlchemy release",
|
|
84
|
+
"2.1",
|
|
85
|
+
)
|
|
86
|
+
elif not _is_mapping(params[0]):
|
|
87
|
+
raise exc.ArgumentError(
|
|
88
|
+
"List argument must consist only of dictionaries"
|
|
89
|
+
)
|
|
90
|
+
return params
|
|
91
|
+
elif _is_mapping(params):
|
|
92
|
+
return [params] # type: ignore[list-item]
|
|
93
|
+
else:
|
|
94
|
+
raise exc.ArgumentError("mapping or list expected for parameters")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# _is_mapping_or_tuple could be inlined if pure python perf is a problem
|
|
98
|
+
def _distill_raw_params(
|
|
99
|
+
params: Optional[_DBAPIAnyExecuteParams],
|
|
100
|
+
) -> _DBAPIMultiExecuteParams:
|
|
101
|
+
if params is None:
|
|
102
|
+
return _Empty_Tuple
|
|
103
|
+
elif isinstance(params, list):
|
|
104
|
+
# collections_abc.MutableSequence # avoid abc.__instancecheck__
|
|
105
|
+
if len(params) > 0 and not _is_mapping_or_tuple(params[0]):
|
|
106
|
+
raise exc.ArgumentError(
|
|
107
|
+
"List argument must consist only of tuples or dictionaries"
|
|
108
|
+
)
|
|
109
|
+
return params
|
|
110
|
+
elif _is_mapping_or_tuple(params):
|
|
111
|
+
return [params] # type: ignore[return-value]
|
|
112
|
+
else:
|
|
113
|
+
raise exc.ArgumentError("mapping or sequence expected for parameters")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@cython.cfunc
|
|
117
|
+
def _is_contiguous(indexes: Tuple[int, ...]) -> cython.bint:
|
|
118
|
+
i: cython.Py_ssize_t
|
|
119
|
+
prev: cython.Py_ssize_t
|
|
120
|
+
curr: cython.Py_ssize_t
|
|
121
|
+
for i in range(1, len(indexes)):
|
|
122
|
+
prev = indexes[i - 1]
|
|
123
|
+
curr = indexes[i]
|
|
124
|
+
if prev != curr - 1:
|
|
125
|
+
return False
|
|
126
|
+
return True
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def tuplegetter(*indexes: int) -> _TupleGetterType:
|
|
130
|
+
max_index: int
|
|
131
|
+
if len(indexes) == 1 or _is_contiguous(indexes):
|
|
132
|
+
# slice form is faster but returns a list if input is list
|
|
133
|
+
max_index = indexes[-1]
|
|
134
|
+
return operator.itemgetter(slice(indexes[0], max_index + 1))
|
|
135
|
+
else:
|
|
136
|
+
return operator.itemgetter(*indexes)
|