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,633 @@
1
+ # engine/_result_cy.py
2
+ # Copyright (C) 2005-2026 the SQLAlchemy authors and contributors
3
+ # <see AUTHORS file>
4
+ #
5
+ # This module is part of SQLAlchemy and is released under
6
+ # the MIT License: https://www.opensource.org/licenses/mit-license.php
7
+ # mypy: disable-error-code="misc,no-redef,type-arg,untyped-decorator"
8
+ from __future__ import annotations
9
+
10
+ from collections.abc import Callable
11
+ from collections.abc import Iterator
12
+ from collections.abc import Sequence
13
+ from enum import Enum
14
+ import operator
15
+ from typing import Any
16
+ from typing import Generic
17
+ from typing import Literal
18
+ from typing import overload
19
+ from typing import TYPE_CHECKING
20
+ from typing import TypeVar
21
+ from typing import Union
22
+
23
+ from .row import Row
24
+ from .row import RowMapping
25
+ from .. import exc
26
+ from ..util import HasMemoized_ro_memoized_attribute
27
+ from ..util.typing import Self
28
+ from ..util.typing import TupleAny
29
+ from ..util.typing import Unpack
30
+
31
+ if TYPE_CHECKING:
32
+ from .result import _ProcessorsType
33
+ from .result import Result
34
+ from .result import ResultMetaData
35
+
36
+ # START GENERATED CYTHON IMPORT
37
+ # This section is automatically generated by the script tools/cython_imports.py
38
+ try:
39
+ # NOTE: the cython compiler needs this "import cython" in the file, it
40
+ # can't be only "from sqlalchemy.util import cython" with the fallback
41
+ # in that module
42
+ import cython
43
+ except ModuleNotFoundError:
44
+ from sqlalchemy.util import cython
45
+
46
+
47
+ def _is_compiled() -> bool:
48
+ """Utility function to indicate if this module is compiled or not."""
49
+ return cython.compiled # type: ignore[no-any-return,unused-ignore]
50
+
51
+
52
+ # END GENERATED CYTHON IMPORT
53
+
54
+ if cython.compiled:
55
+ from cython.cimports.cpython import Py_INCREF
56
+ from cython.cimports.cpython import PyList_New
57
+ from cython.cimports.cpython import PyList_SET_ITEM
58
+ from cython.cimports.cpython import PyTuple_New
59
+ from cython.cimports.cpython import PyTuple_SET_ITEM
60
+
61
+
62
+ _RowData = Row[Unpack[TupleAny]] | RowMapping | Any
63
+ """A generic form of "row" that accommodates for the different kinds of
64
+ "rows" that different result objects return, including row, row mapping, and
65
+ scalar values"""
66
+ _R = TypeVar("_R", bound=_RowData)
67
+ _T = TypeVar("_T", bound=Any)
68
+
69
+ _InterimRowType = Union[_R, TupleAny]
70
+ """a catchall "anything" kind of return type that can be applied
71
+ across all the result types
72
+
73
+ """
74
+
75
+ _UniqueFilterType = Callable[[Any], Any]
76
+ _UniqueFilterStateType = tuple[set[Any], _UniqueFilterType | None]
77
+
78
+ _FLAG_SIMPLE = cython.declare(cython.char, 0)
79
+ _FLAG_SCALAR_TO_TUPLE = cython.declare(cython.char, 1)
80
+ _FLAG_TUPLE_FILTER = cython.declare(cython.char, 2)
81
+
82
+
83
+ # a symbol that indicates to internal Result methods that
84
+ # "no row is returned". We can't use None for those cases where a scalar
85
+ # filter is applied to rows.
86
+ class _NoRow(Enum):
87
+ _NO_ROW = 0
88
+
89
+
90
+ _NO_ROW = _NoRow._NO_ROW
91
+
92
+
93
+ class BaseResultInternal(Generic[_R]):
94
+ __slots__ = ()
95
+
96
+ _real_result: Result[Unpack[TupleAny]] | None = None
97
+ _generate_rows: bool = True
98
+ _row_logging_fn: Callable[[Any], Any] | None
99
+
100
+ _unique_filter_state: _UniqueFilterStateType | None = None
101
+ _post_creational_filter: Callable[[Any], Any] | None = None
102
+
103
+ _metadata: ResultMetaData
104
+
105
+ _source_supports_scalars: bool
106
+ _yield_per: int | None
107
+
108
+ def _fetchiter_impl(
109
+ self,
110
+ ) -> Iterator[_InterimRowType[Row[Unpack[TupleAny]]]]:
111
+ raise NotImplementedError()
112
+
113
+ def _fetchone_impl(
114
+ self, hard_close: bool = False
115
+ ) -> _InterimRowType[Row[Unpack[TupleAny]]] | None:
116
+ raise NotImplementedError()
117
+
118
+ def _fetchmany_impl(
119
+ self, size: int | None = None
120
+ ) -> list[_InterimRowType[Row[Unpack[TupleAny]]]]:
121
+ raise NotImplementedError()
122
+
123
+ def _fetchall_impl(
124
+ self,
125
+ ) -> list[_InterimRowType[Row[Unpack[TupleAny]]]]:
126
+ raise NotImplementedError()
127
+
128
+ def _soft_close(self, hard: bool = False) -> None:
129
+ raise NotImplementedError()
130
+
131
+ @HasMemoized_ro_memoized_attribute
132
+ def _row_getter(
133
+ self,
134
+ ) -> tuple[Callable[..., _R] | None, Callable[..., Sequence[_R]] | None]:
135
+ real_result = self if self._real_result is None else self._real_result
136
+
137
+ metadata = self._metadata
138
+ tuple_filters = metadata._tuplefilter
139
+ flag: cython.char = _FLAG_SIMPLE
140
+
141
+ if real_result._source_supports_scalars:
142
+ if not self._generate_rows:
143
+ return None, None
144
+ else:
145
+ flag = _FLAG_SCALAR_TO_TUPLE
146
+ elif tuple_filters is not None:
147
+ flag = _FLAG_TUPLE_FILTER
148
+
149
+ processors: tuple
150
+ proc_valid: tuple
151
+
152
+ if metadata._effective_processors is not None:
153
+ ep = metadata._effective_processors
154
+ if flag == _FLAG_TUPLE_FILTER:
155
+ ep = tuple_filters(ep)
156
+
157
+ processors = tuple(ep)
158
+ proc_valid = tuple(
159
+ [i for i, p in enumerate(processors) if p is not None]
160
+ )
161
+ else:
162
+ processors = ()
163
+ proc_valid = ()
164
+
165
+ proc_size: cython.Py_ssize_t = len(processors)
166
+ log_row = real_result._row_logging_fn
167
+ has_log_row: cython.bint = log_row is not None
168
+
169
+ key_to_index = metadata._key_to_index
170
+ _Row = Row
171
+
172
+ if flag == _FLAG_SIMPLE and proc_size == 0 and not has_log_row:
173
+ # just build the rows
174
+
175
+ def single_row_simple(input_row: Sequence[Any], /) -> Row:
176
+ return _Row(metadata, None, key_to_index, input_row)
177
+
178
+ if cython.compiled:
179
+
180
+ def many_rows_simple(rows: Sequence[Any], /) -> list[Any]:
181
+ size: cython.Py_hash_t = len(rows)
182
+ i: cython.Py_ssize_t
183
+ result: list = PyList_New(size)
184
+ for i in range(size):
185
+ row: object = _Row(
186
+ metadata, None, key_to_index, rows[i]
187
+ )
188
+ Py_INCREF(row)
189
+ PyList_SET_ITEM(result, i, row)
190
+ return result
191
+
192
+ else:
193
+
194
+ def many_rows_simple(rows: Sequence[Any], /) -> list[Any]:
195
+ return [
196
+ _Row(metadata, None, key_to_index, row) for row in rows
197
+ ]
198
+
199
+ return single_row_simple, many_rows_simple # type: ignore[return-value] # noqa: E501
200
+
201
+ first_row: cython.bint = True
202
+
203
+ def single_row(input_row: Sequence[Any], /) -> Row:
204
+ nonlocal first_row
205
+
206
+ if flag == _FLAG_SCALAR_TO_TUPLE:
207
+ input_row = (input_row,)
208
+ elif flag == _FLAG_TUPLE_FILTER:
209
+ input_row = tuple_filters(input_row)
210
+
211
+ if proc_size != 0:
212
+ if first_row:
213
+ first_row = False
214
+ assert len(input_row) == proc_size
215
+ input_row = _apply_processors(
216
+ processors, proc_size, proc_valid, input_row
217
+ )
218
+
219
+ row: Row = _Row(metadata, None, key_to_index, input_row)
220
+ if has_log_row:
221
+ row = log_row(row)
222
+ return row
223
+
224
+ if cython.compiled:
225
+
226
+ def many_rows(rows: Sequence[Any], /) -> list[Any]:
227
+ size: cython.Py_hash_t = len(rows)
228
+ i: cython.Py_ssize_t
229
+ result: list = PyList_New(size)
230
+ for i in range(size):
231
+ row: object = single_row(rows[i])
232
+ Py_INCREF(row)
233
+ PyList_SET_ITEM(result, i, row)
234
+ return result
235
+
236
+ else:
237
+
238
+ def many_rows(rows: Sequence[Any], /) -> list[Any]:
239
+ return [single_row(row) for row in rows]
240
+
241
+ return single_row, many_rows # type: ignore[return-value]
242
+
243
+ @HasMemoized_ro_memoized_attribute
244
+ def _iterator_getter(self) -> Callable[[], Iterator[_R]]:
245
+ make_row = self._row_getter[0]
246
+
247
+ post_creational_filter = self._post_creational_filter
248
+
249
+ if self._unique_filter_state is not None:
250
+ uniques: set
251
+ uniques, strategy = self._unique_strategy
252
+
253
+ def iterrows() -> Iterator[_R]:
254
+ for raw_row in self._fetchiter_impl():
255
+ row = (
256
+ make_row(raw_row) if make_row is not None else raw_row
257
+ )
258
+ hashed = strategy(row) if strategy is not None else row
259
+ if hashed in uniques:
260
+ continue
261
+ uniques.add(hashed)
262
+ if post_creational_filter is not None:
263
+ row = post_creational_filter(row)
264
+ yield row
265
+
266
+ else:
267
+
268
+ def iterrows() -> Iterator[_R]:
269
+ for raw_row in self._fetchiter_impl():
270
+ row = (
271
+ make_row(raw_row) if make_row is not None else raw_row
272
+ )
273
+ if post_creational_filter is not None:
274
+ row = post_creational_filter(row)
275
+ yield row
276
+
277
+ return iterrows
278
+
279
+ def _raw_all_rows(self) -> Sequence[_R]:
280
+ make_rows = self._row_getter[1]
281
+ assert make_rows is not None
282
+ return make_rows(self._fetchall_impl())
283
+
284
+ def _allrows(self) -> Sequence[_R]:
285
+ post_creational_filter = self._post_creational_filter
286
+
287
+ make_rows = self._row_getter[1]
288
+
289
+ rows = self._fetchall_impl()
290
+ made_rows: Sequence[_InterimRowType[_R]]
291
+ if make_rows is not None:
292
+ made_rows = make_rows(rows)
293
+ else:
294
+ made_rows = rows
295
+
296
+ interim_rows: Sequence[_R]
297
+
298
+ if self._unique_filter_state is not None:
299
+ uniques: set
300
+ uniques, strategy = self._unique_strategy
301
+ interim_rows = _apply_unique_strategy(
302
+ made_rows, [], uniques, strategy
303
+ )
304
+ else:
305
+ interim_rows = made_rows # type: ignore
306
+
307
+ if post_creational_filter is not None:
308
+ interim_rows = [
309
+ post_creational_filter(row) for row in interim_rows
310
+ ]
311
+ return interim_rows
312
+
313
+ @HasMemoized_ro_memoized_attribute
314
+ def _onerow_getter(
315
+ self,
316
+ ) -> Callable[[Self], Literal[_NoRow._NO_ROW] | _R]:
317
+ make_row = self._row_getter[0]
318
+
319
+ post_creational_filter = self._post_creational_filter
320
+
321
+ if self._unique_filter_state is not None:
322
+ uniques: set
323
+ uniques, strategy = self._unique_strategy
324
+
325
+ def onerow(self: Self) -> Literal[_NoRow._NO_ROW] | _R:
326
+ while True:
327
+ row = self._fetchone_impl()
328
+ if row is None:
329
+ return _NO_ROW
330
+ else:
331
+ obj: _InterimRowType[Any] = (
332
+ make_row(row) if make_row is not None else row
333
+ )
334
+ hashed = strategy(obj) if strategy is not None else obj
335
+ if hashed in uniques:
336
+ continue
337
+ uniques.add(hashed)
338
+ if post_creational_filter is not None:
339
+ obj = post_creational_filter(obj)
340
+ return obj # type: ignore
341
+
342
+ else:
343
+
344
+ def onerow(self: Self) -> Literal[_NoRow._NO_ROW] | _R:
345
+ row = self._fetchone_impl()
346
+ if row is None:
347
+ return _NO_ROW
348
+ else:
349
+ interim_row: _InterimRowType[Any] = (
350
+ make_row(row) if make_row is not None else row
351
+ )
352
+ if post_creational_filter is not None:
353
+ interim_row = post_creational_filter(interim_row)
354
+ return interim_row # type: ignore
355
+
356
+ return onerow
357
+
358
+ @HasMemoized_ro_memoized_attribute
359
+ def _manyrow_getter(self) -> Callable[[Self, int | None], Sequence[_R]]:
360
+ make_rows = self._row_getter[1]
361
+ real_result = self if self._real_result is None else self._real_result
362
+ yield_per = real_result._yield_per
363
+
364
+ post_creational_filter = self._post_creational_filter
365
+
366
+ if self._unique_filter_state:
367
+ uniques: set
368
+ uniques, strategy = self._unique_strategy
369
+
370
+ def manyrows(self: Self, num: int | None, /) -> Sequence[_R]:
371
+ made_rows: Sequence[Any]
372
+ collect: list[_R] = []
373
+
374
+ _manyrows = self._fetchmany_impl
375
+
376
+ if num is None:
377
+ # if None is passed, we don't know the default
378
+ # manyrows number, DBAPI has this as cursor.arraysize
379
+ # different DBAPIs / fetch strategies may be different.
380
+ # do a fetch to find what the number is. if there are
381
+ # only fewer rows left, then it doesn't matter.
382
+ if yield_per:
383
+ num_required = num = yield_per
384
+ else:
385
+ rows = _manyrows()
386
+ num = len(rows)
387
+ made_rows = (
388
+ rows if make_rows is None else make_rows(rows)
389
+ )
390
+ _apply_unique_strategy(
391
+ made_rows, collect, uniques, strategy
392
+ )
393
+ num_required = num - len(collect)
394
+ else:
395
+ num_required = num
396
+
397
+ assert num is not None
398
+
399
+ while num_required:
400
+ rows = _manyrows(num_required)
401
+ if not rows:
402
+ break
403
+
404
+ made_rows = rows if make_rows is None else make_rows(rows)
405
+ _apply_unique_strategy(
406
+ made_rows, collect, uniques, strategy
407
+ )
408
+ num_required = num - len(collect)
409
+
410
+ if post_creational_filter is not None:
411
+ collect = [post_creational_filter(row) for row in collect]
412
+ return collect
413
+
414
+ else:
415
+
416
+ def manyrows(self: Self, num: int | None, /) -> Sequence[_R]:
417
+ if num is None:
418
+ num = yield_per
419
+
420
+ rows: Sequence = self._fetchmany_impl(num)
421
+ if make_rows is not None:
422
+ rows = make_rows(rows)
423
+ if post_creational_filter is not None:
424
+ rows = [post_creational_filter(row) for row in rows]
425
+ return rows
426
+
427
+ return manyrows
428
+
429
+ @overload
430
+ def _only_one_row(
431
+ self: BaseResultInternal[Row[_T, Unpack[TupleAny]]],
432
+ raise_for_second_row: bool,
433
+ raise_for_none: bool,
434
+ scalar: Literal[True],
435
+ ) -> _T: ...
436
+
437
+ @overload
438
+ def _only_one_row(
439
+ self,
440
+ raise_for_second_row: bool,
441
+ raise_for_none: Literal[True],
442
+ scalar: bool,
443
+ ) -> _R: ...
444
+
445
+ @overload
446
+ def _only_one_row(
447
+ self,
448
+ raise_for_second_row: bool,
449
+ raise_for_none: bool,
450
+ scalar: bool,
451
+ ) -> _R | None: ...
452
+
453
+ def _only_one_row(
454
+ self,
455
+ raise_for_second_row: bool,
456
+ raise_for_none: bool,
457
+ scalar: bool,
458
+ ) -> _R | None:
459
+ onerow = self._fetchone_impl
460
+
461
+ row = onerow(hard_close=True)
462
+ if row is None:
463
+ if raise_for_none:
464
+ raise exc.NoResultFound(
465
+ "No row was found when one was required"
466
+ )
467
+ else:
468
+ return None
469
+
470
+ if scalar and self._source_supports_scalars:
471
+ self._generate_rows = False
472
+ make_row = None
473
+ else:
474
+ make_row = self._row_getter[0]
475
+
476
+ try:
477
+ row = make_row(row) if make_row is not None else row # type: ignore[assignment] # noqa: E501
478
+ except:
479
+ self._soft_close(hard=True)
480
+ raise
481
+
482
+ if raise_for_second_row:
483
+ if self._unique_filter_state:
484
+ # for no second row but uniqueness, need to essentially
485
+ # consume the entire result :(
486
+ strategy = self._unique_strategy[1]
487
+
488
+ existing_row_hash = (
489
+ strategy(row) if strategy is not None else row
490
+ )
491
+
492
+ while True:
493
+ next_row: Any = onerow(hard_close=True)
494
+ if next_row is None:
495
+ next_row = _NO_ROW
496
+ break
497
+
498
+ try:
499
+ next_row = (
500
+ make_row(next_row)
501
+ if make_row is not None
502
+ else next_row
503
+ )
504
+
505
+ if strategy is not None:
506
+ # assert next_row is not _NO_ROW
507
+ if existing_row_hash == strategy(next_row):
508
+ continue
509
+ elif row == next_row:
510
+ continue
511
+ # here, we have a row and it's different
512
+ break
513
+ except:
514
+ self._soft_close(hard=True)
515
+ raise
516
+ else:
517
+ next_row = onerow(hard_close=True)
518
+ if next_row is None:
519
+ next_row = _NO_ROW
520
+
521
+ if next_row is not _NO_ROW:
522
+ self._soft_close(hard=True)
523
+ raise exc.MultipleResultsFound(
524
+ "Multiple rows were found when exactly one was required"
525
+ if raise_for_none
526
+ else "Multiple rows were found when one or none "
527
+ "was required"
528
+ )
529
+ else:
530
+ next_row = _NO_ROW
531
+ # if we checked for second row then that would have
532
+ # closed us :)
533
+ self._soft_close(hard=True)
534
+
535
+ if not scalar:
536
+ post_creational_filter = self._post_creational_filter
537
+ if post_creational_filter is not None:
538
+ row = post_creational_filter(row)
539
+
540
+ if scalar and make_row is not None:
541
+ return row[0] # type: ignore
542
+ else:
543
+ return row # type: ignore
544
+
545
+ def _iter_impl(self) -> Iterator[_R]:
546
+ return self._iterator_getter()
547
+
548
+ def _next_impl(self) -> _R:
549
+ row = self._onerow_getter(self)
550
+ if row is _NO_ROW:
551
+ raise StopIteration()
552
+ else:
553
+ return row
554
+
555
+ @HasMemoized_ro_memoized_attribute
556
+ def _unique_strategy(self) -> _UniqueFilterStateType:
557
+ assert self._unique_filter_state is not None
558
+ uniques, strategy = self._unique_filter_state
559
+
560
+ if strategy is None and self._metadata._unique_filters is not None:
561
+ real_result = (
562
+ self if self._real_result is None else self._real_result
563
+ )
564
+ if (
565
+ real_result._source_supports_scalars
566
+ and not self._generate_rows
567
+ ):
568
+ strategy = self._metadata._unique_filters[0]
569
+ else:
570
+ filters = self._metadata._unique_filters
571
+ if self._metadata._tuplefilter is not None:
572
+ filters = self._metadata._tuplefilter(filters)
573
+
574
+ strategy = operator.methodcaller("_filter_on_values", filters)
575
+ return uniques, strategy
576
+
577
+
578
+ if cython.compiled:
579
+
580
+ @cython.inline
581
+ @cython.cfunc
582
+ @cython.wraparound(False)
583
+ @cython.boundscheck(False)
584
+ def _apply_processors(
585
+ proc: tuple,
586
+ proc_size: cython.Py_ssize_t,
587
+ proc_valid: object, # used only by python impl
588
+ data: Sequence,
589
+ ) -> tuple[Any, ...]:
590
+ res: tuple = PyTuple_New(proc_size)
591
+ i: cython.Py_ssize_t
592
+ for i in range(proc_size):
593
+ p = proc[i]
594
+ if p is not None:
595
+ value = p(data[i])
596
+ else:
597
+ value = data[i]
598
+ Py_INCREF(value)
599
+ PyTuple_SET_ITEM(res, i, value)
600
+ return res
601
+
602
+ else:
603
+
604
+ def _apply_processors(
605
+ proc: _ProcessorsType,
606
+ proc_size: int, # used only by cython impl
607
+ proc_valid: tuple[int, ...],
608
+ data: Sequence[Any],
609
+ ) -> tuple[Any, ...]:
610
+ res = list(data)
611
+ for i in proc_valid:
612
+ res[i] = proc[i](res[i])
613
+ return tuple(res)
614
+
615
+
616
+ @cython.inline
617
+ @cython.cfunc
618
+ def _apply_unique_strategy(
619
+ rows: Sequence[Any],
620
+ destination: list[Any],
621
+ uniques: set[Any],
622
+ strategy: Callable[[Any], Any] | None,
623
+ ) -> list[Any]:
624
+ i: cython.Py_ssize_t
625
+ has_strategy: cython.bint = strategy is not None
626
+ for i in range(len(rows)):
627
+ row = rows[i]
628
+ hashed = strategy(row) if has_strategy else row
629
+ if hashed in uniques:
630
+ continue
631
+ uniques.add(hashed)
632
+ destination.append(row)
633
+ return destination