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,134 @@
|
|
|
1
|
+
# engine/mock.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
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from operator import attrgetter
|
|
11
|
+
import typing
|
|
12
|
+
from typing import Any
|
|
13
|
+
from typing import Callable
|
|
14
|
+
from typing import cast
|
|
15
|
+
from typing import Optional
|
|
16
|
+
from typing import Type
|
|
17
|
+
from typing import Union
|
|
18
|
+
|
|
19
|
+
from . import url as _url
|
|
20
|
+
from .. import util
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
if typing.TYPE_CHECKING:
|
|
24
|
+
from .base import Engine
|
|
25
|
+
from .interfaces import _CoreAnyExecuteParams
|
|
26
|
+
from .interfaces import CoreExecuteOptionsParameter
|
|
27
|
+
from .interfaces import Dialect
|
|
28
|
+
from .url import URL
|
|
29
|
+
from ..sql.base import Executable
|
|
30
|
+
from ..sql.ddl import InvokeDDLBase
|
|
31
|
+
from ..sql.schema import HasSchemaAttr
|
|
32
|
+
from ..sql.visitors import Visitable
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class MockConnection:
|
|
36
|
+
def __init__(self, dialect: Dialect, execute: Callable[..., Any]):
|
|
37
|
+
self._dialect = dialect
|
|
38
|
+
self._execute_impl = execute
|
|
39
|
+
|
|
40
|
+
engine: Engine = cast(Any, property(lambda s: s))
|
|
41
|
+
dialect: Dialect = cast(Any, property(attrgetter("_dialect")))
|
|
42
|
+
name: str = cast(Any, property(lambda s: s._dialect.name))
|
|
43
|
+
|
|
44
|
+
def connect(self, **kwargs: Any) -> MockConnection:
|
|
45
|
+
return self
|
|
46
|
+
|
|
47
|
+
def schema_for_object(self, obj: HasSchemaAttr) -> Optional[str]:
|
|
48
|
+
return obj.schema
|
|
49
|
+
|
|
50
|
+
def execution_options(self, **kw: Any) -> MockConnection:
|
|
51
|
+
return self
|
|
52
|
+
|
|
53
|
+
def _run_ddl_visitor(
|
|
54
|
+
self,
|
|
55
|
+
visitorcallable: Type[InvokeDDLBase],
|
|
56
|
+
element: Visitable,
|
|
57
|
+
**kwargs: Any,
|
|
58
|
+
) -> None:
|
|
59
|
+
kwargs["checkfirst"] = False
|
|
60
|
+
visitorcallable(
|
|
61
|
+
dialect=self.dialect, connection=self, **kwargs
|
|
62
|
+
).traverse_single(element)
|
|
63
|
+
|
|
64
|
+
def execute(
|
|
65
|
+
self,
|
|
66
|
+
obj: Executable,
|
|
67
|
+
parameters: Optional[_CoreAnyExecuteParams] = None,
|
|
68
|
+
execution_options: Optional[CoreExecuteOptionsParameter] = None,
|
|
69
|
+
) -> Any:
|
|
70
|
+
return self._execute_impl(obj, parameters)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def create_mock_engine(
|
|
74
|
+
url: Union[str, URL], executor: Any, **kw: Any
|
|
75
|
+
) -> MockConnection:
|
|
76
|
+
"""Create a "mock" engine used for echoing DDL.
|
|
77
|
+
|
|
78
|
+
This is a utility function used for debugging or storing the output of DDL
|
|
79
|
+
sequences as generated by :meth:`_schema.MetaData.create_all`
|
|
80
|
+
and related methods.
|
|
81
|
+
|
|
82
|
+
The function accepts a URL which is used only to determine the kind of
|
|
83
|
+
dialect to be used, as well as an "executor" callable function which
|
|
84
|
+
will receive a SQL expression object and parameters, which can then be
|
|
85
|
+
echoed or otherwise printed. The executor's return value is not handled,
|
|
86
|
+
nor does the engine allow regular string statements to be invoked, and
|
|
87
|
+
is therefore only useful for DDL that is sent to the database without
|
|
88
|
+
receiving any results.
|
|
89
|
+
|
|
90
|
+
E.g.::
|
|
91
|
+
|
|
92
|
+
from sqlalchemy import create_mock_engine
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def dump(sql, *multiparams, **params):
|
|
96
|
+
print(sql.compile(dialect=engine.dialect))
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
engine = create_mock_engine("postgresql+psycopg2://", dump)
|
|
100
|
+
metadata.create_all(engine, checkfirst=False)
|
|
101
|
+
|
|
102
|
+
:param url: A string URL which typically needs to contain only the
|
|
103
|
+
database backend name.
|
|
104
|
+
|
|
105
|
+
:param executor: a callable which receives the arguments ``sql``,
|
|
106
|
+
``*multiparams`` and ``**params``. The ``sql`` parameter is typically
|
|
107
|
+
an instance of :class:`.ExecutableDDLElement`, which can then be compiled
|
|
108
|
+
into a string using :meth:`.ExecutableDDLElement.compile`.
|
|
109
|
+
|
|
110
|
+
.. versionadded:: 1.4 - the :func:`.create_mock_engine` function replaces
|
|
111
|
+
the previous "mock" engine strategy used with
|
|
112
|
+
:func:`_sa.create_engine`.
|
|
113
|
+
|
|
114
|
+
.. seealso::
|
|
115
|
+
|
|
116
|
+
:ref:`faq_ddl_as_string`
|
|
117
|
+
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
# create url.URL object
|
|
121
|
+
u = _url.make_url(url)
|
|
122
|
+
|
|
123
|
+
dialect_cls = u.get_dialect()
|
|
124
|
+
|
|
125
|
+
dialect_args = {}
|
|
126
|
+
# consume dialect arguments from kwargs
|
|
127
|
+
for k in util.get_cls_kwargs(dialect_cls):
|
|
128
|
+
if k in kw:
|
|
129
|
+
dialect_args[k] = kw.pop(k)
|
|
130
|
+
|
|
131
|
+
# create dialect
|
|
132
|
+
dialect = dialect_cls(**dialect_args)
|
|
133
|
+
|
|
134
|
+
return MockConnection(dialect, executor)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# engine/processors.py
|
|
2
|
+
# Copyright (C) 2010-2026 the SQLAlchemy authors and contributors
|
|
3
|
+
# <see AUTHORS file>
|
|
4
|
+
# Copyright (C) 2010 Gaetan de Menten gdementen@gmail.com
|
|
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
|
+
"""defines generic type conversion functions, as used in bind and result
|
|
10
|
+
processors.
|
|
11
|
+
|
|
12
|
+
They all share one common characteristic: None is passed through unchanged.
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import datetime
|
|
18
|
+
from typing import Callable
|
|
19
|
+
from typing import Optional
|
|
20
|
+
from typing import Pattern
|
|
21
|
+
from typing import TypeVar
|
|
22
|
+
from typing import Union
|
|
23
|
+
|
|
24
|
+
from ._processors_cy import int_to_boolean as int_to_boolean # noqa: F401
|
|
25
|
+
from ._processors_cy import str_to_date as str_to_date # noqa: F401
|
|
26
|
+
from ._processors_cy import str_to_datetime as str_to_datetime # noqa: F401
|
|
27
|
+
from ._processors_cy import str_to_time as str_to_time # noqa: F401
|
|
28
|
+
from ._processors_cy import to_float as to_float # noqa: F401
|
|
29
|
+
from ._processors_cy import to_str as to_str # noqa: F401
|
|
30
|
+
|
|
31
|
+
if True:
|
|
32
|
+
from ._processors_cy import ( # noqa: F401
|
|
33
|
+
to_decimal_processor_factory as to_decimal_processor_factory,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
_DT = TypeVar(
|
|
38
|
+
"_DT", bound=Union[datetime.datetime, datetime.time, datetime.date]
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def str_to_datetime_processor_factory(
|
|
43
|
+
regexp: Pattern[str], type_: Callable[..., _DT]
|
|
44
|
+
) -> Callable[[Optional[str]], Optional[_DT]]:
|
|
45
|
+
rmatch = regexp.match
|
|
46
|
+
# Even on python2.6 datetime.strptime is both slower than this code
|
|
47
|
+
# and it does not support microseconds.
|
|
48
|
+
has_named_groups = bool(regexp.groupindex)
|
|
49
|
+
|
|
50
|
+
def process(value: Optional[str]) -> Optional[_DT]:
|
|
51
|
+
if value is None:
|
|
52
|
+
return None
|
|
53
|
+
else:
|
|
54
|
+
try:
|
|
55
|
+
m = rmatch(value)
|
|
56
|
+
except TypeError as err:
|
|
57
|
+
raise ValueError(
|
|
58
|
+
"Couldn't parse %s string '%r' "
|
|
59
|
+
"- value is not a string." % (type_.__name__, value)
|
|
60
|
+
) from err
|
|
61
|
+
|
|
62
|
+
if m is None:
|
|
63
|
+
raise ValueError(
|
|
64
|
+
"Couldn't parse %s string: "
|
|
65
|
+
"'%s'" % (type_.__name__, value)
|
|
66
|
+
)
|
|
67
|
+
if has_named_groups:
|
|
68
|
+
groups = m.groupdict(0)
|
|
69
|
+
return type_(
|
|
70
|
+
**dict(
|
|
71
|
+
list(
|
|
72
|
+
zip(
|
|
73
|
+
iter(groups.keys()),
|
|
74
|
+
list(map(int, iter(groups.values()))),
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
)
|
|
79
|
+
else:
|
|
80
|
+
return type_(*list(map(int, m.groups(0))))
|
|
81
|
+
|
|
82
|
+
return process
|