From 3d83554c466c13471b3b92744d8960d3553e2b6f Mon Sep 17 00:00:00 2001 From: Niels Pardon Date: Wed, 3 Dec 2025 16:43:27 +0000 Subject: [PATCH] feat: add substrait spec version to plan This PR retrieves the Substrait spec version from the Git submodule and writes it into the plan when using the builders. Signed-off-by: Niels Pardon --- .github/workflows/codegen-check.yml | 10 ++-- CONTRIBUTING.md | 12 +++++ Makefile | 11 ++++ src/substrait/builders/plan.py | 27 +++++++++- src/substrait/gen/__init__.pyi | 1 + src/substrait/gen/version.py | 1 + tests/builders/plan/test_aggregate.py | 3 +- tests/builders/plan/test_cross.py | 5 +- tests/builders/plan/test_fetch.py | 5 +- tests/builders/plan/test_filter.py | 5 +- tests/builders/plan/test_join.py | 5 +- tests/builders/plan/test_project.py | 5 +- tests/builders/plan/test_read.py | 11 ++-- tests/builders/plan/test_set.py | 5 +- tests/builders/plan/test_sort.py | 8 +-- tests/test_uri_urn_migration.py | 11 +++- uv.lock | 78 ++------------------------- 17 files changed, 101 insertions(+), 102 deletions(-) create mode 100644 src/substrait/gen/version.py diff --git a/.github/workflows/codegen-check.yml b/.github/workflows/codegen-check.yml index 33bebbc..aa1697f 100644 --- a/.github/workflows/codegen-check.yml +++ b/.github/workflows/codegen-check.yml @@ -20,12 +20,12 @@ jobs: uses: devcontainers/ci@v0.3 with: runCmd: | + # fetch submodule tags since actions/checkout does not + git submodule foreach 'git fetch --unshallow || true' # Ensure dependencies are installed uv sync --extra test --extra gen_proto # Run all code generation steps - make antlr - ./gen_proto.sh - make codegen-extensions + make codegen - name: Check for uncommitted changes run: | @@ -36,9 +36,7 @@ jobs: git diff src/substrait/gen/ echo "" echo "To fix this, run:" - echo " make antlr" - echo " ./gen_proto.sh" - echo " make codegen-extensions" + echo " make codegen" echo "Then commit the changes." exit 1 fi diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f2bb2ef..39d0164 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,6 +22,12 @@ git submodule update --init --recursive # Code generation +You can run the full code generation using the following command or use the individual commands to selectively regenerate the generated code. This does not update the Substrait Git submodule. + +``` +make codegen +``` + ## Protobuf stubs Run the upgrade script to upgrade the submodule and regenerate the protobuf stubs. @@ -31,6 +37,12 @@ uv sync --extra gen_proto uv run ./update_proto.sh ``` +Or run the proto codegen without updating the Substrait Git submodule: + +``` +make codegen-proto +``` + ## Antlr grammar Substrait uses antlr grammar to derive output types of extension functions. Make sure java is installed and ANTLR_JAR environment variable is set. Take a look at .devcontainer/Dockerfile for example setup. diff --git a/Makefile b/Makefile index 670c6eb..865b20f 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,20 @@ +codegen: antlr codegen-proto codegen-extensions codegen-version + + antlr: cd third_party/substrait/grammar \ && java -jar ${ANTLR_JAR} -o ../../../src/substrait/gen/antlr -Dlanguage=Python3 SubstraitType.g4 \ && rm ../../../src/substrait/gen/antlr/*.tokens \ && rm ../../../src/substrait/gen/antlr/*.interp +codegen-version: + echo -n 'substrait_version = "' > src/substrait/gen/version.py \ + && cd third_party/substrait && git describe --tags | tr -d 'v\n' >> ../../src/substrait/gen/version.py && cd ../.. \ + && echo '"' >> src/substrait/gen/version.py + +codegen-proto: + ./gen_proto.sh + codegen-extensions: uv run --with datamodel-code-generator datamodel-codegen \ --input-file-type jsonschema \ diff --git a/src/substrait/builders/plan.py b/src/substrait/builders/plan.py index a4a2180..54bbef6 100644 --- a/src/substrait/builders/plan.py +++ b/src/substrait/builders/plan.py @@ -6,6 +6,7 @@ """ from typing import Iterable, Optional, Union, Callable +import re import substrait.gen.proto.algebra_pb2 as stalg from substrait.gen.proto.extensions.extensions_pb2 import AdvancedExtension @@ -23,12 +24,27 @@ merge_extension_urns, merge_extension_uris, ) +from substrait.gen.version import substrait_version UnboundPlan = Callable[[ExtensionRegistry], stp.Plan] PlanOrUnbound = Union[stp.Plan, UnboundPlan] +def _create_default_version(): + p = re.compile(r"(\d+)\.(\d+)\.(\d+)") + m = p.match(substrait_version) + global default_version + default_version = stp.Version( + major_number=int(m.group(1)), + minor_number=int(m.group(2)), + patch_number=int(m.group(3)), + ) + + +_create_default_version() + + def _merge_extensions(*objs): """Merge extension URIs, URNs, and declarations from multiple plan/expression objects. @@ -65,9 +81,10 @@ def resolve(registry: ExtensionRegistry) -> stp.Plan: ) return stp.Plan( + version=default_version, relations=[ stp.PlanRel(root=stalg.RelRoot(input=rel, names=named_struct.names)) - ] + ], ) return resolve @@ -107,6 +124,7 @@ def resolve(registry: ExtensionRegistry) -> stp.Plan: ) return stp.Plan( + version=default_version, relations=[stp.PlanRel(root=stalg.RelRoot(input=rel, names=names))], **_merge_extensions(_plan, *bound_expressions), ) @@ -137,6 +155,7 @@ def resolve(registry: ExtensionRegistry) -> stp.Plan: names = ns.names return stp.Plan( + version=default_version, relations=[stp.PlanRel(root=stalg.RelRoot(input=rel, names=names))], **_merge_extensions(bound_plan, bound_expression), ) @@ -183,6 +202,7 @@ def resolve(registry: ExtensionRegistry) -> stp.Plan: ) return stp.Plan( + version=default_version, relations=[stp.PlanRel(root=stalg.RelRoot(input=rel, names=ns.names))], **_merge_extensions(bound_plan, *[e[0] for e in bound_expressions]), ) @@ -200,6 +220,7 @@ def resolve(registry: ExtensionRegistry) -> stp.Plan: ) return stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -238,6 +259,7 @@ def resolve(registry: ExtensionRegistry) -> stp.Plan: ) return stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -286,6 +308,7 @@ def resolve(registry: ExtensionRegistry) -> stp.Plan: ) return stp.Plan( + version=default_version, relations=[stp.PlanRel(root=stalg.RelRoot(input=rel, names=ns.names))], **_merge_extensions(bound_left, bound_right, bound_expression), ) @@ -321,6 +344,7 @@ def resolve(registry: ExtensionRegistry) -> stp.Plan: ) return stp.Plan( + version=default_version, relations=[stp.PlanRel(root=stalg.RelRoot(input=rel, names=ns.names))], **_merge_extensions(bound_left, bound_right), ) @@ -372,6 +396,7 @@ def resolve(registry: ExtensionRegistry) -> stp.Plan: ] + [e.referred_expr[0].output_names[0] for e in bound_measures] return stp.Plan( + version=default_version, relations=[stp.PlanRel(root=stalg.RelRoot(input=rel, names=names))], **_merge_extensions( bound_input, *bound_grouping_expressions, *bound_measures diff --git a/src/substrait/gen/__init__.pyi b/src/substrait/gen/__init__.pyi index 4f7532c..3f49c72 100644 --- a/src/substrait/gen/__init__.pyi +++ b/src/substrait/gen/__init__.pyi @@ -1,3 +1,4 @@ from . import proto from . import antlr from . import json +from . import version diff --git a/src/substrait/gen/version.py b/src/substrait/gen/version.py new file mode 100644 index 0000000..b7f2ccf --- /dev/null +++ b/src/substrait/gen/version.py @@ -0,0 +1 @@ +substrait_version = "0.77.0" diff --git a/tests/builders/plan/test_aggregate.py b/tests/builders/plan/test_aggregate.py index 0b30685..1eb3f6c 100644 --- a/tests/builders/plan/test_aggregate.py +++ b/tests/builders/plan/test_aggregate.py @@ -3,7 +3,7 @@ import substrait.gen.proto.algebra_pb2 as stalg import substrait.gen.proto.extensions.extensions_pb2 as ste from substrait.builders.type import boolean, i64 -from substrait.builders.plan import read_named_table, aggregate +from substrait.builders.plan import read_named_table, aggregate, default_version from substrait.builders.extended_expression import column, aggregate_function from substrait.extension_registry import ExtensionRegistry from substrait.type_inference import infer_plan_schema @@ -56,6 +56,7 @@ def test_aggregate(): ns = infer_plan_schema(table(None)) expected = stp.Plan( + version=default_version, extension_urns=[ ste.SimpleExtensionURN(extension_urn_anchor=1, urn="extension:test:urn") ], diff --git a/tests/builders/plan/test_cross.py b/tests/builders/plan/test_cross.py index e022706..63686c1 100644 --- a/tests/builders/plan/test_cross.py +++ b/tests/builders/plan/test_cross.py @@ -2,7 +2,7 @@ import substrait.gen.proto.plan_pb2 as stp import substrait.gen.proto.algebra_pb2 as stalg from substrait.builders.type import boolean, i64, string -from substrait.builders.plan import read_named_table, cross +from substrait.builders.plan import read_named_table, cross, default_version from substrait.extension_registry import ExtensionRegistry registry = ExtensionRegistry(load_default_extensions=False) @@ -28,6 +28,7 @@ def test_cross_join(): actual = cross(table, table2)(registry) expected = stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -40,7 +41,7 @@ def test_cross_join(): names=["id", "is_applicable", "fk_id", "name"], ) ) - ] + ], ) assert actual == expected diff --git a/tests/builders/plan/test_fetch.py b/tests/builders/plan/test_fetch.py index a9f8a4d..0f6f21b 100644 --- a/tests/builders/plan/test_fetch.py +++ b/tests/builders/plan/test_fetch.py @@ -2,7 +2,7 @@ import substrait.gen.proto.plan_pb2 as stp import substrait.gen.proto.algebra_pb2 as stalg from substrait.builders.type import boolean, i64 -from substrait.builders.plan import read_named_table, fetch +from substrait.builders.plan import read_named_table, fetch, default_version from substrait.builders.extended_expression import literal from substrait.extension_registry import ExtensionRegistry @@ -24,6 +24,7 @@ def test_fetch(): actual = fetch(table, offset=offset, count=count)(registry) expected = stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -37,7 +38,7 @@ def test_fetch(): names=["id", "is_applicable"], ) ) - ] + ], ) assert actual == expected diff --git a/tests/builders/plan/test_filter.py b/tests/builders/plan/test_filter.py index bba55ec..25959af 100644 --- a/tests/builders/plan/test_filter.py +++ b/tests/builders/plan/test_filter.py @@ -2,7 +2,7 @@ import substrait.gen.proto.plan_pb2 as stp import substrait.gen.proto.algebra_pb2 as stalg from substrait.builders.type import boolean, i64 -from substrait.builders.plan import read_named_table, filter +from substrait.builders.plan import read_named_table, filter, default_version from substrait.builders.extended_expression import literal from substrait.extension_registry import ExtensionRegistry @@ -21,6 +21,7 @@ def test_filter(): actual = filter(table, literal(True, boolean()))(registry) expected = stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -37,7 +38,7 @@ def test_filter(): names=["id", "is_applicable"], ) ) - ] + ], ) assert actual == expected diff --git a/tests/builders/plan/test_join.py b/tests/builders/plan/test_join.py index d6503cc..00cf55a 100644 --- a/tests/builders/plan/test_join.py +++ b/tests/builders/plan/test_join.py @@ -2,7 +2,7 @@ import substrait.gen.proto.plan_pb2 as stp import substrait.gen.proto.algebra_pb2 as stalg from substrait.builders.type import boolean, i64, string -from substrait.builders.plan import read_named_table, join +from substrait.builders.plan import read_named_table, join, default_version from substrait.builders.extended_expression import literal from substrait.extension_registry import ExtensionRegistry @@ -31,6 +31,7 @@ def test_join(): )(registry) expected = stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -47,7 +48,7 @@ def test_join(): names=["id", "is_applicable", "fk_id", "name"], ) ) - ] + ], ) assert actual == expected diff --git a/tests/builders/plan/test_project.py b/tests/builders/plan/test_project.py index e66a499..18ba4b5 100644 --- a/tests/builders/plan/test_project.py +++ b/tests/builders/plan/test_project.py @@ -2,7 +2,7 @@ import substrait.gen.proto.plan_pb2 as stp import substrait.gen.proto.algebra_pb2 as stalg from substrait.builders.type import boolean, i64 -from substrait.builders.plan import read_named_table, project +from substrait.builders.plan import read_named_table, project, default_version from substrait.builders.extended_expression import column from substrait.extension_registry import ExtensionRegistry @@ -21,6 +21,7 @@ def test_project(): actual = project(table, [column("id")])(registry) expected = stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -47,7 +48,7 @@ def test_project(): names=["id"], ) ) - ] + ], ) assert actual == expected diff --git a/tests/builders/plan/test_read.py b/tests/builders/plan/test_read.py index 429fc9f..9060672 100644 --- a/tests/builders/plan/test_read.py +++ b/tests/builders/plan/test_read.py @@ -2,7 +2,7 @@ import substrait.gen.proto.plan_pb2 as stp import substrait.gen.proto.algebra_pb2 as stalg from substrait.builders.type import boolean, i64 -from substrait.builders.plan import read_named_table +from substrait.builders.plan import read_named_table, default_version import pytest from substrait.gen.proto.extensions.extensions_pb2 import AdvancedExtension from google.protobuf import any_pb2 @@ -20,6 +20,7 @@ def test_read_rel(): actual = read_named_table("example_table", named_struct)(None) expected = stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -35,7 +36,7 @@ def test_read_rel(): names=["id", "is_applicable"], ) ) - ] + ], ) assert actual == expected @@ -45,6 +46,7 @@ def test_read_rel_db(): actual = read_named_table(["example_db", "example_table"], named_struct)(None) expected = stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -60,7 +62,7 @@ def test_read_rel_db(): names=["id", "is_applicable"], ) ) - ] + ], ) assert actual == expected @@ -90,6 +92,7 @@ def test_read_rel_ae(): ) expected = stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -106,7 +109,7 @@ def test_read_rel_ae(): names=["id", "is_applicable"], ) ) - ] + ], ) assert actual == expected diff --git a/tests/builders/plan/test_set.py b/tests/builders/plan/test_set.py index e35570d..24265a8 100644 --- a/tests/builders/plan/test_set.py +++ b/tests/builders/plan/test_set.py @@ -2,7 +2,7 @@ import substrait.gen.proto.plan_pb2 as stp import substrait.gen.proto.algebra_pb2 as stalg from substrait.builders.type import boolean, i64 -from substrait.builders.plan import read_named_table, set +from substrait.builders.plan import read_named_table, set, default_version from substrait.extension_registry import ExtensionRegistry registry = ExtensionRegistry(load_default_extensions=False) @@ -21,6 +21,7 @@ def test_set(): actual = set([table, table2], stalg.SetRel.SET_OP_UNION_ALL)(None) expected = stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -36,7 +37,7 @@ def test_set(): names=["id", "is_applicable"], ) ) - ] + ], ) assert actual == expected diff --git a/tests/builders/plan/test_sort.py b/tests/builders/plan/test_sort.py index 7fee44f..c8c18c2 100644 --- a/tests/builders/plan/test_sort.py +++ b/tests/builders/plan/test_sort.py @@ -2,7 +2,7 @@ import substrait.gen.proto.plan_pb2 as stp import substrait.gen.proto.algebra_pb2 as stalg from substrait.builders.type import boolean, i64 -from substrait.builders.plan import read_named_table, sort +from substrait.builders.plan import read_named_table, sort, default_version from substrait.builders.extended_expression import column from substrait.type_inference import infer_plan_schema from substrait.extension_registry import ExtensionRegistry @@ -24,6 +24,7 @@ def test_sort_no_direction(): actual = sort(table, expressions=[col])(registry) expected = stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -43,7 +44,7 @@ def test_sort_no_direction(): names=["id", "is_applicable"], ) ) - ] + ], ) assert actual == expected @@ -59,6 +60,7 @@ def test_sort_direction(): )(registry) expected = stp.Plan( + version=default_version, relations=[ stp.PlanRel( root=stalg.RelRoot( @@ -78,7 +80,7 @@ def test_sort_direction(): names=["id", "is_applicable"], ) ) - ] + ], ) assert actual == expected diff --git a/tests/test_uri_urn_migration.py b/tests/test_uri_urn_migration.py index 184abd6..9aa4be8 100644 --- a/tests/test_uri_urn_migration.py +++ b/tests/test_uri_urn_migration.py @@ -21,7 +21,13 @@ aggregate_function, ) from substrait.builders.type import i64 -from substrait.builders.plan import read_named_table, aggregate, project, filter +from substrait.builders.plan import ( + read_named_table, + aggregate, + project, + filter, + default_version, +) from substrait.extension_registry import ExtensionRegistry from substrait.type_inference import infer_plan_schema @@ -148,6 +154,7 @@ def test_project_outputs_both_uri_and_urn(): ns = infer_plan_schema(table(None)) expected = stp.Plan( + version=default_version, extension_urns=[ ste.SimpleExtensionURN(extension_urn_anchor=1, urn="extension:test:math") ], @@ -223,6 +230,7 @@ def test_filter_outputs_both_uri_and_urn(): ns = infer_plan_schema(table(None)) expected = stp.Plan( + version=default_version, extension_urns=[ ste.SimpleExtensionURN( extension_urn_anchor=1, urn="extension:test:comparison" @@ -297,6 +305,7 @@ def test_aggregate_with_aggregate_function(): ns = infer_plan_schema(table(None)) expected = stp.Plan( + version=default_version, extension_urns=[ ste.SimpleExtensionURN( extension_urn_anchor=1, urn="extension:test:aggregate" diff --git a/uv.lock b/uv.lock index 0c3006f..d31ecde 100644 --- a/uv.lock +++ b/uv.lock @@ -1,10 +1,6 @@ version = 1 revision = 3 -requires-python = ">=3.9" -resolution-markers = [ - "python_full_version >= '3.10'", - "python_full_version < '3.10'", -] +requires-python = ">=3.10" [[package]] name = "antlr4-python3-runtime" @@ -15,30 +11,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/89/03/a851e84fcbb85214dc637b6378121ef9a0dd61b4c65264675d8a5c9b1ae7/antlr4_python3_runtime-4.13.2-py3-none-any.whl", hash = "sha256:fe3835eb8d33daece0e799090eda89719dbccee7aa39ef94eed3818cafa5a7e8", size = 144462, upload-time = "2024-08-03T19:00:11.134Z" }, ] -[[package]] -name = "click" -version = "8.1.8" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -dependencies = [ - { name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" }, -] - [[package]] name = "click" version = "8.3.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.10'", -] dependencies = [ - { name = "colorama", marker = "python_full_version >= '3.10' and sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } wheels = [ @@ -121,14 +99,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/69/c7/95fcd7bde0f754ea6700208d36b845379cbd2b28779c0eff4dd4a7396369/duckdb-1.2.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72f688a8b0df7030c5a28ca6072817c1f090979e08d28ee5912dee37c26a7d0c", size = 18756619, upload-time = "2025-04-08T08:46:29.035Z" }, { url = "https://files.pythonhosted.org/packages/ad/1b/c9eab9e84d4a70dd5f7e2a93dd6e9d7b4d868d3df755cd58b572d82d6c5d/duckdb-1.2.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:26e9c349f56f7c99341b5c79bbaff5ba12a5414af0261e79bf1a6a2693f152f6", size = 22294667, upload-time = "2025-04-08T08:46:31.295Z" }, { url = "https://files.pythonhosted.org/packages/3f/3d/ce68db53084746a4a62695a4cb064e44ce04123f8582bb3afbf6ee944e16/duckdb-1.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:e1aec7102670e59d83512cf47d32a6c77a79df9df0294c5e4d16b6259851e2e9", size = 11370206, upload-time = "2025-04-08T08:46:33.472Z" }, - { url = "https://files.pythonhosted.org/packages/a9/a8/9d75eeab4ff76a4e9dae52298cd0c582f513300f3fc34db9520a6db6c4b1/duckdb-1.2.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:25ac669180f88fecca20f300b898e191f81aa674d51dde8a328bdeb28a572ab0", size = 15255341, upload-time = "2025-04-08T08:46:59.758Z" }, - { url = "https://files.pythonhosted.org/packages/67/52/745839eb1299be96379b52b6cc3783ee330e91ec8d325b157611b9a2d49c/duckdb-1.2.2-cp39-cp39-macosx_12_0_universal2.whl", hash = "sha256:d42e7e545d1059e6b73d0f0baa9ae34c90684bfd8c862e70b0d8ab92e01e0e3f", size = 31923916, upload-time = "2025-04-08T08:47:02.231Z" }, - { url = "https://files.pythonhosted.org/packages/0c/6b/0e1da90808ec4f60215c2a2873c5ae5a248337ccccc77c2b5fb71918f7eb/duckdb-1.2.2-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:f3ce127bcecc723f1c7bddbc57f0526d11128cb05bfd81ffcd5e69e2dd5a1624", size = 16778052, upload-time = "2025-04-08T08:47:06.091Z" }, - { url = "https://files.pythonhosted.org/packages/60/13/04974fdd6106492d6ebbd411c51fca949f73d1a08b5281f9b41c622b0386/duckdb-1.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2418937adb9d6d0ca823bd385b914495294db27bc2963749d54af6708757f679", size = 18727076, upload-time = "2025-04-08T08:47:08.456Z" }, - { url = "https://files.pythonhosted.org/packages/be/cf/f875823e9eae416928b7e583b2174e826e67c120297880f1dde3a726accc/duckdb-1.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d41f899ce7979e7b3f9097ebce70da5c659db2d81d08c07a72b2b50f869859", size = 20196346, upload-time = "2025-04-08T08:47:10.868Z" }, - { url = "https://files.pythonhosted.org/packages/b1/3e/b483c5ad2223392474f4d74d42e522b7545a95154c673f81eea4252d7192/duckdb-1.2.2-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:85e90a9c5307cf4d9151844e60c80f492618ea6e9b71081020e7d462e071ac8f", size = 18724393, upload-time = "2025-04-08T08:47:13.235Z" }, - { url = "https://files.pythonhosted.org/packages/a6/99/349475c08be5abe686d647ca4585287bd01c01b16121f329e05e664630f4/duckdb-1.2.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:df8c8a4ec998139b8507213c44c50e24f62a36af1cfded87e8972173dc9f8baf", size = 22237700, upload-time = "2025-04-08T08:47:15.63Z" }, - { url = "https://files.pythonhosted.org/packages/8e/1a/1a9da0336c146750ba1dc9a5ad1ab8c228da4512991e1d5b8f0e07076bd5/duckdb-1.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:6507ad2445cd3479853fb6473164b5eb5b22446d283c9892cfbbd0a85c5f361d", size = 11400288, upload-time = "2025-04-08T08:47:17.999Z" }, ] [[package]] @@ -143,25 +113,10 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, ] -[[package]] -name = "iniconfig" -version = "2.1.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, -] - [[package]] name = "iniconfig" version = "2.3.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.10'", -] sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, @@ -205,8 +160,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dd/73/10e1661c21f139f2c6ad9b23040ff36fee624310dc28fba20d33fdae124c/protobuf-5.29.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e38c5add5a311f2a6eb0340716ef9b039c1dfa428b28f25a7838ac329204a671", size = 418091, upload-time = "2025-05-28T23:51:45.907Z" }, { url = "https://files.pythonhosted.org/packages/6c/04/98f6f8cf5b07ab1294c13f34b4e69b3722bb609c5b701d6c169828f9f8aa/protobuf-5.29.5-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:fa18533a299d7ab6c55a238bf8629311439995f2e7eca5caaff08663606e9015", size = 319824, upload-time = "2025-05-28T23:51:47.545Z" }, { url = "https://files.pythonhosted.org/packages/85/e4/07c80521879c2d15f321465ac24c70efe2381378c00bf5e56a0f4fbac8cd/protobuf-5.29.5-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:63848923da3325e1bf7e9003d680ce6e14b07e55d0473253a690c3a8b8fd6e61", size = 319942, upload-time = "2025-05-28T23:51:49.11Z" }, - { url = "https://files.pythonhosted.org/packages/e5/59/ca89678bb0352f094fc92f2b358daa40e3acc91a93aa8f922b24762bf841/protobuf-5.29.5-cp39-cp39-win32.whl", hash = "sha256:6f642dc9a61782fa72b90878af134c5afe1917c89a568cd3476d758d3c3a0736", size = 423025, upload-time = "2025-05-28T23:51:54.003Z" }, - { url = "https://files.pythonhosted.org/packages/96/8b/2c62731fe3e92ddbbeca0174f78f0f8739197cdeb7c75ceb5aad3706963b/protobuf-5.29.5-cp39-cp39-win_amd64.whl", hash = "sha256:470f3af547ef17847a28e1f47200a1cbf0ba3ff57b7de50d22776607cd2ea353", size = 434906, upload-time = "2025-05-28T23:51:55.782Z" }, { url = "https://files.pythonhosted.org/packages/7e/cc/7e77861000a0691aeea8f4566e5d3aa716f2b1dece4a24439437e41d3d25/protobuf-5.29.5-py3-none-any.whl", hash = "sha256:6cf42630262c59b2d8de33954443d94b746c952b01434fc58a417fdbd2e84bd5", size = 172823, upload-time = "2025-05-28T23:51:58.157Z" }, ] @@ -215,8 +168,7 @@ name = "protoletariat" version = "3.3.10" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "click", version = "8.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "click" }, { name = "protobuf" }, ] sdist = { url = "https://files.pythonhosted.org/packages/36/60/31c8dac4e060bce3f102195409128838fc5830e4e589f7962eb7531b4a27/protoletariat-3.3.10.tar.gz", hash = "sha256:bfa0e663fe4c9e3584101779b8b9f5a77b8af623aa25f680e0559b7d2609039b", size = 20694, upload-time = "2025-03-19T22:39:15.043Z" } @@ -265,13 +217,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0a/f9/4ee798dc902533159250fb4321267730bc0a107d8c6889e07c3add4fe3a5/pyarrow-21.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:fc0d2f88b81dcf3ccf9a6ae17f89183762c8a94a5bdcfa09e05cfe413acf0503", size = 43276625, upload-time = "2025-07-18T00:56:48.002Z" }, { url = "https://files.pythonhosted.org/packages/5a/da/e02544d6997037a4b0d22d8e5f66bc9315c3671371a8b18c79ade1cefe14/pyarrow-21.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6299449adf89df38537837487a4f8d3bd91ec94354fdd2a7d30bc11c48ef6e79", size = 44951890, upload-time = "2025-07-18T00:56:52.568Z" }, { url = "https://files.pythonhosted.org/packages/e5/4e/519c1bc1876625fe6b71e9a28287c43ec2f20f73c658b9ae1d485c0c206e/pyarrow-21.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:222c39e2c70113543982c6b34f3077962b44fca38c0bd9e68bb6781534425c10", size = 26371006, upload-time = "2025-07-18T00:56:56.379Z" }, - { url = "https://files.pythonhosted.org/packages/3e/cc/ce4939f4b316457a083dc5718b3982801e8c33f921b3c98e7a93b7c7491f/pyarrow-21.0.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:a7f6524e3747e35f80744537c78e7302cd41deee8baa668d56d55f77d9c464b3", size = 31211248, upload-time = "2025-07-18T00:56:59.7Z" }, - { url = "https://files.pythonhosted.org/packages/1f/c2/7a860931420d73985e2f340f06516b21740c15b28d24a0e99a900bb27d2b/pyarrow-21.0.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:203003786c9fd253ebcafa44b03c06983c9c8d06c3145e37f1b76a1f317aeae1", size = 32676896, upload-time = "2025-07-18T00:57:03.884Z" }, - { url = "https://files.pythonhosted.org/packages/68/a8/197f989b9a75e59b4ca0db6a13c56f19a0ad8a298c68da9cc28145e0bb97/pyarrow-21.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:3b4d97e297741796fead24867a8dabf86c87e4584ccc03167e4a811f50fdf74d", size = 41067862, upload-time = "2025-07-18T00:57:07.587Z" }, - { url = "https://files.pythonhosted.org/packages/fa/82/6ecfa89487b35aa21accb014b64e0a6b814cc860d5e3170287bf5135c7d8/pyarrow-21.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:898afce396b80fdda05e3086b4256f8677c671f7b1d27a6976fa011d3fd0a86e", size = 42747508, upload-time = "2025-07-18T00:57:13.917Z" }, - { url = "https://files.pythonhosted.org/packages/3b/b7/ba252f399bbf3addc731e8643c05532cf32e74cebb5e32f8f7409bc243cf/pyarrow-21.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:067c66ca29aaedae08218569a114e413b26e742171f526e828e1064fcdec13f4", size = 43345293, upload-time = "2025-07-18T00:57:19.828Z" }, - { url = "https://files.pythonhosted.org/packages/ff/0a/a20819795bd702b9486f536a8eeb70a6aa64046fce32071c19ec8230dbaa/pyarrow-21.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0c4e75d13eb76295a49e0ea056eb18dbd87d81450bfeb8afa19a7e5a75ae2ad7", size = 45060670, upload-time = "2025-07-18T00:57:24.477Z" }, - { url = "https://files.pythonhosted.org/packages/10/15/6b30e77872012bbfe8265d42a01d5b3c17ef0ac0f2fae531ad91b6a6c02e/pyarrow-21.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:cdc4c17afda4dab2a9c0b79148a43a7f4e1094916b3e18d8975bfd6d6d52241f", size = 26227521, upload-time = "2025-07-18T00:57:29.119Z" }, ] [[package]] @@ -290,8 +235,7 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "iniconfig", version = "2.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "pygments" }, @@ -364,15 +308,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, - { url = "https://files.pythonhosted.org/packages/9f/62/67fc8e68a75f738c9200422bf65693fb79a4cd0dc5b23310e5202e978090/pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da", size = 184450, upload-time = "2025-09-25T21:33:00.618Z" }, - { url = "https://files.pythonhosted.org/packages/ae/92/861f152ce87c452b11b9d0977952259aa7df792d71c1053365cc7b09cc08/pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917", size = 174319, upload-time = "2025-09-25T21:33:02.086Z" }, - { url = "https://files.pythonhosted.org/packages/d0/cd/f0cfc8c74f8a030017a2b9c771b7f47e5dd702c3e28e5b2071374bda2948/pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9", size = 737631, upload-time = "2025-09-25T21:33:03.25Z" }, - { url = "https://files.pythonhosted.org/packages/ef/b2/18f2bd28cd2055a79a46c9b0895c0b3d987ce40ee471cecf58a1a0199805/pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5", size = 836795, upload-time = "2025-09-25T21:33:05.014Z" }, - { url = "https://files.pythonhosted.org/packages/73/b9/793686b2d54b531203c160ef12bec60228a0109c79bae6c1277961026770/pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a", size = 750767, upload-time = "2025-09-25T21:33:06.398Z" }, - { url = "https://files.pythonhosted.org/packages/a9/86/a137b39a611def2ed78b0e66ce2fe13ee701a07c07aebe55c340ed2a050e/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926", size = 727982, upload-time = "2025-09-25T21:33:08.708Z" }, - { url = "https://files.pythonhosted.org/packages/dd/62/71c27c94f457cf4418ef8ccc71735324c549f7e3ea9d34aba50874563561/pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7", size = 755677, upload-time = "2025-09-25T21:33:09.876Z" }, - { url = "https://files.pythonhosted.org/packages/29/3d/6f5e0d58bd924fb0d06c3a6bad00effbdae2de5adb5cda5648006ffbd8d3/pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0", size = 142592, upload-time = "2025-09-25T21:33:10.983Z" }, - { url = "https://files.pythonhosted.org/packages/f0/0c/25113e0b5e103d7f1490c0e947e303fe4a696c10b501dea7a9f49d4e876c/pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007", size = 158777, upload-time = "2025-09-25T21:33:15.55Z" }, ] [[package]] @@ -401,11 +336,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f9/04/98c216967275cd9a3e517dfeeb513ebff3183f1f22da29180c479c749ac8/sqloxide-0.1.56-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e94f9037d7336bef4e3090b15299c2a405c55aba4ae87ef6d963df2f0b48016", size = 3421350, upload-time = "2025-05-17T18:08:50.758Z" }, { url = "https://files.pythonhosted.org/packages/c2/2a/402274bf73fedfb986fab94239d8b34f9bfdb1a0a24adec3c43bd28e4387/sqloxide-0.1.56-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33006d8414d8c65b8e7e8313c61dd5c3f5dc1a4f88c7d1b7ae25bc8fa9f26fdc", size = 3730165, upload-time = "2025-05-17T18:08:51.995Z" }, { url = "https://files.pythonhosted.org/packages/c8/5c/487e081a5ac1a8538f7eb3a3e3ea04c39da13acde1f17916ca1767d40c4e/sqloxide-0.1.56-cp313-cp313-win_amd64.whl", hash = "sha256:08a119f20334285663989fd39f78eaa448ebf023ca451a25adba78321e3a17ae", size = 3018363, upload-time = "2025-05-17T18:08:53.208Z" }, - { url = "https://files.pythonhosted.org/packages/1d/6b/3c72d38aa754028b573ed5267ebb980f63f9be48c116cabb7553a678f8ee/sqloxide-0.1.56-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95264629cc13ec4ed9b155a88fc78fc9002f0ade1030d74dad5c211931fe679c", size = 3002496, upload-time = "2025-05-17T18:09:09.11Z" }, - { url = "https://files.pythonhosted.org/packages/89/45/e79b9140776d5a025aa885889d233d0543719ad8506c0d9aec0b3e04f663/sqloxide-0.1.56-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ef6b83e670c82a2053870624146c9f95b7a448c7e27d57bf7d562f6a80e0277", size = 3240645, upload-time = "2025-05-17T18:09:10.786Z" }, - { url = "https://files.pythonhosted.org/packages/14/78/684e9423a56073a90a1febf6ec77584e0ac50798cbbee4aca738ded0a740/sqloxide-0.1.56-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8b42d65e52814415ab8a70384405af0dded4762c746787ccd039add83023f99", size = 3423725, upload-time = "2025-05-17T18:09:12.019Z" }, - { url = "https://files.pythonhosted.org/packages/40/0c/b6e4141feafcd654c402a8893c38ee7c2efef9604179ed5727b6fd3198d2/sqloxide-0.1.56-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:176f9fbe86326cf9c3510255aa5cffd2a3b3566f282d7a32be543ff832a726bd", size = 3735201, upload-time = "2025-05-17T18:09:13.312Z" }, - { url = "https://files.pythonhosted.org/packages/c5/0e/77951d60ec8cec3cac652564223fdf7623d3e72906d0356035326a2e80cb/sqloxide-0.1.56-cp39-cp39-win_amd64.whl", hash = "sha256:effeae7e15a173790859a8e32314c50f070751125d5f583fb6b474a525839ecd", size = 3016855, upload-time = "2025-05-17T18:09:15.233Z" }, ] [[package]]