sqlspec 0.47.0__cp314-cp314-win_amd64.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.
- f68e0789eb443ecb1c2c__mypyc.cp314-win_amd64.pyd +0 -0
- sqlspec/__init__.py +167 -0
- sqlspec/__main__.py +12 -0
- sqlspec/__metadata__.py +14 -0
- sqlspec/_typing.py +714 -0
- sqlspec/adapters/__init__.py +0 -0
- sqlspec/adapters/adbc/__init__.py +13 -0
- sqlspec/adapters/adbc/_typing.py +106 -0
- sqlspec/adapters/adbc/adk/__init__.py +5 -0
- sqlspec/adapters/adbc/adk/store.py +1280 -0
- sqlspec/adapters/adbc/config.py +378 -0
- sqlspec/adapters/adbc/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/adbc/core.py +922 -0
- sqlspec/adapters/adbc/data_dictionary.py +339 -0
- sqlspec/adapters/adbc/driver.py +534 -0
- sqlspec/adapters/adbc/events/__init__.py +5 -0
- sqlspec/adapters/adbc/events/store.py +285 -0
- sqlspec/adapters/adbc/litestar/__init__.py +5 -0
- sqlspec/adapters/adbc/litestar/store.py +534 -0
- sqlspec/adapters/adbc/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/adbc/type_converter.py +142 -0
- sqlspec/adapters/aiomysql/__init__.py +21 -0
- sqlspec/adapters/aiomysql/_typing.py +137 -0
- sqlspec/adapters/aiomysql/adk/__init__.py +5 -0
- sqlspec/adapters/aiomysql/adk/store.py +678 -0
- sqlspec/adapters/aiomysql/config.py +305 -0
- sqlspec/adapters/aiomysql/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/aiomysql/core.py +536 -0
- sqlspec/adapters/aiomysql/data_dictionary.py +121 -0
- sqlspec/adapters/aiomysql/driver.py +386 -0
- sqlspec/adapters/aiomysql/events/__init__.py +5 -0
- sqlspec/adapters/aiomysql/events/store.py +104 -0
- sqlspec/adapters/aiomysql/litestar/__init__.py +5 -0
- sqlspec/adapters/aiomysql/litestar/store.py +314 -0
- sqlspec/adapters/aiosqlite/__init__.py +26 -0
- sqlspec/adapters/aiosqlite/_typing.py +109 -0
- sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/adk/store.py +829 -0
- sqlspec/adapters/aiosqlite/config.py +315 -0
- sqlspec/adapters/aiosqlite/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/aiosqlite/core.py +315 -0
- sqlspec/adapters/aiosqlite/data_dictionary.py +202 -0
- sqlspec/adapters/aiosqlite/driver.py +311 -0
- sqlspec/adapters/aiosqlite/events/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/events/store.py +20 -0
- sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/litestar/store.py +279 -0
- sqlspec/adapters/aiosqlite/pool.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/aiosqlite/pool.py +734 -0
- sqlspec/adapters/asyncmy/__init__.py +21 -0
- sqlspec/adapters/asyncmy/_typing.py +113 -0
- sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
- sqlspec/adapters/asyncmy/adk/store.py +644 -0
- sqlspec/adapters/asyncmy/config.py +307 -0
- sqlspec/adapters/asyncmy/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/asyncmy/core.py +538 -0
- sqlspec/adapters/asyncmy/data_dictionary.py +122 -0
- sqlspec/adapters/asyncmy/driver.py +391 -0
- sqlspec/adapters/asyncmy/events/__init__.py +5 -0
- sqlspec/adapters/asyncmy/events/store.py +104 -0
- sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncmy/litestar/store.py +296 -0
- sqlspec/adapters/asyncpg/__init__.py +26 -0
- sqlspec/adapters/asyncpg/_typing.py +103 -0
- sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
- sqlspec/adapters/asyncpg/adk/store.py +483 -0
- sqlspec/adapters/asyncpg/config.py +575 -0
- sqlspec/adapters/asyncpg/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/asyncpg/core.py +480 -0
- sqlspec/adapters/asyncpg/data_dictionary.py +157 -0
- sqlspec/adapters/asyncpg/driver.py +487 -0
- sqlspec/adapters/asyncpg/events/__init__.py +6 -0
- sqlspec/adapters/asyncpg/events/_hub.py +181 -0
- sqlspec/adapters/asyncpg/events/backend.py +210 -0
- sqlspec/adapters/asyncpg/events/store.py +40 -0
- sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncpg/litestar/store.py +251 -0
- sqlspec/adapters/bigquery/__init__.py +15 -0
- sqlspec/adapters/bigquery/_typing.py +108 -0
- sqlspec/adapters/bigquery/config.py +362 -0
- sqlspec/adapters/bigquery/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/bigquery/core.py +768 -0
- sqlspec/adapters/bigquery/data_dictionary.py +120 -0
- sqlspec/adapters/bigquery/driver.py +542 -0
- sqlspec/adapters/bigquery/events/__init__.py +5 -0
- sqlspec/adapters/bigquery/events/store.py +139 -0
- sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
- sqlspec/adapters/bigquery/litestar/store.py +325 -0
- sqlspec/adapters/bigquery/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/bigquery/type_converter.py +107 -0
- sqlspec/adapters/cockroach_asyncpg/__init__.py +26 -0
- sqlspec/adapters/cockroach_asyncpg/_typing.py +73 -0
- sqlspec/adapters/cockroach_asyncpg/adk/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/adk/store.py +465 -0
- sqlspec/adapters/cockroach_asyncpg/config.py +248 -0
- sqlspec/adapters/cockroach_asyncpg/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/cockroach_asyncpg/core.py +55 -0
- sqlspec/adapters/cockroach_asyncpg/data_dictionary.py +110 -0
- sqlspec/adapters/cockroach_asyncpg/driver.py +142 -0
- sqlspec/adapters/cockroach_asyncpg/events/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/events/store.py +20 -0
- sqlspec/adapters/cockroach_asyncpg/litestar/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/litestar/store.py +142 -0
- sqlspec/adapters/cockroach_psycopg/__init__.py +39 -0
- sqlspec/adapters/cockroach_psycopg/_typing.py +137 -0
- sqlspec/adapters/cockroach_psycopg/adk/__init__.py +13 -0
- sqlspec/adapters/cockroach_psycopg/adk/store.py +1039 -0
- sqlspec/adapters/cockroach_psycopg/config.py +511 -0
- sqlspec/adapters/cockroach_psycopg/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/cockroach_psycopg/core.py +63 -0
- sqlspec/adapters/cockroach_psycopg/data_dictionary.py +220 -0
- sqlspec/adapters/cockroach_psycopg/driver.py +273 -0
- sqlspec/adapters/cockroach_psycopg/events/__init__.py +6 -0
- sqlspec/adapters/cockroach_psycopg/events/store.py +34 -0
- sqlspec/adapters/cockroach_psycopg/litestar/__init__.py +3 -0
- sqlspec/adapters/cockroach_psycopg/litestar/store.py +327 -0
- sqlspec/adapters/duckdb/__init__.py +29 -0
- sqlspec/adapters/duckdb/_typing.py +104 -0
- sqlspec/adapters/duckdb/adk/__init__.py +14 -0
- sqlspec/adapters/duckdb/adk/store.py +935 -0
- sqlspec/adapters/duckdb/config.py +386 -0
- sqlspec/adapters/duckdb/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/duckdb/core.py +332 -0
- sqlspec/adapters/duckdb/data_dictionary.py +140 -0
- sqlspec/adapters/duckdb/driver.py +426 -0
- sqlspec/adapters/duckdb/events/__init__.py +5 -0
- sqlspec/adapters/duckdb/events/store.py +57 -0
- sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
- sqlspec/adapters/duckdb/litestar/store.py +330 -0
- sqlspec/adapters/duckdb/pool.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/duckdb/pool.py +350 -0
- sqlspec/adapters/duckdb/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/duckdb/type_converter.py +118 -0
- sqlspec/adapters/mysqlconnector/__init__.py +39 -0
- sqlspec/adapters/mysqlconnector/_typing.py +186 -0
- sqlspec/adapters/mysqlconnector/adk/__init__.py +15 -0
- sqlspec/adapters/mysqlconnector/adk/store.py +1183 -0
- sqlspec/adapters/mysqlconnector/config.py +421 -0
- sqlspec/adapters/mysqlconnector/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/mysqlconnector/core.py +472 -0
- sqlspec/adapters/mysqlconnector/data_dictionary.py +230 -0
- sqlspec/adapters/mysqlconnector/driver.py +516 -0
- sqlspec/adapters/mysqlconnector/events/__init__.py +8 -0
- sqlspec/adapters/mysqlconnector/events/store.py +98 -0
- sqlspec/adapters/mysqlconnector/litestar/__init__.py +5 -0
- sqlspec/adapters/mysqlconnector/litestar/store.py +426 -0
- sqlspec/adapters/oracledb/__init__.py +39 -0
- sqlspec/adapters/oracledb/_json_handlers.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/_json_handlers.py +196 -0
- sqlspec/adapters/oracledb/_param_types.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/_param_types.py +46 -0
- sqlspec/adapters/oracledb/_typing.py +258 -0
- sqlspec/adapters/oracledb/_uuid_handlers.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/_uuid_handlers.py +163 -0
- sqlspec/adapters/oracledb/_vector_handlers.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/_vector_handlers.py +228 -0
- sqlspec/adapters/oracledb/adk/__init__.py +21 -0
- sqlspec/adapters/oracledb/adk/store.py +2453 -0
- sqlspec/adapters/oracledb/config.py +575 -0
- sqlspec/adapters/oracledb/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/core.py +820 -0
- sqlspec/adapters/oracledb/data_dictionary.py +404 -0
- sqlspec/adapters/oracledb/driver.py +1277 -0
- sqlspec/adapters/oracledb/events/__init__.py +16 -0
- sqlspec/adapters/oracledb/events/_hub.py +345 -0
- sqlspec/adapters/oracledb/events/backend.py +300 -0
- sqlspec/adapters/oracledb/events/store.py +420 -0
- sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
- sqlspec/adapters/oracledb/litestar/store.py +781 -0
- sqlspec/adapters/oracledb/migrations.py +539 -0
- sqlspec/adapters/oracledb/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/type_converter.py +211 -0
- sqlspec/adapters/psqlpy/__init__.py +18 -0
- sqlspec/adapters/psqlpy/_typing.py +121 -0
- sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
- sqlspec/adapters/psqlpy/adk/store.py +591 -0
- sqlspec/adapters/psqlpy/config.py +376 -0
- sqlspec/adapters/psqlpy/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/psqlpy/core.py +694 -0
- sqlspec/adapters/psqlpy/data_dictionary.py +121 -0
- sqlspec/adapters/psqlpy/driver.py +411 -0
- sqlspec/adapters/psqlpy/events/__init__.py +6 -0
- sqlspec/adapters/psqlpy/events/_hub.py +204 -0
- sqlspec/adapters/psqlpy/events/backend.py +210 -0
- sqlspec/adapters/psqlpy/events/store.py +20 -0
- sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
- sqlspec/adapters/psqlpy/litestar/store.py +270 -0
- sqlspec/adapters/psqlpy/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/psqlpy/type_converter.py +113 -0
- sqlspec/adapters/psycopg/__init__.py +38 -0
- sqlspec/adapters/psycopg/_typing.py +218 -0
- sqlspec/adapters/psycopg/adk/__init__.py +10 -0
- sqlspec/adapters/psycopg/adk/store.py +1106 -0
- sqlspec/adapters/psycopg/config.py +695 -0
- sqlspec/adapters/psycopg/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/psycopg/core.py +520 -0
- sqlspec/adapters/psycopg/data_dictionary.py +278 -0
- sqlspec/adapters/psycopg/driver.py +1033 -0
- sqlspec/adapters/psycopg/events/__init__.py +20 -0
- sqlspec/adapters/psycopg/events/_hub.py +388 -0
- sqlspec/adapters/psycopg/events/backend.py +398 -0
- sqlspec/adapters/psycopg/events/store.py +42 -0
- sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
- sqlspec/adapters/psycopg/litestar/store.py +554 -0
- sqlspec/adapters/psycopg/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/psycopg/type_converter.py +93 -0
- sqlspec/adapters/pymysql/__init__.py +21 -0
- sqlspec/adapters/pymysql/_typing.py +92 -0
- sqlspec/adapters/pymysql/adk/__init__.py +5 -0
- sqlspec/adapters/pymysql/adk/store.py +657 -0
- sqlspec/adapters/pymysql/config.py +176 -0
- sqlspec/adapters/pymysql/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/pymysql/core.py +469 -0
- sqlspec/adapters/pymysql/data_dictionary.py +120 -0
- sqlspec/adapters/pymysql/driver.py +271 -0
- sqlspec/adapters/pymysql/events/__init__.py +5 -0
- sqlspec/adapters/pymysql/events/store.py +50 -0
- sqlspec/adapters/pymysql/litestar/__init__.py +5 -0
- sqlspec/adapters/pymysql/litestar/store.py +232 -0
- sqlspec/adapters/pymysql/pool.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/pymysql/pool.py +184 -0
- sqlspec/adapters/spanner/__init__.py +33 -0
- sqlspec/adapters/spanner/_typing.py +102 -0
- sqlspec/adapters/spanner/adk/__init__.py +5 -0
- sqlspec/adapters/spanner/adk/store.py +758 -0
- sqlspec/adapters/spanner/config.py +355 -0
- sqlspec/adapters/spanner/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/spanner/core.py +263 -0
- sqlspec/adapters/spanner/data_dictionary.py +120 -0
- sqlspec/adapters/spanner/driver.py +407 -0
- sqlspec/adapters/spanner/events/__init__.py +5 -0
- sqlspec/adapters/spanner/events/store.py +187 -0
- sqlspec/adapters/spanner/litestar/__init__.py +5 -0
- sqlspec/adapters/spanner/litestar/store.py +291 -0
- sqlspec/adapters/spanner/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/spanner/type_converter.py +342 -0
- sqlspec/adapters/sqlite/__init__.py +19 -0
- sqlspec/adapters/sqlite/_typing.py +123 -0
- sqlspec/adapters/sqlite/adk/__init__.py +5 -0
- sqlspec/adapters/sqlite/adk/store.py +992 -0
- sqlspec/adapters/sqlite/config.py +240 -0
- sqlspec/adapters/sqlite/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/sqlite/core.py +357 -0
- sqlspec/adapters/sqlite/data_dictionary.py +198 -0
- sqlspec/adapters/sqlite/driver.py +527 -0
- sqlspec/adapters/sqlite/events/__init__.py +5 -0
- sqlspec/adapters/sqlite/events/store.py +20 -0
- sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/sqlite/litestar/store.py +316 -0
- sqlspec/adapters/sqlite/pool.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/sqlite/pool.py +237 -0
- sqlspec/adapters/sqlite/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/sqlite/type_converter.py +114 -0
- sqlspec/base.py +832 -0
- sqlspec/builder/__init__.py +181 -0
- sqlspec/builder/_base.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_base.py +1071 -0
- sqlspec/builder/_column.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_column.py +521 -0
- sqlspec/builder/_ddl.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_ddl.py +1691 -0
- sqlspec/builder/_delete.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_delete.py +95 -0
- sqlspec/builder/_dml.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_dml.py +386 -0
- sqlspec/builder/_explain.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_explain.py +579 -0
- sqlspec/builder/_expression_wrappers.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_expression_wrappers.py +46 -0
- sqlspec/builder/_factory.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_factory.py +1884 -0
- sqlspec/builder/_insert.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_insert.py +405 -0
- sqlspec/builder/_join.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_join.py +489 -0
- sqlspec/builder/_merge.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_merge.py +823 -0
- sqlspec/builder/_parsing_utils.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_parsing_utils.py +295 -0
- sqlspec/builder/_select.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_select.py +1666 -0
- sqlspec/builder/_temporal.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_temporal.py +167 -0
- sqlspec/builder/_update.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_update.py +173 -0
- sqlspec/builder/_vector_distance.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_vector_distance.py +330 -0
- sqlspec/cli.py +1095 -0
- sqlspec/config.py +2383 -0
- sqlspec/core/__init__.py +372 -0
- sqlspec/core/_correlation.cp314-win_amd64.pyd +0 -0
- sqlspec/core/_correlation.py +176 -0
- sqlspec/core/_pagination.py +42 -0
- sqlspec/core/_pool.cp314-win_amd64.pyd +0 -0
- sqlspec/core/_pool.py +76 -0
- sqlspec/core/cache.cp314-win_amd64.pyd +0 -0
- sqlspec/core/cache.py +1085 -0
- sqlspec/core/compiler.cp314-win_amd64.pyd +0 -0
- sqlspec/core/compiler.py +1090 -0
- sqlspec/core/config_runtime.cp314-win_amd64.pyd +0 -0
- sqlspec/core/config_runtime.py +174 -0
- sqlspec/core/explain.cp314-win_amd64.pyd +0 -0
- sqlspec/core/explain.py +275 -0
- sqlspec/core/filters.cp314-win_amd64.pyd +0 -0
- sqlspec/core/filters.py +969 -0
- sqlspec/core/hashing.cp314-win_amd64.pyd +0 -0
- sqlspec/core/hashing.py +266 -0
- sqlspec/core/metrics.cp314-win_amd64.pyd +0 -0
- sqlspec/core/metrics.py +83 -0
- sqlspec/core/parameters/__init__.py +72 -0
- sqlspec/core/parameters/_alignment.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_alignment.py +283 -0
- sqlspec/core/parameters/_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_converter.py +554 -0
- sqlspec/core/parameters/_processor.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_processor.py +1182 -0
- sqlspec/core/parameters/_registry.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_registry.py +206 -0
- sqlspec/core/parameters/_transformers.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_transformers.py +324 -0
- sqlspec/core/parameters/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_types.py +536 -0
- sqlspec/core/parameters/_validator.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_validator.py +171 -0
- sqlspec/core/pipeline.cp314-win_amd64.pyd +0 -0
- sqlspec/core/pipeline.py +333 -0
- sqlspec/core/query_modifiers.cp314-win_amd64.pyd +0 -0
- sqlspec/core/query_modifiers.py +508 -0
- sqlspec/core/result/__init__.py +25 -0
- sqlspec/core/result/_base.cp314-win_amd64.pyd +0 -0
- sqlspec/core/result/_base.py +1232 -0
- sqlspec/core/result/_io.cp314-win_amd64.pyd +0 -0
- sqlspec/core/result/_io.py +28 -0
- sqlspec/core/splitter.cp314-win_amd64.pyd +0 -0
- sqlspec/core/splitter.py +1021 -0
- sqlspec/core/sqlcommenter.cp314-win_amd64.pyd +0 -0
- sqlspec/core/sqlcommenter.py +249 -0
- sqlspec/core/stack.cp314-win_amd64.pyd +0 -0
- sqlspec/core/stack.py +163 -0
- sqlspec/core/statement.cp314-win_amd64.pyd +0 -0
- sqlspec/core/statement.py +1865 -0
- sqlspec/core/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/core/type_converter.py +340 -0
- sqlspec/data_dictionary/__init__.py +22 -0
- sqlspec/data_dictionary/_loader.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/_loader.py +138 -0
- sqlspec/data_dictionary/_registry.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/_registry.py +74 -0
- sqlspec/data_dictionary/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/_types.py +121 -0
- sqlspec/data_dictionary/dialects/__init__.py +21 -0
- sqlspec/data_dictionary/dialects/bigquery.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/bigquery.py +81 -0
- sqlspec/data_dictionary/dialects/cockroachdb.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/cockroachdb.py +54 -0
- sqlspec/data_dictionary/dialects/duckdb.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/duckdb.py +47 -0
- sqlspec/data_dictionary/dialects/mysql.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/mysql.py +53 -0
- sqlspec/data_dictionary/dialects/oracle.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/oracle.py +197 -0
- sqlspec/data_dictionary/dialects/postgres.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/postgres.py +69 -0
- sqlspec/data_dictionary/dialects/spanner.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/spanner.py +37 -0
- sqlspec/data_dictionary/dialects/sqlite.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/sqlite.py +59 -0
- sqlspec/data_dictionary/sql/.gitkeep +0 -0
- sqlspec/data_dictionary/sql/bigquery/columns.sql +23 -0
- sqlspec/data_dictionary/sql/bigquery/foreign_keys.sql +34 -0
- sqlspec/data_dictionary/sql/bigquery/indexes.sql +19 -0
- sqlspec/data_dictionary/sql/bigquery/tables.sql +33 -0
- sqlspec/data_dictionary/sql/bigquery/version.sql +3 -0
- sqlspec/data_dictionary/sql/cockroachdb/columns.sql +34 -0
- sqlspec/data_dictionary/sql/cockroachdb/foreign_keys.sql +40 -0
- sqlspec/data_dictionary/sql/cockroachdb/indexes.sql +32 -0
- sqlspec/data_dictionary/sql/cockroachdb/tables.sql +44 -0
- sqlspec/data_dictionary/sql/cockroachdb/version.sql +3 -0
- sqlspec/data_dictionary/sql/duckdb/columns.sql +23 -0
- sqlspec/data_dictionary/sql/duckdb/foreign_keys.sql +36 -0
- sqlspec/data_dictionary/sql/duckdb/indexes.sql +19 -0
- sqlspec/data_dictionary/sql/duckdb/tables.sql +38 -0
- sqlspec/data_dictionary/sql/duckdb/version.sql +3 -0
- sqlspec/data_dictionary/sql/mysql/columns.sql +23 -0
- sqlspec/data_dictionary/sql/mysql/foreign_keys.sql +28 -0
- sqlspec/data_dictionary/sql/mysql/indexes.sql +26 -0
- sqlspec/data_dictionary/sql/mysql/tables.sql +33 -0
- sqlspec/data_dictionary/sql/mysql/version.sql +3 -0
- sqlspec/data_dictionary/sql/oracle/columns.sql +23 -0
- sqlspec/data_dictionary/sql/oracle/foreign_keys.sql +48 -0
- sqlspec/data_dictionary/sql/oracle/indexes.sql +44 -0
- sqlspec/data_dictionary/sql/oracle/tables.sql +25 -0
- sqlspec/data_dictionary/sql/oracle/version.sql +20 -0
- sqlspec/data_dictionary/sql/postgres/columns.sql +34 -0
- sqlspec/data_dictionary/sql/postgres/foreign_keys.sql +40 -0
- sqlspec/data_dictionary/sql/postgres/indexes.sql +56 -0
- sqlspec/data_dictionary/sql/postgres/tables.sql +44 -0
- sqlspec/data_dictionary/sql/postgres/version.sql +3 -0
- sqlspec/data_dictionary/sql/spanner/columns.sql +23 -0
- sqlspec/data_dictionary/sql/spanner/foreign_keys.sql +70 -0
- sqlspec/data_dictionary/sql/spanner/indexes.sql +30 -0
- sqlspec/data_dictionary/sql/spanner/tables.sql +9 -0
- sqlspec/data_dictionary/sql/spanner/version.sql +3 -0
- sqlspec/data_dictionary/sql/sqlite/columns.sql +23 -0
- sqlspec/data_dictionary/sql/sqlite/foreign_keys.sql +22 -0
- sqlspec/data_dictionary/sql/sqlite/indexes.sql +7 -0
- sqlspec/data_dictionary/sql/sqlite/tables.sql +28 -0
- sqlspec/data_dictionary/sql/sqlite/version.sql +3 -0
- sqlspec/dialects/__init__.py +22 -0
- sqlspec/dialects/_compat.cp314-win_amd64.pyd +0 -0
- sqlspec/dialects/_compat.py +14 -0
- sqlspec/dialects/postgres/__init__.py +9 -0
- sqlspec/dialects/postgres/_generators.cp314-win_amd64.pyd +0 -0
- sqlspec/dialects/postgres/_generators.py +57 -0
- sqlspec/dialects/postgres/_operators.cp314-win_amd64.pyd +0 -0
- sqlspec/dialects/postgres/_operators.py +81 -0
- sqlspec/dialects/postgres/_paradedb.py +50 -0
- sqlspec/dialects/postgres/_pgvector.py +36 -0
- sqlspec/dialects/spanner/__init__.py +6 -0
- sqlspec/dialects/spanner/_generators.cp314-win_amd64.pyd +0 -0
- sqlspec/dialects/spanner/_generators.py +206 -0
- sqlspec/dialects/spanner/_spangres.py +77 -0
- sqlspec/dialects/spanner/_spanner.py +179 -0
- sqlspec/driver/__init__.py +49 -0
- sqlspec/driver/_async.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_async.py +1830 -0
- sqlspec/driver/_common.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_common.py +2292 -0
- sqlspec/driver/_exception_handler.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_exception_handler.py +108 -0
- sqlspec/driver/_query_cache.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_query_cache.py +96 -0
- sqlspec/driver/_sql_helpers.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_sql_helpers.py +139 -0
- sqlspec/driver/_storage_helpers.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_storage_helpers.py +153 -0
- sqlspec/driver/_sync.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_sync.py +1817 -0
- sqlspec/exceptions.cp314-win_amd64.pyd +0 -0
- sqlspec/exceptions.py +480 -0
- sqlspec/extensions/__init__.py +0 -0
- sqlspec/extensions/adk/__init__.py +84 -0
- sqlspec/extensions/adk/_config_utils.py +199 -0
- sqlspec/extensions/adk/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/adk/_types.py +41 -0
- sqlspec/extensions/adk/artifact/__init__.py +57 -0
- sqlspec/extensions/adk/artifact/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/adk/artifact/_types.py +32 -0
- sqlspec/extensions/adk/artifact/service.py +508 -0
- sqlspec/extensions/adk/artifact/store.py +361 -0
- sqlspec/extensions/adk/converters.py +212 -0
- sqlspec/extensions/adk/memory/__init__.py +69 -0
- sqlspec/extensions/adk/memory/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/adk/memory/_types.py +30 -0
- sqlspec/extensions/adk/memory/converters.py +225 -0
- sqlspec/extensions/adk/memory/service.py +316 -0
- sqlspec/extensions/adk/memory/store.py +525 -0
- sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +184 -0
- sqlspec/extensions/adk/migrations/__init__.py +0 -0
- sqlspec/extensions/adk/service.py +279 -0
- sqlspec/extensions/adk/store.py +590 -0
- sqlspec/extensions/events/__init__.py +51 -0
- sqlspec/extensions/events/_channel.py +703 -0
- sqlspec/extensions/events/_hints.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/events/_hints.py +45 -0
- sqlspec/extensions/events/_models.py +23 -0
- sqlspec/extensions/events/_payload.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/events/_payload.py +69 -0
- sqlspec/extensions/events/_protocols.py +134 -0
- sqlspec/extensions/events/_queue.py +462 -0
- sqlspec/extensions/events/_store.py +209 -0
- sqlspec/extensions/events/migrations/0001_create_event_queue.py +59 -0
- sqlspec/extensions/events/migrations/__init__.py +3 -0
- sqlspec/extensions/fastapi/__init__.py +22 -0
- sqlspec/extensions/fastapi/extension.py +391 -0
- sqlspec/extensions/fastapi/providers.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/fastapi/providers.py +712 -0
- sqlspec/extensions/flask/__init__.py +38 -0
- sqlspec/extensions/flask/_state.py +87 -0
- sqlspec/extensions/flask/_utils.py +71 -0
- sqlspec/extensions/flask/extension.py +539 -0
- sqlspec/extensions/litestar/__init__.py +31 -0
- sqlspec/extensions/litestar/_utils.py +52 -0
- sqlspec/extensions/litestar/channels.py +165 -0
- sqlspec/extensions/litestar/cli.py +102 -0
- sqlspec/extensions/litestar/config.py +90 -0
- sqlspec/extensions/litestar/handlers.py +316 -0
- sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
- sqlspec/extensions/litestar/migrations/__init__.py +3 -0
- sqlspec/extensions/litestar/plugin.py +1066 -0
- sqlspec/extensions/litestar/providers.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/litestar/providers.py +784 -0
- sqlspec/extensions/litestar/store.py +298 -0
- sqlspec/extensions/otel/__init__.py +58 -0
- sqlspec/extensions/prometheus/__init__.py +113 -0
- sqlspec/extensions/sanic/__init__.py +19 -0
- sqlspec/extensions/sanic/_state.py +43 -0
- sqlspec/extensions/sanic/_utils.py +127 -0
- sqlspec/extensions/sanic/extension.py +647 -0
- sqlspec/extensions/starlette/__init__.py +22 -0
- sqlspec/extensions/starlette/_state.py +42 -0
- sqlspec/extensions/starlette/_utils.py +96 -0
- sqlspec/extensions/starlette/extension.py +374 -0
- sqlspec/extensions/starlette/middleware.py +281 -0
- sqlspec/loader.cp314-win_amd64.pyd +0 -0
- sqlspec/loader.py +727 -0
- sqlspec/migrations/__init__.py +39 -0
- sqlspec/migrations/base.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/base.py +862 -0
- sqlspec/migrations/commands.py +2151 -0
- sqlspec/migrations/context.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/context.py +157 -0
- sqlspec/migrations/fix.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/fix.py +204 -0
- sqlspec/migrations/loaders.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/loaders.py +443 -0
- sqlspec/migrations/runner.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/runner.py +1195 -0
- sqlspec/migrations/squash.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/squash.py +490 -0
- sqlspec/migrations/templates.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/templates.py +234 -0
- sqlspec/migrations/tracker.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/tracker.py +792 -0
- sqlspec/migrations/utils.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/utils.py +256 -0
- sqlspec/migrations/validation.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/validation.py +359 -0
- sqlspec/migrations/version.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/version.py +446 -0
- sqlspec/observability/__init__.py +57 -0
- sqlspec/observability/_common.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_common.py +77 -0
- sqlspec/observability/_config.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_config.py +364 -0
- sqlspec/observability/_diagnostics.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_diagnostics.py +74 -0
- sqlspec/observability/_dispatcher.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_dispatcher.py +200 -0
- sqlspec/observability/_formatters/__init__.py +13 -0
- sqlspec/observability/_formatters/_aws.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_formatters/_aws.py +102 -0
- sqlspec/observability/_formatters/_azure.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_formatters/_azure.py +96 -0
- sqlspec/observability/_formatters/_base.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_formatters/_base.py +57 -0
- sqlspec/observability/_formatters/_gcp.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_formatters/_gcp.py +131 -0
- sqlspec/observability/_formatting.py +58 -0
- sqlspec/observability/_observer.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_observer.py +361 -0
- sqlspec/observability/_runtime.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_runtime.py +461 -0
- sqlspec/observability/_sampling.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_sampling.py +188 -0
- sqlspec/observability/_spans.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_spans.py +161 -0
- sqlspec/protocols.py +955 -0
- sqlspec/py.typed +0 -0
- sqlspec/service.py +433 -0
- sqlspec/storage/__init__.py +48 -0
- sqlspec/storage/_arrow_payload.py +68 -0
- sqlspec/storage/_paths.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/_paths.py +58 -0
- sqlspec/storage/_utils.py +46 -0
- sqlspec/storage/backends/__init__.py +1 -0
- sqlspec/storage/backends/base.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/backends/base.py +374 -0
- sqlspec/storage/backends/fsspec.py +574 -0
- sqlspec/storage/backends/local.py +468 -0
- sqlspec/storage/backends/obstore.py +956 -0
- sqlspec/storage/errors.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/errors.py +102 -0
- sqlspec/storage/pipeline.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/pipeline.py +628 -0
- sqlspec/storage/registry.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/registry.py +329 -0
- sqlspec/typing.py +405 -0
- sqlspec/utils/__init__.py +7 -0
- sqlspec/utils/arrow_helpers.py +384 -0
- sqlspec/utils/config_tools.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/config_tools.py +314 -0
- sqlspec/utils/correlation.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/correlation.py +134 -0
- sqlspec/utils/deprecation.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/deprecation.py +157 -0
- sqlspec/utils/dispatch.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/dispatch.py +101 -0
- sqlspec/utils/fixtures.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/fixtures.py +260 -0
- sqlspec/utils/logging.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/logging.py +251 -0
- sqlspec/utils/module_loader.py +306 -0
- sqlspec/utils/portal.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/portal.py +377 -0
- sqlspec/utils/schema.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/schema.py +1040 -0
- sqlspec/utils/serializers/__init__.py +30 -0
- sqlspec/utils/serializers/_json.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/serializers/_json.py +415 -0
- sqlspec/utils/serializers/_numpy.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/serializers/_numpy.py +65 -0
- sqlspec/utils/serializers/_schema.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/serializers/_schema.py +285 -0
- sqlspec/utils/singleton.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/singleton.py +41 -0
- sqlspec/utils/sync_tools.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/sync_tools.py +316 -0
- sqlspec/utils/text.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/text.py +109 -0
- sqlspec/utils/type_converters.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/type_converters.py +216 -0
- sqlspec/utils/type_guards.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/type_guards.py +1508 -0
- sqlspec/utils/uuids.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/uuids.py +241 -0
- sqlspec-0.47.0.dist-info/METADATA +202 -0
- sqlspec-0.47.0.dist-info/RECORD +621 -0
- sqlspec-0.47.0.dist-info/WHEEL +4 -0
- sqlspec-0.47.0.dist-info/entry_points.txt +6 -0
- sqlspec-0.47.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"""Schema dumping and cache helpers for ``sqlspec.utils.serializers``."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from collections import OrderedDict
|
|
5
|
+
from functools import partial
|
|
6
|
+
from threading import RLock
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Final, cast
|
|
8
|
+
|
|
9
|
+
from sqlspec.typing import MSGSPEC_INSTALLED, UNSET, ArrowReturnFormat, attrs_asdict, msgspec_fields
|
|
10
|
+
from sqlspec.utils.arrow_helpers import convert_dict_to_arrow
|
|
11
|
+
from sqlspec.utils.type_guards import (
|
|
12
|
+
dataclass_to_dict,
|
|
13
|
+
has_dict_attribute,
|
|
14
|
+
is_attrs_instance,
|
|
15
|
+
is_dataclass_instance,
|
|
16
|
+
is_dict,
|
|
17
|
+
is_msgspec_struct,
|
|
18
|
+
is_pydantic_model,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from collections.abc import Callable, Iterable
|
|
23
|
+
|
|
24
|
+
__all__ = (
|
|
25
|
+
"SchemaSerializer",
|
|
26
|
+
"get_collection_serializer",
|
|
27
|
+
"get_serializer_metrics",
|
|
28
|
+
"reset_serializer_cache",
|
|
29
|
+
"schema_dump",
|
|
30
|
+
"serialize_collection",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
DEBUG_ENV_FLAG: Final[str] = "SQLSPEC_DEBUG_PIPELINE_CACHE"
|
|
35
|
+
_PRIMITIVE_TYPES: Final[tuple[type[Any], ...]] = (str, bytes, int, float, bool)
|
|
36
|
+
_PRIMITIVE_TYPES_SET: Final[frozenset[type[Any]]] = frozenset(_PRIMITIVE_TYPES)
|
|
37
|
+
_SCHEMA_SERIALIZER_CACHE_MAX_SIZE: Final[int] = 1000
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _is_truthy(value: "str | None") -> bool:
|
|
41
|
+
if value is None:
|
|
42
|
+
return False
|
|
43
|
+
normalized = value.strip().lower()
|
|
44
|
+
return normalized in {"1", "true", "yes", "on"}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
_METRICS_ENABLED: Final[bool] = _is_truthy(os.getenv(DEBUG_ENV_FLAG))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class _SerializerCacheMetrics:
|
|
51
|
+
__slots__ = ("hits", "max_size", "misses", "size")
|
|
52
|
+
|
|
53
|
+
def __init__(self) -> None:
|
|
54
|
+
self.hits = 0
|
|
55
|
+
self.misses = 0
|
|
56
|
+
self.size = 0
|
|
57
|
+
self.max_size = 0
|
|
58
|
+
|
|
59
|
+
def record_hit(self, cache_size: int) -> None:
|
|
60
|
+
if not _METRICS_ENABLED:
|
|
61
|
+
return
|
|
62
|
+
self.hits += 1
|
|
63
|
+
self.size = cache_size
|
|
64
|
+
self.max_size = max(self.max_size, cache_size)
|
|
65
|
+
|
|
66
|
+
def record_miss(self, cache_size: int) -> None:
|
|
67
|
+
if not _METRICS_ENABLED:
|
|
68
|
+
return
|
|
69
|
+
self.misses += 1
|
|
70
|
+
self.size = cache_size
|
|
71
|
+
self.max_size = max(self.max_size, cache_size)
|
|
72
|
+
|
|
73
|
+
def reset(self) -> None:
|
|
74
|
+
self.hits = 0
|
|
75
|
+
self.misses = 0
|
|
76
|
+
self.size = 0
|
|
77
|
+
self.max_size = 0
|
|
78
|
+
|
|
79
|
+
def snapshot(self) -> "dict[str, int]":
|
|
80
|
+
return {
|
|
81
|
+
"hits": self.hits if _METRICS_ENABLED else 0,
|
|
82
|
+
"misses": self.misses if _METRICS_ENABLED else 0,
|
|
83
|
+
"max_size": self.max_size if _METRICS_ENABLED else 0,
|
|
84
|
+
"size": self.size if _METRICS_ENABLED else 0,
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class SchemaSerializer:
|
|
89
|
+
"""Serializer pipeline that caches conversions for repeated schema dumps."""
|
|
90
|
+
|
|
91
|
+
__slots__ = ("_dump", "_key")
|
|
92
|
+
|
|
93
|
+
def __init__(self, key: "tuple[type[Any] | None, bool, bool]", dump: "Callable[[Any], dict[str, Any]]") -> None:
|
|
94
|
+
self._key = key
|
|
95
|
+
self._dump = dump
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def key(self) -> "tuple[type[Any] | None, bool, bool]":
|
|
99
|
+
return self._key
|
|
100
|
+
|
|
101
|
+
def dump_one(self, item: Any) -> "dict[str, Any]":
|
|
102
|
+
return self._dump(item)
|
|
103
|
+
|
|
104
|
+
def dump_many(self, items: "Iterable[Any]") -> "list[dict[str, Any]]":
|
|
105
|
+
return [self._dump(item) for item in items]
|
|
106
|
+
|
|
107
|
+
def to_arrow(
|
|
108
|
+
self, items: "Iterable[Any]", *, return_format: "ArrowReturnFormat" = "table", batch_size: int | None = None
|
|
109
|
+
) -> Any:
|
|
110
|
+
payload = self.dump_many(items)
|
|
111
|
+
return convert_dict_to_arrow(payload, return_format=return_format, batch_size=batch_size)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
_SERIALIZER_LOCK: RLock = RLock()
|
|
115
|
+
_SCHEMA_SERIALIZERS: "OrderedDict[tuple[type[Any] | None, bool, bool], SchemaSerializer]" = OrderedDict()
|
|
116
|
+
_SERIALIZER_METRICS = _SerializerCacheMetrics()
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _make_serializer_key(sample: Any, exclude_unset: bool, wire_format: bool) -> "tuple[type[Any] | None, bool, bool]":
|
|
120
|
+
if sample is None or isinstance(sample, dict):
|
|
121
|
+
return (None, exclude_unset, wire_format)
|
|
122
|
+
return (type(sample), exclude_unset, wire_format)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _dump_identity_dict(value: Any) -> "dict[str, Any]":
|
|
126
|
+
return cast("dict[str, Any]", value)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _get_msgspec_field_pairs(schema_type: type[Any], *, wire_format: bool) -> "tuple[tuple[str, str], ...]":
|
|
130
|
+
if not MSGSPEC_INSTALLED:
|
|
131
|
+
msg = "msgspec is required to serialize msgspec.Struct values"
|
|
132
|
+
raise RuntimeError(msg)
|
|
133
|
+
|
|
134
|
+
if wire_format:
|
|
135
|
+
return tuple((field.encode_name, field.name) for field in msgspec_fields(schema_type))
|
|
136
|
+
return tuple((field.name, field.name) for field in msgspec_fields(schema_type))
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _dump_msgspec_struct(
|
|
140
|
+
value: Any, *, field_pairs: "tuple[tuple[str, str], ...]", exclude_unset: bool
|
|
141
|
+
) -> "dict[str, Any]":
|
|
142
|
+
if not exclude_unset:
|
|
143
|
+
return {output_name: value.__getattribute__(field_name) for output_name, field_name in field_pairs}
|
|
144
|
+
return {
|
|
145
|
+
output_name: field_value
|
|
146
|
+
for output_name, field_name in field_pairs
|
|
147
|
+
if (field_value := value.__getattribute__(field_name)) != UNSET
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _dump_dataclass(value: Any, *, exclude_unset: bool) -> "dict[str, Any]":
|
|
152
|
+
return dataclass_to_dict(value, exclude_empty=exclude_unset)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _dump_pydantic(value: Any, *, exclude_unset: bool) -> "dict[str, Any]":
|
|
156
|
+
return cast("dict[str, Any]", value.model_dump(exclude_unset=exclude_unset))
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def _dump_attrs(value: Any) -> "dict[str, Any]":
|
|
160
|
+
return attrs_asdict(value, recurse=True)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def _dump_dict_attr(value: Any) -> "dict[str, Any]":
|
|
164
|
+
return dict(value.__dict__)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _dump_mapping(value: Any) -> "dict[str, Any]":
|
|
168
|
+
return dict(value)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def _build_msgspec_dump_function(
|
|
172
|
+
sample: Any, *, exclude_unset: bool, wire_format: bool
|
|
173
|
+
) -> "Callable[[Any], dict[str, Any]]":
|
|
174
|
+
field_pairs = _get_msgspec_field_pairs(type(sample), wire_format=wire_format)
|
|
175
|
+
return cast(
|
|
176
|
+
"Callable[[Any], dict[str, Any]]",
|
|
177
|
+
partial(_dump_msgspec_struct, field_pairs=field_pairs, exclude_unset=exclude_unset),
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def _build_dump_function(sample: Any, exclude_unset: bool, wire_format: bool) -> "Callable[[Any], dict[str, Any]]":
|
|
182
|
+
if sample is None or isinstance(sample, dict):
|
|
183
|
+
return _dump_identity_dict
|
|
184
|
+
if is_dataclass_instance(sample):
|
|
185
|
+
return cast("Callable[[Any], dict[str, Any]]", partial(_dump_dataclass, exclude_unset=exclude_unset))
|
|
186
|
+
if is_pydantic_model(sample):
|
|
187
|
+
return cast("Callable[[Any], dict[str, Any]]", partial(_dump_pydantic, exclude_unset=exclude_unset))
|
|
188
|
+
if is_msgspec_struct(sample):
|
|
189
|
+
return _build_msgspec_dump_function(sample, exclude_unset=exclude_unset, wire_format=wire_format)
|
|
190
|
+
if is_attrs_instance(sample):
|
|
191
|
+
return _dump_attrs
|
|
192
|
+
if has_dict_attribute(sample):
|
|
193
|
+
return _dump_dict_attr
|
|
194
|
+
return _dump_mapping
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def get_collection_serializer(
|
|
198
|
+
sample: Any, *, exclude_unset: bool = True, wire_format: bool = False
|
|
199
|
+
) -> "SchemaSerializer":
|
|
200
|
+
"""Return cached serializer pipeline for the provided sample object."""
|
|
201
|
+
key = _make_serializer_key(sample, exclude_unset, wire_format)
|
|
202
|
+
pipeline = _SCHEMA_SERIALIZERS.get(key)
|
|
203
|
+
if pipeline is not None:
|
|
204
|
+
try:
|
|
205
|
+
_SCHEMA_SERIALIZERS.move_to_end(key)
|
|
206
|
+
except KeyError:
|
|
207
|
+
pipeline = None
|
|
208
|
+
else:
|
|
209
|
+
_SERIALIZER_METRICS.record_hit(len(_SCHEMA_SERIALIZERS))
|
|
210
|
+
return pipeline
|
|
211
|
+
|
|
212
|
+
with _SERIALIZER_LOCK:
|
|
213
|
+
pipeline = _SCHEMA_SERIALIZERS.get(key)
|
|
214
|
+
if pipeline is not None:
|
|
215
|
+
_SCHEMA_SERIALIZERS.move_to_end(key)
|
|
216
|
+
_SERIALIZER_METRICS.record_hit(len(_SCHEMA_SERIALIZERS))
|
|
217
|
+
return pipeline
|
|
218
|
+
|
|
219
|
+
dump = _build_dump_function(sample, exclude_unset, wire_format)
|
|
220
|
+
pipeline = SchemaSerializer(key, dump)
|
|
221
|
+
_SCHEMA_SERIALIZERS[key] = pipeline
|
|
222
|
+
if len(_SCHEMA_SERIALIZERS) > _SCHEMA_SERIALIZER_CACHE_MAX_SIZE:
|
|
223
|
+
_SCHEMA_SERIALIZERS.popitem(last=False)
|
|
224
|
+
_SERIALIZER_METRICS.record_miss(len(_SCHEMA_SERIALIZERS))
|
|
225
|
+
return pipeline
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def serialize_collection(
|
|
229
|
+
items: "Iterable[Any]", *, exclude_unset: bool = True, wire_format: bool = False
|
|
230
|
+
) -> "list[Any]":
|
|
231
|
+
"""Serialize a collection using cached pipelines keyed by item type."""
|
|
232
|
+
serialized: list[Any] = []
|
|
233
|
+
cache: dict[tuple[type[Any] | None, bool, bool], SchemaSerializer] = {}
|
|
234
|
+
|
|
235
|
+
for item in items:
|
|
236
|
+
if type(item) in _PRIMITIVE_TYPES_SET or item is None or isinstance(item, dict):
|
|
237
|
+
serialized.append(item)
|
|
238
|
+
continue
|
|
239
|
+
|
|
240
|
+
key = _make_serializer_key(item, exclude_unset, wire_format)
|
|
241
|
+
pipeline = cache.get(key)
|
|
242
|
+
if pipeline is None:
|
|
243
|
+
pipeline = get_collection_serializer(item, exclude_unset=exclude_unset, wire_format=wire_format)
|
|
244
|
+
cache[key] = pipeline
|
|
245
|
+
serialized.append(pipeline.dump_one(item))
|
|
246
|
+
return serialized
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def reset_serializer_cache() -> None:
|
|
250
|
+
"""Clear cached serializer pipelines."""
|
|
251
|
+
with _SERIALIZER_LOCK:
|
|
252
|
+
_SCHEMA_SERIALIZERS.clear()
|
|
253
|
+
_SERIALIZER_METRICS.reset()
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def get_serializer_metrics() -> "dict[str, int]":
|
|
257
|
+
"""Return cache metrics aligned with the core pipeline counters."""
|
|
258
|
+
with _SERIALIZER_LOCK:
|
|
259
|
+
metrics = _SERIALIZER_METRICS.snapshot()
|
|
260
|
+
metrics["size"] = len(_SCHEMA_SERIALIZERS)
|
|
261
|
+
return metrics
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def schema_dump(data: Any, *, exclude_unset: bool = True, wire_format: bool = False) -> Any:
|
|
265
|
+
"""Dump a schema model or dict to a plain representation.
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
data: A schema instance (msgspec.Struct, Pydantic BaseModel, dataclass, attrs class)
|
|
269
|
+
or plain dict / primitive.
|
|
270
|
+
exclude_unset: If True, exclude fields that were never set (msgspec UNSET, Pydantic
|
|
271
|
+
model_fields_set semantics). No-op for attrs (attrs has no unset concept).
|
|
272
|
+
wire_format: msgspec-only knob. Default ``False`` emits Python attribute names
|
|
273
|
+
(``field.name``) for cross-library consistency — keys match Pydantic, dataclass,
|
|
274
|
+
and attrs output regardless of the Struct's ``rename=`` meta. Pass
|
|
275
|
+
``wire_format=True`` to emit ``field.encode_name`` (honours ``rename=`` on the
|
|
276
|
+
Struct) for wire-aligned JSON / API payloads. Pydantic, dataclass, and attrs
|
|
277
|
+
branches always use Python attribute names regardless of this flag.
|
|
278
|
+
"""
|
|
279
|
+
if is_dict(data):
|
|
280
|
+
return data
|
|
281
|
+
if type(data) in _PRIMITIVE_TYPES_SET or data is None:
|
|
282
|
+
return data
|
|
283
|
+
|
|
284
|
+
serializer = get_collection_serializer(data, exclude_unset=exclude_unset, wire_format=wire_format)
|
|
285
|
+
return serializer.dump_one(data)
|
|
Binary file
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Singleton pattern implementation for SQLSpec.
|
|
2
|
+
|
|
3
|
+
Provides a thread-safe metaclass for implementing the singleton pattern.
|
|
4
|
+
Used for creating classes that should have only one instance per class type.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import threading
|
|
8
|
+
from typing import Any, TypeVar
|
|
9
|
+
|
|
10
|
+
from mypy_extensions import mypyc_attr
|
|
11
|
+
|
|
12
|
+
__all__ = ("SingletonMeta",)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
_T = TypeVar("_T")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@mypyc_attr(native_class=False)
|
|
19
|
+
class SingletonMeta(type):
|
|
20
|
+
"""Metaclass for singleton pattern."""
|
|
21
|
+
|
|
22
|
+
_instances: "dict[type, object]" = {}
|
|
23
|
+
_lock = threading.Lock()
|
|
24
|
+
|
|
25
|
+
def __call__(cls: type[_T], *args: Any, **kwargs: Any) -> _T:
|
|
26
|
+
"""Call method for the singleton metaclass.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
cls: The class being instantiated.
|
|
30
|
+
*args: Positional arguments for the class constructor.
|
|
31
|
+
**kwargs: Keyword arguments for the class constructor.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
The singleton instance of the class.
|
|
35
|
+
"""
|
|
36
|
+
if cls not in SingletonMeta._instances: # pyright: ignore[reportUnnecessaryContains]
|
|
37
|
+
with SingletonMeta._lock:
|
|
38
|
+
if cls not in SingletonMeta._instances:
|
|
39
|
+
instance = super().__call__(*args, **kwargs) # type: ignore[misc]
|
|
40
|
+
SingletonMeta._instances[cls] = instance
|
|
41
|
+
return SingletonMeta._instances[cls] # type: ignore[return-value]
|
|
Binary file
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"""Utilities for async/sync interoperability in SQLSpec.
|
|
2
|
+
|
|
3
|
+
This module provides utilities for converting between async and sync functions,
|
|
4
|
+
managing concurrency limits, and handling context managers. Used primarily
|
|
5
|
+
for adapter implementations that need to support both sync and async patterns.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import concurrent.futures
|
|
10
|
+
import functools
|
|
11
|
+
import inspect
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
from contextlib import AbstractAsyncContextManager, AbstractContextManager
|
|
15
|
+
from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast
|
|
16
|
+
|
|
17
|
+
from typing_extensions import ParamSpec
|
|
18
|
+
|
|
19
|
+
from sqlspec.utils.module_loader import module_available
|
|
20
|
+
from sqlspec.utils.portal import get_global_portal
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from collections.abc import Awaitable, Callable, Coroutine
|
|
24
|
+
from types import TracebackType
|
|
25
|
+
|
|
26
|
+
if module_available("uvloop"):
|
|
27
|
+
import uvloop # pyright: ignore[reportMissingImports]
|
|
28
|
+
else:
|
|
29
|
+
uvloop = None # type: ignore[assignment,unused-ignore]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
ReturnT = TypeVar("ReturnT")
|
|
33
|
+
ParamSpecT = ParamSpec("ParamSpecT")
|
|
34
|
+
T = TypeVar("T")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class NoValue:
|
|
38
|
+
"""Sentinel class for missing values."""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
NO_VALUE = NoValue()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class CapacityLimiter:
|
|
45
|
+
"""Limits the number of concurrent operations using a semaphore."""
|
|
46
|
+
|
|
47
|
+
def __init__(self, total_tokens: int) -> None:
|
|
48
|
+
"""Initialize the capacity limiter.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
total_tokens: Maximum number of concurrent operations allowed
|
|
52
|
+
"""
|
|
53
|
+
self._total_tokens = total_tokens
|
|
54
|
+
self._semaphore_instance: asyncio.Semaphore | None = None
|
|
55
|
+
self._pid: int | None = None
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def _semaphore(self) -> asyncio.Semaphore:
|
|
59
|
+
"""Lazy initialization of asyncio.Semaphore with per-process tracking.
|
|
60
|
+
|
|
61
|
+
Reinitializes the semaphore if running in a new process (detected via PID).
|
|
62
|
+
This ensures pytest-xdist workers each get their own semaphore bound to
|
|
63
|
+
their event loop, preventing cross-process deadlocks.
|
|
64
|
+
"""
|
|
65
|
+
current_pid = os.getpid()
|
|
66
|
+
if self._semaphore_instance is None or self._pid != current_pid:
|
|
67
|
+
self._semaphore_instance = asyncio.Semaphore(self._total_tokens)
|
|
68
|
+
self._pid = current_pid
|
|
69
|
+
return self._semaphore_instance
|
|
70
|
+
|
|
71
|
+
async def acquire(self) -> None:
|
|
72
|
+
"""Acquire a token from the semaphore."""
|
|
73
|
+
await self._semaphore.acquire()
|
|
74
|
+
|
|
75
|
+
def release(self) -> None:
|
|
76
|
+
"""Release a token back to the semaphore."""
|
|
77
|
+
self._semaphore.release()
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def total_tokens(self) -> int:
|
|
81
|
+
"""Get the total number of tokens available."""
|
|
82
|
+
return self._total_tokens
|
|
83
|
+
|
|
84
|
+
@total_tokens.setter
|
|
85
|
+
def total_tokens(self, value: int) -> None:
|
|
86
|
+
self._total_tokens = value
|
|
87
|
+
self._semaphore_instance = None
|
|
88
|
+
self._pid = None
|
|
89
|
+
|
|
90
|
+
async def __aenter__(self) -> None:
|
|
91
|
+
"""Async context manager entry."""
|
|
92
|
+
await self.acquire()
|
|
93
|
+
|
|
94
|
+
async def __aexit__(
|
|
95
|
+
self, exc_type: "type[BaseException] | None", exc_val: "BaseException | None", exc_tb: "TracebackType | None"
|
|
96
|
+
) -> None:
|
|
97
|
+
"""Async context manager exit."""
|
|
98
|
+
self.release()
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
_default_limiter = CapacityLimiter(1000)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _return_value(value: Any) -> Any:
|
|
105
|
+
return value
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class _RunWrapper(Generic[ParamSpecT, ReturnT]):
|
|
109
|
+
__slots__ = ("__dict__", "_function")
|
|
110
|
+
|
|
111
|
+
def __init__(self, async_function: "Callable[ParamSpecT, Coroutine[Any, Any, ReturnT]]") -> None:
|
|
112
|
+
self._function = async_function
|
|
113
|
+
functools.update_wrapper(self, async_function)
|
|
114
|
+
|
|
115
|
+
def __call__(self, *args: "ParamSpecT.args", **kwargs: "ParamSpecT.kwargs") -> "ReturnT":
|
|
116
|
+
partial_f = functools.partial(self._function, *args, **kwargs)
|
|
117
|
+
try:
|
|
118
|
+
loop = asyncio.get_running_loop()
|
|
119
|
+
except RuntimeError:
|
|
120
|
+
loop = None
|
|
121
|
+
|
|
122
|
+
if loop is not None:
|
|
123
|
+
if loop.is_running():
|
|
124
|
+
with concurrent.futures.ThreadPoolExecutor() as executor:
|
|
125
|
+
future = executor.submit(asyncio.run, partial_f())
|
|
126
|
+
return future.result()
|
|
127
|
+
return asyncio.run(partial_f())
|
|
128
|
+
if uvloop and sys.platform != "win32":
|
|
129
|
+
return uvloop.run(partial_f()) # pyright: ignore[reportUnknownMemberType]
|
|
130
|
+
return asyncio.run(partial_f())
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def run_(async_function: "Callable[ParamSpecT, Coroutine[Any, Any, ReturnT]]") -> "Callable[ParamSpecT, ReturnT]":
|
|
134
|
+
"""Convert an async function to a blocking function using asyncio.run().
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
async_function: The async function to convert.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
A blocking function that runs the async function.
|
|
141
|
+
"""
|
|
142
|
+
|
|
143
|
+
return _RunWrapper(async_function)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def await_(
|
|
147
|
+
async_function: "Callable[ParamSpecT, Coroutine[Any, Any, ReturnT]]", raise_sync_error: bool = False
|
|
148
|
+
) -> "Callable[ParamSpecT, ReturnT]":
|
|
149
|
+
"""Convert an async function to a blocking one, running in the main async loop.
|
|
150
|
+
|
|
151
|
+
When no event loop exists, automatically creates and uses a global portal for
|
|
152
|
+
async-to-sync bridging via background thread. Set raise_sync_error=True to
|
|
153
|
+
disable this behavior and raise errors instead.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
async_function: The async function to convert.
|
|
157
|
+
raise_sync_error: If True, raises RuntimeError when no loop exists.
|
|
158
|
+
If False (default), uses portal pattern for automatic bridging.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
A blocking function that runs the async function.
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
return _AwaitWrapper(async_function, raise_sync_error)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def async_(
|
|
168
|
+
function: "Callable[ParamSpecT, ReturnT]", *, limiter: "CapacityLimiter | None" = None
|
|
169
|
+
) -> "Callable[ParamSpecT, Awaitable[ReturnT]]":
|
|
170
|
+
"""Convert a blocking function to an async one using asyncio.to_thread().
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
function: The blocking function to convert.
|
|
174
|
+
limiter: Limit the total number of threads.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
An async function that runs the original function in a thread.
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
return _AsyncWrapper(function, limiter)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def ensure_async_(
|
|
184
|
+
function: "Callable[ParamSpecT, Awaitable[ReturnT] | ReturnT]",
|
|
185
|
+
) -> "Callable[ParamSpecT, Awaitable[ReturnT]]":
|
|
186
|
+
"""Convert a function to an async one if it is not already.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
function: The function to convert.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
An async function that runs the original function.
|
|
193
|
+
"""
|
|
194
|
+
if inspect.iscoroutinefunction(function):
|
|
195
|
+
return function
|
|
196
|
+
|
|
197
|
+
return _EnsureAsyncWrapper(function)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class _AwaitWrapper(Generic[ParamSpecT, ReturnT]):
|
|
201
|
+
__slots__ = ("__dict__", "_function", "_raise_sync_error")
|
|
202
|
+
|
|
203
|
+
def __init__(
|
|
204
|
+
self, async_function: "Callable[ParamSpecT, Coroutine[Any, Any, ReturnT]]", raise_sync_error: bool
|
|
205
|
+
) -> None:
|
|
206
|
+
self._function = async_function
|
|
207
|
+
self._raise_sync_error = raise_sync_error
|
|
208
|
+
functools.update_wrapper(self, async_function)
|
|
209
|
+
|
|
210
|
+
def __call__(self, *args: "ParamSpecT.args", **kwargs: "ParamSpecT.kwargs") -> "ReturnT":
|
|
211
|
+
partial_f = functools.partial(self._function, *args, **kwargs)
|
|
212
|
+
try:
|
|
213
|
+
loop = asyncio.get_running_loop()
|
|
214
|
+
except RuntimeError:
|
|
215
|
+
if self._raise_sync_error:
|
|
216
|
+
msg = "Cannot run async function"
|
|
217
|
+
raise RuntimeError(msg) from None
|
|
218
|
+
portal = get_global_portal()
|
|
219
|
+
typed_partial = cast("Callable[[], Coroutine[Any, Any, ReturnT]]", partial_f)
|
|
220
|
+
return portal.call(typed_partial)
|
|
221
|
+
if loop.is_running():
|
|
222
|
+
try:
|
|
223
|
+
current_task = asyncio.current_task(loop=loop)
|
|
224
|
+
except RuntimeError:
|
|
225
|
+
current_task = None
|
|
226
|
+
|
|
227
|
+
if current_task is not None:
|
|
228
|
+
if self._raise_sync_error:
|
|
229
|
+
msg = "await_ cannot be called from within an async task running on the same event loop. Use 'await' instead."
|
|
230
|
+
raise RuntimeError(msg)
|
|
231
|
+
portal = get_global_portal()
|
|
232
|
+
typed_partial = cast("Callable[[], Coroutine[Any, Any, ReturnT]]", partial_f)
|
|
233
|
+
return portal.call(typed_partial)
|
|
234
|
+
future = asyncio.run_coroutine_threadsafe(partial_f(), loop)
|
|
235
|
+
return future.result()
|
|
236
|
+
if self._raise_sync_error:
|
|
237
|
+
msg = "Cannot run async function"
|
|
238
|
+
raise RuntimeError(msg)
|
|
239
|
+
portal = get_global_portal()
|
|
240
|
+
typed_partial = cast("Callable[[], Coroutine[Any, Any, ReturnT]]", partial_f)
|
|
241
|
+
return portal.call(typed_partial)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class _AsyncWrapper(Generic[ParamSpecT, ReturnT]):
|
|
245
|
+
__slots__ = ("__dict__", "_function", "_limiter")
|
|
246
|
+
|
|
247
|
+
def __init__(self, function: "Callable[ParamSpecT, ReturnT]", limiter: "CapacityLimiter | None") -> None:
|
|
248
|
+
self._function = function
|
|
249
|
+
self._limiter = limiter
|
|
250
|
+
functools.update_wrapper(self, function)
|
|
251
|
+
|
|
252
|
+
async def __call__(self, *args: "ParamSpecT.args", **kwargs: "ParamSpecT.kwargs") -> "ReturnT":
|
|
253
|
+
partial_f = functools.partial(self._function, *args, **kwargs)
|
|
254
|
+
if self._limiter is not None:
|
|
255
|
+
async with self._limiter:
|
|
256
|
+
return await asyncio.to_thread(partial_f)
|
|
257
|
+
return await asyncio.to_thread(partial_f)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class _EnsureAsyncWrapper(Generic[ParamSpecT, ReturnT]):
|
|
261
|
+
__slots__ = ("__dict__", "_function")
|
|
262
|
+
|
|
263
|
+
def __init__(self, function: "Callable[ParamSpecT, Awaitable[ReturnT] | ReturnT]") -> None:
|
|
264
|
+
self._function = function
|
|
265
|
+
functools.update_wrapper(self, function)
|
|
266
|
+
|
|
267
|
+
async def __call__(self, *args: "ParamSpecT.args", **kwargs: "ParamSpecT.kwargs") -> "ReturnT":
|
|
268
|
+
result = self._function(*args, **kwargs)
|
|
269
|
+
if inspect.isawaitable(result):
|
|
270
|
+
return await cast("Awaitable[ReturnT]", result)
|
|
271
|
+
return result
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
class _ContextManagerWrapper(Generic[T]):
|
|
275
|
+
def __init__(self, cm: AbstractContextManager[T]) -> None:
|
|
276
|
+
self._cm = cm
|
|
277
|
+
|
|
278
|
+
async def __aenter__(self) -> T:
|
|
279
|
+
return self._cm.__enter__()
|
|
280
|
+
|
|
281
|
+
async def __aexit__(
|
|
282
|
+
self, exc_type: "type[BaseException] | None", exc_val: "BaseException | None", exc_tb: "TracebackType | None"
|
|
283
|
+
) -> "bool | None":
|
|
284
|
+
return self._cm.__exit__(exc_type, exc_val, exc_tb)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def with_ensure_async_(
|
|
288
|
+
obj: "AbstractContextManager[T] | AbstractAsyncContextManager[T]",
|
|
289
|
+
) -> "AbstractAsyncContextManager[T]":
|
|
290
|
+
"""Convert a context manager to an async one if it is not already.
|
|
291
|
+
|
|
292
|
+
Args:
|
|
293
|
+
obj: The context manager to convert.
|
|
294
|
+
|
|
295
|
+
Returns:
|
|
296
|
+
An async context manager that runs the original context manager.
|
|
297
|
+
"""
|
|
298
|
+
if isinstance(obj, AbstractContextManager):
|
|
299
|
+
return cast("AbstractAsyncContextManager[T]", _ContextManagerWrapper(obj))
|
|
300
|
+
return obj
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
async def get_next(iterable: Any, default: Any = NO_VALUE, *args: Any) -> Any: # pragma: no cover
|
|
304
|
+
"""Return the next item from an async iterator.
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
iterable: An async iterable.
|
|
308
|
+
default: An optional default value to return if the iterable is empty.
|
|
309
|
+
*args: The remaining args
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
The next value of the iterable.
|
|
313
|
+
"""
|
|
314
|
+
if isinstance(default, NoValue):
|
|
315
|
+
return await anext(iterable)
|
|
316
|
+
return await anext(iterable, default)
|
|
Binary file
|