diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..b45b5b4b --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,10 @@ +## Summary + + + +## Checklist + +- [ ] Run the pre-commit checks locally with `uv run python x.py precommit` +- [ ] Add tests for any new functionality +- [ ] Update the relevant changelog (`Changes.md` for `serde_arrow`, + `marrow/Changes.md` for `marrow`) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 8a3d2358..e68ea788 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -8,7 +8,7 @@ "CARGO_TERM_COLOR": "always" }, "jobs": { - "build": { + "bench": { "runs-on": "ubuntu-latest", "steps": [ { @@ -24,7 +24,11 @@ }, { "name": "Bench", - "run": "cargo bench -p serde_arrow_bench\npython x.py summarize-bench >> $GITHUB_STEP_SUMMARY" + "run": "cargo bench -p serde_arrow_bench" + }, + { + "name": "Summarize", + "run": "python scripts/analyze-benchmark.py --criterion-root target/criterion --update-github-summary" } ] } diff --git a/.github/workflows/local.yml b/.github/workflows/local.yml new file mode 100644 index 00000000..ce35c5b3 --- /dev/null +++ b/.github/workflows/local.yml @@ -0,0 +1,167 @@ +{ + "name": "Local", + "on": { + "workflow_dispatch": {} + }, + "env": { + "CARGO_TERM_COLOR": "always" + }, + "jobs": { + "format": { + "runs-on": "ubuntu-latest", + "steps": [ + { + "uses": "actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0" + }, + { + "name": "Install uv", + "uses": "astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39", + "with": { + "enable-cache": true + } + }, + { + "name": "rustc", + "run": "rustc --version" + }, + { + "name": "cargo", + "run": "cargo --version" + }, + { + "name": "Format Python", + "run": "uv run ruff format x.py" + }, + { + "name": "Format Cargo", + "run": "cargo fmt" + }, + { + "name": "Format generated Rust", + "run": "rustfmt marrow/src/impl_arrow/impl_api_53.rs marrow/src/impl_arrow/impl_api_base.rs marrow_integration/src/tests/arrays.rs marrow_integration/src/tests/data_types.rs marrow_integration/src/tests/fixed_size_binary_arrays.rs marrow_integration/src/tests/intervals.rs marrow_integration/src/tests/struct_arrays.rs marrow_integration/src/tests/union_arrays.rs marrow_integration/src/tests/utils.rs marrow_integration/src/tests/views.rs" + } + ] + }, + "check": { + "runs-on": "ubuntu-latest", + "steps": [ + { + "uses": "actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0" + }, + { + "name": "Install uv", + "uses": "astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39", + "with": { + "enable-cache": true + } + }, + { + "name": "rustc", + "run": "rustc --version" + }, + { + "name": "cargo", + "run": "cargo --version" + }, + { + "name": "Check Cargo.toml", + "run": "uv run python scripts/check-cargo-toml.py" + }, + { + "name": "Check workspace", + "run": "cargo check" + }, + { + "name": "Check serde_arrow", + "run": "cargo check --all-targets --package serde_arrow --features arrow-59" + }, + { + "name": "Check marrow", + "run": "cargo check --all-targets --package marrow --features serde,arrow-59" + }, + { + "name": "Clippy serde_arrow", + "run": "cargo clippy --all-targets --package serde_arrow --features arrow-59" + }, + { + "name": "Clippy marrow", + "run": "cargo clippy --all-targets --package marrow --features serde,arrow-59" + }, + { + "name": "Check support packages", + "run": "cargo check --all-targets --all-features --package serde_arrow_bench --package serde_arrow_example --package serde_arrow_integration --package marrow_integration" + }, + { + "name": "Clippy support packages", + "run": "cargo clippy --all-targets --all-features --package serde_arrow_bench --package serde_arrow_example --package serde_arrow_integration --package marrow_integration" + } + ] + }, + "test": { + "runs-on": "ubuntu-latest", + "steps": [ + { + "uses": "actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0" + }, + { + "name": "Install uv", + "uses": "astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39", + "with": { + "enable-cache": true + } + }, + { + "name": "rustc", + "run": "rustc --version" + }, + { + "name": "cargo", + "run": "cargo --version" + }, + { + "name": "Test serde_arrow", + "run": "cargo test -q --package serde_arrow --features arrow-59" + }, + { + "name": "Test marrow", + "run": "cargo test -q --package marrow --features serde,arrow-59" + }, + { + "name": "Integration test", + "run": "cargo test -p serde_arrow_integration" + } + ] + }, + "example": { + "runs-on": "ubuntu-latest", + "steps": [ + { + "uses": "actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0" + }, + { + "name": "Install uv", + "uses": "astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39", + "with": { + "enable-cache": true + } + }, + { + "name": "rustc", + "run": "rustc --version" + }, + { + "name": "cargo", + "run": "cargo --version" + }, + { + "name": "Run example", + "run": "cargo run -p serde_arrow_example" + }, + { + "name": "Read example output", + "run": "uv run python -c 'import polars as pl; print(pl.read_ipc(\"serde_arrow_example.ipc\"))'" + } + ] + } + } +} \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4f297667..686c6712 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,7 +51,7 @@ } ] }, - "build": { + "test": { "runs-on": "ubuntu-latest", "steps": [ { @@ -72,6 +72,10 @@ "name": "cargo", "run": "cargo --version" }, + { + "name": "Check Cargo.toml", + "run": "uv run python scripts/check-cargo-toml.py" + }, { "name": "Check", "run": "cargo check" @@ -140,10 +144,30 @@ "name": "Check support packages", "run": "cargo check --all-features --package serde_arrow_bench --package serde_arrow_example --package serde_arrow_integration --package marrow_integration" }, + { + "name": "Clippy serde_arrow", + "run": "cargo clippy --all-targets --package serde_arrow --features arrow-59" + }, + { + "name": "Clippy marrow", + "run": "cargo clippy --all-targets --package marrow --features serde,arrow-59" + }, + { + "name": "Clippy support packages", + "run": "cargo clippy --all-targets --all-features --package serde_arrow_bench --package serde_arrow_example --package serde_arrow_integration --package marrow_integration" + }, + { + "name": "Check Python format", + "run": "uv run ruff format --check x.py" + }, { "name": "Check format", "run": "cargo fmt --check" }, + { + "name": "Check generated Rust format", + "run": "rustfmt --check marrow/src/impl_arrow/impl_api_53.rs marrow/src/impl_arrow/impl_api_base.rs marrow_integration/src/tests/arrays.rs marrow_integration/src/tests/data_types.rs marrow_integration/src/tests/fixed_size_binary_arrays.rs marrow_integration/src/tests/intervals.rs marrow_integration/src/tests/struct_arrays.rs marrow_integration/src/tests/union_arrays.rs marrow_integration/src/tests/utils.rs marrow_integration/src/tests/views.rs" + }, { "name": "Build", "run": "cargo build --package serde_arrow --package marrow --features serde_arrow/arrow-59,marrow/serde,marrow/arrow-59" @@ -154,7 +178,15 @@ }, { "name": "Integration test", - "run": "uv run python x.py test-integration" + "run": "cargo test -p serde_arrow_integration" + }, + { + "name": "Run example", + "run": "cargo run -p serde_arrow_example" + }, + { + "name": "Read example output", + "run": "uv run python -c 'import polars as pl; print(pl.read_ipc(\"serde_arrow_example.ipc\"))'" } ] } diff --git a/.gitignore b/.gitignore index dddad0db..ef6e4d37 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ target/ /serde_arrow_example.ipc __pycache__/ +*.py[cod] .ipynb_checkpoints/ # Editor directories and files diff --git a/Cargo.lock b/Cargo.lock index fdc01f43..62a3be60 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,47 +65,47 @@ checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "arrow" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffaaa3e009861fd829d0a24dd6f115aa8e4634324bb092147d43baafe69ca4a7" +checksum = "b952ca5a8046ad741b60f142d6eca4aeebcad615694202bc64c5341f23e32c5b" dependencies = [ "arrow-arith", - "arrow-array 59.0.0", - "arrow-buffer 59.0.0", + "arrow-array 59.1.0", + "arrow-buffer 59.1.0", "arrow-cast", "arrow-csv", - "arrow-data 59.0.0", + "arrow-data 59.1.0", "arrow-ipc", "arrow-json", "arrow-ord", "arrow-row", - "arrow-schema 59.0.0", + "arrow-schema 59.1.0", "arrow-select", "arrow-string", ] [[package]] name = "arrow-arith" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ac95125e1d71c4a252b5a9c729aef111e80418f08aaa6dbabd1ba66918247fc" +checksum = "64a13b8d3008c4e9063c597a08f46446fe3fd5789277127672d6c0bdbb43b1ff" dependencies = [ - "arrow-array 59.0.0", - "arrow-buffer 59.0.0", - "arrow-data 59.0.0", - "arrow-schema 59.0.0", + "arrow-array 59.1.0", + "arrow-buffer 59.1.0", + "arrow-data 59.1.0", + "arrow-schema 59.1.0", "chrono", "num-traits", ] @@ -212,14 +212,14 @@ dependencies = [ [[package]] name = "arrow-array" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c60c79628e9a97cb90d7a0dc3e944f216a902f837d4ecabc14d524bddbbc137" +checksum = "9486151b2f0785bafc6fa04fc5c99fcb4495455662e58787ea32eaaed33c4192" dependencies = [ "ahash 0.8.12", - "arrow-buffer 59.0.0", - "arrow-data 59.0.0", - "arrow-schema 59.0.0", + "arrow-buffer 59.1.0", + "arrow-data 59.1.0", + "arrow-schema 59.1.0", "chrono", "half", "hashbrown 0.17.1", @@ -298,9 +298,9 @@ dependencies = [ [[package]] name = "arrow-buffer" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6026f638c400e9878c1b1cc05c3cfd46fbf381285916ab408678701c1df46c1a" +checksum = "c4776577a87794bfdf0b4e90e2ea12454fa7738ea2823c4be5b9d1851da7b434" dependencies = [ "bytes", "half", @@ -310,15 +310,15 @@ dependencies = [ [[package]] name = "arrow-cast" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82c236c3caf8df5664284f3f1fbe89938852163998c3fdbf37e84ac220445e9" +checksum = "a9ad451ce4f98710828a455b96991b8f031deb2e67f5fcad6773f017e4a69c3a" dependencies = [ - "arrow-array 59.0.0", - "arrow-buffer 59.0.0", - "arrow-data 59.0.0", + "arrow-array 59.1.0", + "arrow-buffer 59.1.0", + "arrow-data 59.1.0", "arrow-ord", - "arrow-schema 59.0.0", + "arrow-schema 59.1.0", "arrow-select", "atoi", "base64", @@ -331,13 +331,13 @@ dependencies = [ [[package]] name = "arrow-csv" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12714e5fb7954159af1e26d4e0d37108bcf1a2ad5ee5c5bf02a944d564d588b7" +checksum = "8aa7bf96d6141a7bcca2eed57c7c9767d2a2175281857b8a7b68308992864784" dependencies = [ - "arrow-array 59.0.0", + "arrow-array 59.1.0", "arrow-cast", - "arrow-schema 59.0.0", + "arrow-schema 59.1.0", "chrono", "csv", "csv-core", @@ -420,12 +420,12 @@ dependencies = [ [[package]] name = "arrow-data" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd568aa70c4ec5947027b0d5caee94877433b661a0bb9e8ddceeeb5f0c9b1ab" +checksum = "b38fe43e2e8704360f1464e6e8cc4fc381ef02cc4fb0192afa8df1aaa0115c66" dependencies = [ - "arrow-buffer 59.0.0", - "arrow-schema 59.0.0", + "arrow-buffer 59.1.0", + "arrow-schema 59.1.0", "half", "num-integer", "num-traits", @@ -433,29 +433,29 @@ dependencies = [ [[package]] name = "arrow-ipc" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57ee4d470eab1a021bc4b63fa2b2c15d572892bf227b0a982d3b755a6c662b5" +checksum = "29dac499fcbc6ba74ee0324057821d381929a48526a3966bd9dffb44aa06d98c" dependencies = [ - "arrow-array 59.0.0", - "arrow-buffer 59.0.0", - "arrow-data 59.0.0", - "arrow-schema 59.0.0", + "arrow-array 59.1.0", + "arrow-buffer 59.1.0", + "arrow-data 59.1.0", + "arrow-schema 59.1.0", "arrow-select", "flatbuffers", ] [[package]] name = "arrow-json" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f47e0e7a284e1f3707a780dc8cd5451b1614e9e398ea2d9ca03c7a2fe9a9ed" +checksum = "0fe05e916ddc50f4c7a363cd69c0ef5894fcee063517e9a0b8582f0c56746af6" dependencies = [ - "arrow-array 59.0.0", - "arrow-buffer 59.0.0", + "arrow-array 59.1.0", + "arrow-buffer 59.1.0", "arrow-cast", "arrow-ord", - "arrow-schema 59.0.0", + "arrow-schema 59.1.0", "arrow-select", "chrono", "half", @@ -472,27 +472,27 @@ dependencies = [ [[package]] name = "arrow-ord" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a79cf73ad2eba8686ec2aa9bbf8671208e509025f166afc040cedbd94ffe4983" +checksum = "0e13dbdc2a9c053c10c7baa6e30faee04a180aa7ce88e471835850ce37abd20b" dependencies = [ - "arrow-array 59.0.0", - "arrow-buffer 59.0.0", - "arrow-data 59.0.0", - "arrow-schema 59.0.0", + "arrow-array 59.1.0", + "arrow-buffer 59.1.0", + "arrow-data 59.1.0", + "arrow-schema 59.1.0", "arrow-select", ] [[package]] name = "arrow-row" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea0f7d8ed6182f14952761e2c0f989852d5aa334fcbc49f73a9f2247c25b879" +checksum = "4d5a1f8c733d15260b305683472ee8ad89c62cbd706703ca873b90d051b41592" dependencies = [ - "arrow-array 59.0.0", - "arrow-buffer 59.0.0", - "arrow-data 59.0.0", - "arrow-schema 59.0.0", + "arrow-array 59.1.0", + "arrow-buffer 59.1.0", + "arrow-data 59.1.0", + "arrow-schema 59.1.0", "half", ] @@ -554,9 +554,9 @@ dependencies = [ [[package]] name = "arrow-schema" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80b3e786a0dd9103acd583a6fb486dbf2f3268466cc0bd571dcf34cef231c1f1" +checksum = "d9e4969dc350d571766247143ab36a5187d095d3d3690970408bc630d47c69e5" dependencies = [ "serde", "serde_core", @@ -564,28 +564,28 @@ dependencies = [ [[package]] name = "arrow-select" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "067a67e0361f6c31f4a7248759f36ca4ca71b187a941ed4d49da1c7d3d4db624" +checksum = "402770dba90865359d98d1ef92ef16e23d75c0cca9c2c880c8a05468b7743bf9" dependencies = [ "ahash 0.8.12", - "arrow-array 59.0.0", - "arrow-buffer 59.0.0", - "arrow-data 59.0.0", - "arrow-schema 59.0.0", + "arrow-array 59.1.0", + "arrow-buffer 59.1.0", + "arrow-data 59.1.0", + "arrow-schema 59.1.0", "num-traits", ] [[package]] name = "arrow-string" -version = "59.0.0" +version = "59.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99bc95847f3ff62a2b03d6f8ce2e3e78f01362060549a2a311898dd442f6256d" +checksum = "a2b0afbb8b9016700938291123df30838b89decc3213dba00852021988b170d3" dependencies = [ - "arrow-array 59.0.0", - "arrow-buffer 59.0.0", - "arrow-data 59.0.0", - "arrow-schema 59.0.0", + "arrow-array 59.1.0", + "arrow-buffer 59.1.0", + "arrow-data 59.1.0", + "arrow-schema 59.1.0", "arrow-select", "memchr", "num-traits", @@ -630,15 +630,21 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.13.0" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "bitvec" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" dependencies = [ "funty", "radium", @@ -648,9 +654,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" +checksum = "a88b7ea17d208c4193f2c1e6de3c35fe71f98c96982d5ced308bdcc749ff6e1f" dependencies = [ "borsh-derive", "bytes", @@ -659,15 +665,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfcfdc083699101d5a7965e49925975f2f55060f94f9a05e7187be95d530ca59" +checksum = "d8f347189c62a579b8cd5f80714efa178f52e461dc2e6d701d264f5ff22e566c" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -700,29 +706,29 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.25.0" +version = "1.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "d6aedf8ae72766347502cf3cb4f41cf5e9cc37d28bee90f1fdaaae15f9cf9424" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.10.2" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" +checksum = "f65693059b6b9c588b9f62fed1cedbf0a8b805631457ea162d68f0de186f3de5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cast" @@ -732,9 +738,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.64" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f" +checksum = "c89588d05638b5b4594a3348a2d6c20277e43a7f5c5202b05cc56888475a47b8" dependencies = [ "find-msvc-tools", "shlex", @@ -748,9 +754,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "chrono" @@ -795,18 +801,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.6.1" +version = "4.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +checksum = "dd059f9da4f5c36b3787f65d38ccaab1cc315f07b01f89abc8359ee6a8205011" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.6.0" +version = "4.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b" dependencies = [ "anstyle", "clap_lex", @@ -882,9 +888,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -892,18 +898,18 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crunchy" @@ -932,6 +938,37 @@ dependencies = [ "memchr", ] +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + [[package]] name = "either" version = "1.16.0" @@ -956,7 +993,7 @@ version = "25.12.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35f6839d7b3b98adde531effaf34f0c2badc6f4735d26fe74709d8e513a96ef3" dependencies = [ - "bitflags", + "bitflags 2.13.1", "rustc_version", ] @@ -969,12 +1006,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "funty" version = "2.0.0" @@ -983,21 +1014,21 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" dependencies = [ "futures-core", "futures-task", @@ -1032,15 +1063,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", - "wasip2", - "wasip3", ] [[package]] @@ -1090,9 +1119,6 @@ name = "hashbrown" version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "foldhash", -] [[package]] name = "hashbrown" @@ -1106,12 +1132,6 @@ version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - [[package]] name = "hermit-abi" version = "0.5.2" @@ -1142,12 +1162,6 @@ dependencies = [ "cc", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "indexmap" version = "2.14.0" @@ -1156,8 +1170,6 @@ checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", "hashbrown 0.17.1", - "serde", - "serde_core", ] [[package]] @@ -1188,10 +1200,12 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.28" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102" +checksum = "dc43d6fb25860892c78ef7ce2ffed572087a6853ecb60f587f499329717ed7da" dependencies = [ + "defmt", + "jiff-core", "jiff-static", "jiff-tzdb-platform", "log", @@ -1201,22 +1215,32 @@ dependencies = [ "windows-link", ] +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", +] + [[package]] name = "jiff-static" -version = "0.2.28" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47" +checksum = "96fb828bff41eeb269a9665f950cb359e8018f7288b8f34db24937ff54ed8fc5" dependencies = [ + "jiff-core", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "jiff-tzdb" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c900ef84826f1338a557697dc8fc601df9ca9af4ac137c7fb61d4c6f2dfd3076" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" [[package]] name = "jiff-tzdb-platform" @@ -1229,21 +1253,15 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.102" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", "wasm-bindgen", ] -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "lexical-core" version = "1.0.6" @@ -1315,9 +1333,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "log" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "marrow" @@ -1329,28 +1347,28 @@ dependencies = [ "arrow-array 56.2.1", "arrow-array 57.3.1", "arrow-array 58.3.0", - "arrow-array 59.0.0", + "arrow-array 59.1.0", "arrow-buffer 53.4.1", "arrow-buffer 54.3.1", "arrow-buffer 55.2.0", "arrow-buffer 56.2.1", "arrow-buffer 57.3.1", "arrow-buffer 58.3.0", - "arrow-buffer 59.0.0", + "arrow-buffer 59.1.0", "arrow-data 53.4.1", "arrow-data 54.3.1", "arrow-data 55.2.0", "arrow-data 56.2.1", "arrow-data 57.3.1", "arrow-data 58.3.0", - "arrow-data 59.0.0", + "arrow-data 59.1.0", "arrow-schema 53.4.1", "arrow-schema 54.3.1", "arrow-schema 55.2.0", "arrow-schema 56.2.1", "arrow-schema 57.3.1", "arrow-schema 58.3.0", - "arrow-schema 59.0.0", + "arrow-schema 59.1.0", "bytemuck", "half", "serde", @@ -1366,14 +1384,14 @@ dependencies = [ "arrow-array 56.2.1", "arrow-array 57.3.1", "arrow-array 58.3.0", - "arrow-array 59.0.0", + "arrow-array 59.1.0", "arrow-schema 53.4.1", "arrow-schema 54.3.1", "arrow-schema 55.2.0", "arrow-schema 56.2.1", "arrow-schema 57.3.1", "arrow-schema 58.3.0", - "arrow-schema 59.0.0", + "arrow-schema 59.1.0", "chrono", "half", "marrow", @@ -1382,9 +1400,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "num" @@ -1402,9 +1420,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ "num-integer", "num-traits", @@ -1430,11 +1448,10 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -1508,9 +1525,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3" [[package]] name = "portable-atomic-util" @@ -1530,16 +1547,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.117", -] - [[package]] name = "proc-macro-crate" version = "3.5.0" @@ -1551,9 +1558,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -1580,9 +1587,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -1607,9 +1614,9 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" dependencies = [ "libc", "rand_chacha", @@ -1657,29 +1664,29 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +checksum = "216e8f773d7923bcba9ceb86a86c93cabb3903a11872fc3f138c49630e50b96d" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +checksum = "2c9283685feec7d69af75fb0e858d5e7378f33fe4fc699383b2916ab9273e03c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.0", ] [[package]] name = "regex" -version = "1.12.4" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -1689,9 +1696,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" dependencies = [ "aho-corasick", "memchr", @@ -1770,9 +1777,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "ryu" @@ -1803,9 +1810,9 @@ checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -1831,14 +1838,14 @@ dependencies = [ "arrow-array 56.2.1", "arrow-array 57.3.1", "arrow-array 58.3.0", - "arrow-array 59.0.0", + "arrow-array 59.1.0", "arrow-schema 53.4.1", "arrow-schema 54.3.1", "arrow-schema 55.2.0", "arrow-schema 56.2.1", "arrow-schema 57.3.1", "arrow-schema 58.3.0", - "arrow-schema 59.0.0", + "arrow-schema 59.1.0", "bigdecimal", "bytemuck", "chrono", @@ -1856,9 +1863,9 @@ dependencies = [ name = "serde_arrow_bench" version = "0.1.0" dependencies = [ - "arrow-array 59.0.0", + "arrow-array 59.1.0", "arrow-json", - "arrow-schema 59.0.0", + "arrow-schema 59.1.0", "criterion", "rand", "serde", @@ -1901,22 +1908,22 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.0", ] [[package]] @@ -1979,9 +1986,20 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "f2fac314a64dc9a36e61a9eb4261a5e9bbfbc922b27e518af97bc32b926cf967" dependencies = [ "proc-macro2", "quote", @@ -1994,6 +2012,26 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "thiserror" +version = "2.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.0", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -2015,9 +2053,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" dependencies = [ "tinyvec_macros", ] @@ -2039,9 +2077,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.12+spec-1.1.0" +version = "0.25.13+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" +checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" dependencies = [ "indexmap", "toml_datetime", @@ -2064,19 +2102,13 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "uuid" -version = "1.23.3" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7" +checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "js-sys", "serde_core", "wasm-bindgen", @@ -2122,23 +2154,14 @@ version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -2150,9 +2173,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2160,65 +2183,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "web-sys" -version = "0.3.102" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" dependencies = [ "js-sys", "wasm-bindgen", @@ -2254,7 +2243,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2265,7 +2254,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2303,107 +2292,19 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" dependencies = [ "memchr", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - [[package]] name = "wyz" version = "0.5.1" @@ -2415,26 +2316,26 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.52" +version = "0.8.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +checksum = "b7cbbc0a705a0fd05cc3676525980d2bf5a9bc4adac6d6475209a7887cf59d19" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.52" +version = "0.8.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/Contributing.md b/Contributing.md index 1e9435c6..39343b62 100644 --- a/Contributing.md +++ b/Contributing.md @@ -8,44 +8,107 @@ Contributions are highly welcome! When authoring a pull request, please ## Development Setup +Install Rust and [`uv`](https://docs.astral.sh/uv/). The Python environment is +managed by `uv` from [`pyproject.toml`](pyproject.toml), including the packages +used by formatting, integration tests, examples, and benchmark summaries. + All common tasks are bundled in the `x.py` script: ```bash # format the code and run tests -uv run x.py precommit +uv run python x.py precommit ``` -Run `uv run x.py --help` for details. The script only uses standard Python -modules and can be run without installing further packages. +Run `uv run python x.py --help` for details. + +Useful commands: + +- `uv run python x.py format`: format Rust sources and `x.py` +- `uv run python x.py check`: run `cargo check`, clippy, and Cargo.toml checks +- `uv run python x.py test`: run default unit and integration tests +- `uv run python x.py ci-test`: run the full pull request test workflow locally +- `uv run python x.py serde-arrow-example`: run the example and read its output +- `uv run python x.py doc --open`: build and open local documentation + +Add `--backtrace` to `precommit`, `test`, `ci-test`, or +`serde-arrow-example` to set `RUST_BACKTRACE=1`. + +The GitHub workflow files are generated from templates in `x.py`. If you change +workflow generation logic or supported Arrow versions, run: + +```bash +uv run python x.py update-workflows +``` + +## `marrow` + +This repository also contains [`marrow`](marrow/Readme.md), the minimal Arrow +interop crate used by `serde_arrow`. See [`marrow/Changes.md`](marrow/Changes.md) +for its changelog. The crates are versioned and released independently with +crate-scoped tags such as `marrow/v1.0.0` and `serde_arrow/v1.0.0`. + ## Creating a release 1. Create a new branch with name `release/{VERSION}` -2. Update the `version` field in - [`serde_arrow/Cargo.toml`](serde_arrow/Cargo.toml) -3. Update the changelog ([`Changes.md`](Changes.md)) -4. Create a pull request -5. Merge the branch into main (requires maintainer access) -6. Create a new release via the GH UI tagged with `v{VERSION}` to trigger the - release workflow (requires maintainer access) +2. Update the crate version: + - `serde_arrow`: [`serde_arrow/Cargo.toml`](serde_arrow/Cargo.toml) + - `marrow`: [`marrow/Cargo.toml`](marrow/Cargo.toml) +3. If releasing both crates together, update `serde_arrow`'s `marrow` + dependency to the new `marrow` version +4. Update the relevant changelog: + - `serde_arrow`: [`Changes.md`](Changes.md) + - `marrow`: [`marrow/Changes.md`](marrow/Changes.md) +5. Run `uv run python x.py precommit` +6. Create a pull request +7. Merge the branch into main (requires maintainer access) +8. Create a new release via the GH UI tagged with `serde_arrow/v{VERSION}` to + trigger the release workflow (requires maintainer access). Use + `marrow/v{VERSION}` to release a new `marrow` version. + +Before publishing, the release workflows run package-specific checks and +`cargo package`. You can run those checks locally with: + +```bash +cargo package -p serde_arrow --allow-dirty +cargo package -p marrow --allow-dirty +``` + +For release candidates, use normal Cargo prerelease versions such as +`0.15.0-rc.1`. + +This repository uses the following tags: + +- `serde_arrow/v*`: `serde_arrow` releases +- `marrow/v*`: `marrow` releases +- `v*`: `serde_arrow` releases `<0.15.0` ## Running the benchmarks -1. `uv run x.py bench` -2. (optional) `uv run x.py summarize-bench --update` to update the Readme +1. `uv run python x.py serde-arrow-bench` +2. (optional) `uv run python x.py summarize-bench --update` to update the + Readme and `timings.png` + +Use `uv run python x.py serde-arrow-bench --quick` for a shorter local run. + +On GitHub, execute `uv run python x.py bench-remote`, or run: -On GitHub, execute `gh workflow run Bench --ref {BRANCH}` +```bash +gh workflow run Bench --ref {BRANCH} +``` The examples in the `benches` packages can be used to generate flamegraphs: ```bash -cargo flamegraph --example serialize_nested_struct --package bench --profile bench +cargo flamegraph --example serialize_nested_struct --package serde_arrow_bench --profile bench ``` ## Adding a new arrow version -1. `uv run x.py add-arrow-version {VERSION}` -2. `uv run x.py precommit` +1. Start with a clean working tree. The command edits every file that contains + `arrow-version` markers and refuses to run with unstaged changes. +2. `uv run python x.py add-arrow-version {VERSION}` +3. `uv run python x.py precommit` ## Error format diff --git a/Readme.md b/Readme.md index 73653b38..26567fc6 100644 --- a/Readme.md +++ b/Readme.md @@ -27,13 +27,6 @@ Rust structs to arrays, and deserialization from arrays to Rust structs. [polars]: https://github.com/pola-rs/polars [datafusion]: https://github.com/apache/arrow-datafusion/ -## Monorepo - -This repository also contains [`marrow`](marrow/Readme.md), the minimal Arrow -interop crate used by `serde_arrow`. See [`marrow/Changes.md`](marrow/Changes.md) -for its changelog. The crates are versioned and released independently with -crate-scoped tags such as `marrow/v1.0.0` and `serde_arrow/v1.0.0`. - ## Example The following examples assume that `serde_arrow` is added to the `Cargo.toml` @@ -134,7 +127,7 @@ Arrow builder construction. These benchmark results are workload-specific and on ![Time ](timings.png) -The detailed runtimes of the [benchmarks](../serde_arrow_bench/benches/groups/) are listed below. +The detailed runtimes of the [benchmarks](serde_arrow_bench/benches/groups/) are listed below. ### `complex_1000` diff --git a/arrow-versions.toml b/arrow-versions.toml new file mode 100644 index 00000000..c8ad32aa --- /dev/null +++ b/arrow-versions.toml @@ -0,0 +1,10 @@ +arrow-features = [ + # arrow-version:insert: "arrow-{version}", + "arrow-59", + "arrow-58", + "arrow-57", + "arrow-56", + "arrow-55", + "arrow-54", + "arrow-53", +] diff --git a/pyproject.toml b/pyproject.toml index cc754b40..5e5d27e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,11 +5,11 @@ version = "0.0.0" requires-python = ">=3.14" dependencies = [ - "pyarrow~=24.0", + "pyarrow~=25.0", "matplotlib~=3.11", - "numpy~=2.4", - "ruff~=0.15.7", - "polars~=1.41", + "numpy~=2.5", + "ruff~=0.15.22", + "polars~=1.42", ] [tool.uv] diff --git a/scripts/add-arrow-version.py b/scripts/add-arrow-version.py new file mode 100644 index 00000000..c70fd586 --- /dev/null +++ b/scripts/add-arrow-version.py @@ -0,0 +1,73 @@ +import argparse +import pathlib +import re +import subprocess + + +SELF_PATH = pathlib.Path(__file__).parents[1].resolve() + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("version") + add_arrow_version(parser.parse_args().version) + + +def add_arrow_version(version): + if ( + subprocess.run( + ["git", "diff-files", "--quiet"], + check=False, + cwd=SELF_PATH, + ).returncode + != 0 + ): + print( + "WARNING: potentially destructive changes. " + "Please stage or commit the working tree first." + ) + raise SystemExit(1) + + for path in arrow_version_paths(): + process_arrow_version_path(path, version) + + +def arrow_version_paths(): + return [ + SELF_PATH / "x.py", + *SELF_PATH.glob("*.toml"), + *SELF_PATH.glob("*/**/*.rs"), + *SELF_PATH.glob("*/**/*.toml"), + ] + + +def process_arrow_version_path(path, version): + content = path.read_text() + if "arrow-version" not in content: + return + + print(f"process {path}") + new_content = [] + include_next = True + for line in content.splitlines(): + if ( + match := re.match(r"^.*(//|#) arrow-version:(replace|insert): (.*)$", line) + ) is not None: + new_content.append(line) + new_content.append( + match.group(3).format_map({"version": version, "\\n": "\n"}) + ) + include_next = match.group(2) != "replace" + + else: + if include_next: + new_content.append(line) + + include_next = True + + with open(path, "wt", newline="\n", encoding="utf-8") as fobj: + fobj.write("\n".join(new_content)) + + +if __name__ == "__main__": + main() diff --git a/scripts/analyze-benchmark.py b/scripts/analyze-benchmark.py new file mode 100644 index 00000000..e5a68e30 --- /dev/null +++ b/scripts/analyze-benchmark.py @@ -0,0 +1,244 @@ +import argparse +import json +import os +import pathlib +import statistics + + +SELF_PATH = pathlib.Path(__file__).parents[1].resolve() + +BENCHMARK_RENAMES = { + "arrow": "arrow_json::ReaderBuilder", + "arrow_builder": "arrow builder", + "serde_arrow_arrow": "serde_arrow::to_arrow", + "serde_arrow_marrow": "serde_arrow::to_marrow", +} +BENCHMARK_BASELINE = "arrow builder" +README_BENCHMARK_IGNORE_GROUPS = {"json_to_arrow"} + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--criterion-root", type=pathlib.Path, required=True) + parser.add_argument( + "--plot-output", type=pathlib.Path, default=pathlib.Path("timings.png") + ) + parser.add_argument("--update", type=pathlib.Path) + parser.add_argument("--update-github-summary", action="store_true", default=False) + analyze_benchmark(parser.parse_args()) + + +def analyze_benchmark(args): + root = resolve_path(args.criterion_root) + update = resolve_path(args.update) if args.update else None + plot_output = resolve_path(args.plot_output) + + mean_times = load_times(root) + benchmark = format_benchmark( + mean_times, + ignore_groups=README_BENCHMARK_IGNORE_GROUPS, + ) + + print(benchmark) + + if update is not None: + update_marked_output(update, benchmark) + + if args.update_github_summary: + update_github_summary(benchmark) + + plot_times( + mean_times, + benchmark_baseline=BENCHMARK_BASELINE, + ignore_groups=README_BENCHMARK_IGNORE_GROUPS, + output=plot_output, + ) + + +def resolve_path(path): + if path.is_absolute(): + return path + + return SELF_PATH / path + + +def load_times(root): + results = [] + for p in root.glob("*/*/new/sample.json"): + group = p.parent.parent.parent.name + name = p.parent.parent.name + with open(p) as fobj: + data = json.load(fobj) + + for iterations, time in zip(data["iters"], data["times"]): + results.append( + { + "name": BENCHMARK_RENAMES.get(name, name), + "group": group, + "iterations": iterations, + "time": time, + "seconds_per_iter": time / iterations / 1e9, + } + ) + + grouped_times = collect( + ((d["group"], d["name"]), d["seconds_per_iter"]) for d in results + ) + + mean_times = {} + for k, times in grouped_times.items(): + # remove the top 5% of times + qq = statistics.quantiles(times, n=20) + mean_times[k] = statistics.mean(time for time in times if time < qq[-1]) + + return mean_times + + +def collect(kv_pairs): + res = {} + for k, v in kv_pairs: + res.setdefault(k, []).append(v) + + return res + + +def format_benchmark(mean_times, ignore_groups=()): + def _parts(): + for group in sorted({g for g, _ in mean_times if g not in ignore_groups}): + times_in_group = {n: v for (g, n), v in mean_times.items() if g == group} + sorted_items = sorted(times_in_group.items(), key=lambda kv: kv[1]) + + rows = [["label", "time [ms]", *(k[:15] for k, _ in sorted_items)]] + for label, time in sorted_items: + rows.append( + [ + label, + f"{1000 * time:7.2f}", + *(f"{time / cmp:.2f}" for _, cmp in sorted_items), + ] + ) + + widths = [max(len(row[i]) for row in rows) for i in range(len(rows[0]))] + + yield f"### `{group}`" + yield "" + for idx, row in enumerate(rows): + padded_row = [ + (str.ljust if idx == 0 else str.rjust)(item, width) + for idx, (item, width) in enumerate(zip(row, widths)) + ] + + if idx == 0: + yield "| " + " | ".join(padded_row) + " |" + yield "|-" + "-|-".join("-" * w for w in widths) + "-|" + else: + yield "| " + " | ".join(padded_row) + " |" + + yield "" + + return "\n".join(_parts()) + + +def update_marked_output(output, content): + print(f"Update markers in {output}") + with open(output, "rt", encoding="utf8") as fobj: + lines = [line.rstrip() for line in fobj] + + with open(output, "wt", encoding="utf8", newline="\n") as fobj: + for line in replace_marked_section( + lines, + start_marker="", + end_marker="", + content=content, + ): + print(line, file=fobj) + + +def update_github_summary(content): + path = os.environ.get("GITHUB_STEP_SUMMARY") + if path is None: + return + + append_output(pathlib.Path(path), content) + + +def append_output(path, content): + print(f"Append summary to {path}") + with open(path, "at", encoding="utf8", newline="\n") as fobj: + print(content, file=fobj) + + +def replace_marked_section(lines, *, start_marker, end_marker, content): + start = None + end = None + for idx, line in enumerate(lines): + if line.strip() == start_marker: + start = idx + elif line.strip() == end_marker: + end = idx + break + + if start is None or end is None or end < start: + raise RuntimeError( + f"Could not find marker block {start_marker!r}..{end_marker!r}" + ) + + return [ + *lines[: start + 1], + *content.splitlines(), + *lines[end:], + ] + + +def plot_times(mean_times, *, benchmark_baseline, ignore_groups, output): + print("Plot times") + + import matplotlib.pyplot as plt + import polars as pl + + df = pl.from_dicts( + [ + {"group": group, "impl": impl, "time": time} + for (group, impl), time in mean_times.items() + if group not in ignore_groups + ] + ) + agg_df = ( + df.select( + [ + pl.col("impl"), + ( + pl.col("time") + / pl.col("time") + .filter(pl.col("impl") == benchmark_baseline) + .mean() + .over("group") + ), + ] + ) + .group_by("impl") + .agg(pl.col("time").mean()) + .sort("time") + ) + + plt.figure(figsize=(7, 3.5), dpi=150) + b = plt.barh( + [d["impl"] for d in agg_df.to_dicts()], + [d["time"] for d in agg_df.to_dicts()], + zorder=10, + ) + plt.bar_label( + b, + ["{:.1f} x".format(d["time"]) for d in agg_df.to_dicts()], + bbox=dict(boxstyle="square,pad=0.0", fc="white", ec="none"), + padding=2.5, + ) + plt.grid(axis="x", zorder=0) + plt.xlim(0, 1.15 * agg_df["time"].max()) + plt.subplots_adjust(left=0.32, right=0.975, top=0.95, bottom=0.15) + plt.xlabel(f"Mean runtime compared to {benchmark_baseline}") + plt.savefig(output) + + +if __name__ == "__main__": + main() diff --git a/scripts/check-cargo-toml.py b/scripts/check-cargo-toml.py new file mode 100644 index 00000000..97ec51da --- /dev/null +++ b/scripts/check-cargo-toml.py @@ -0,0 +1,142 @@ +import pathlib +import tomllib + + +SELF_PATH = pathlib.Path(__file__).parents[1].resolve() +SERDE_ARROW_COMPONENTS = ("arrow-array", "arrow-schema") +MARROW_COMPONENTS = ("arrow-array", "arrow-schema", "arrow-data", "arrow-buffer") + + +def main(): + check_cargo_toml(load_script_config()["arrow-features"]) + + +def check_cargo_toml(arrow_features): + print(":: check Cargo.toml") + serde_arrow_config = load_config("serde_arrow") + marrow_config = load_config("marrow") + marrow_integration_config = load_config("marrow_integration") + + serde_arrow_marrow_dep = serde_arrow_config["dependencies"].get("marrow") + if serde_arrow_marrow_dep is None: + raise ValueError("Missing serde_arrow dependency marrow") + + serde_arrow_marrow_version = serde_arrow_marrow_dep.get("version") + marrow_version = marrow_config["package"]["version"] + if serde_arrow_marrow_version != marrow_version: + raise ValueError( + "Invalid serde_arrow marrow dependency version. " + f"Expected: {marrow_version}, found: {serde_arrow_marrow_version}" + ) + + check_feature_list( + "serde_arrow", + "docs.rs configuration", + serde_arrow_config["package"]["metadata"]["docs"]["rs"]["features"], + (arrow_features[0],), + ) + check_feature_list( + "marrow", + "docs.rs configuration", + marrow_config["package"]["metadata"]["docs"]["rs"]["features"], + ("serde", arrow_features[0]), + ) + + for feature in arrow_features: + check_arrow_feature( + "serde_arrow", + serde_arrow_config, + feature, + SERDE_ARROW_COMPONENTS, + extra_features=("marrow/arrow-{version}",), + ) + check_arrow_feature( + "marrow", + marrow_config, + feature, + MARROW_COMPONENTS, + ) + + *_, version = feature.partition("-") + check_feature_list( + "marrow_integration", + f"feature definition for {feature}", + marrow_integration_config["features"][feature], + [ + f"marrow/arrow-{version}", + f"dep:arrow-array-{version}", + f"dep:arrow-schema-{version}", + ], + ) + + for crate, config in [ + ("serde_arrow", serde_arrow_config), + ("marrow", marrow_config), + ]: + for name, dep in config["dependencies"].items(): + if dep.get("default-features", True): + raise ValueError( + f"Default features for {crate} dependency {name} not deactivated" + ) + + +def load_config(crate): + with open(SELF_PATH / crate / "Cargo.toml", "rb") as fobj: + return tomllib.load(fobj) + + +def load_script_config(): + with open(SELF_PATH / "arrow-versions.toml", "rb") as fobj: + return tomllib.load(fobj) + + +def check_feature_list(crate, label, actual, expected): + actual_features = sorted(actual) + expected_features = sorted(expected) + + if actual_features != expected_features: + raise ValueError( + f"Invalid {crate} {label}. " + f"Expected: {expected_features}, found: {actual_features}" + ) + + +def check_arrow_feature(crate, config, feature, components, extra_features=()): + *_, version = feature.partition("-") + check_feature_list( + crate, + f"feature definition for {feature}", + config["features"][feature], + [ + *(f"dep:{component}-{version}" for component in components), + *(feature.format(version=version) for feature in extra_features), + ], + ) + + for component in components: + check_dependency( + crate, + config, + f"{component}-{version}", + { + "package": component, + "version": version, + "optional": True, + "default-features": False, + }, + ) + + +def check_dependency(crate, config, name, expected): + actual = config["dependencies"].get(name) + if actual is None: + raise ValueError(f"Missing {crate} dependency {name}") + + if actual != expected: + raise ValueError( + f"Invalid {crate} dependency {name}. Expected: {expected}, found: {actual}" + ) + + +if __name__ == "__main__": + main() diff --git a/scripts/doc.py b/scripts/doc.py new file mode 100644 index 00000000..17bbe63d --- /dev/null +++ b/scripts/doc.py @@ -0,0 +1,72 @@ +import argparse +import pathlib +import subprocess +import tomllib + + +SELF_PATH = pathlib.Path(__file__).parents[1].resolve() + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--private", action="store_true", default=False) + parser.add_argument("--open", action="store_true", default=False) + doc(parser.parse_args()) + + +def doc(args): + extra_args = (("--document-private-items",) if args.private else ()) + ( + ("--open",) if args.open else () + ) + subprocess.run( + split_command( + cargo( + "doc", + *extra_args, + packages=("serde_arrow", "marrow"), + features=( + f"serde_arrow/{arrow_features()[0]}", + "marrow/serde", + f"marrow/{arrow_features()[0]}", + ), + ) + ), + check=True, + cwd=SELF_PATH, + ) + + +def arrow_features(): + return load_script_config()["arrow-features"] + + +def load_script_config(): + with open(SELF_PATH / "arrow-versions.toml", "rb") as fobj: + return tomllib.load(fobj) + + +def cargo(command, *extra_args, packages=(), features=()): + return " ".join( + part + for part in [ + "cargo", + command, + *(f"--package {package}" for package in packages), + "--features" if features else "", + ",".join(features) if features else "", + *extra_args, + ] + if part + ) + + +def split_command(command): + import shlex + + args = shlex.split(command.replace("\n", " ")) + print("::", *args) + return args + + +if __name__ == "__main__": + main() diff --git a/scripts/update-workflows.py b/scripts/update-workflows.py new file mode 100644 index 00000000..fe2345c7 --- /dev/null +++ b/scripts/update-workflows.py @@ -0,0 +1,534 @@ +import json +import pathlib +import shlex +import tomllib + + +SELF_PATH = pathlib.Path(__file__).parents[1].resolve() + +# actions/checkout v7.0.0 +ACTION_CHECKOUT = "actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0" + +# astral-sh/setup-uv v8.2.0 +ACTION_SETUP_UV = "astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39" + +# dtolnay/rust-toolchain branch 1.83.0 +ACTION_RUST_TOOLCHAIN = ( + "dtolnay/rust-toolchain@bd41891a8e7f4b8649f6d684415e1a6155fe4e22" +) + + +def main(): + arrow_features = load_script_config()["arrow-features"] + + local_workflow = workflow_local(arrow_features) + test_workflow = workflow_test(arrow_features) + release_marrow_workflow = release_workflow_template( + "marrow", + [ + { + "name": "Check marrow", + "run": cargo("check", packages=("marrow",), all_targets=True), + }, + *( + { + "name": f"Check marrow {feature}", + "run": cargo( + "check", + packages=("marrow",), + features=(feature,), + all_targets=True, + ), + } + for feature in ("serde", *arrow_features) + ), + { + "name": "Test marrow", + "run": cargo( + "test", + packages=("marrow",), + features=("serde", arrow_features[0]), + ), + }, + { + "name": "Package marrow", + "run": "cargo package -p marrow --allow-dirty", + }, + ], + ) + release_serde_arrow_workflow = release_workflow_template( + "serde_arrow", + [ + { + "name": "Check serde_arrow", + "run": cargo( + "check", + packages=("serde_arrow",), + all_targets=True, + ), + }, + *( + { + "name": f"Check serde_arrow {feature}", + "run": cargo( + "check", + packages=("serde_arrow",), + features=(feature,), + all_targets=True, + ), + } + for feature in arrow_features + ), + { + "name": "Test serde_arrow", + "run": cargo( + "test", + packages=("serde_arrow",), + features=(arrow_features[0],), + ), + }, + { + "name": "Package serde_arrow", + "run": "cargo package -p serde_arrow --allow-dirty", + }, + ], + ) + + update_workflow(SELF_PATH / ".github" / "workflows" / "local.yml", local_workflow) + update_workflow(SELF_PATH / ".github" / "workflows" / "test.yml", test_workflow) + update_workflow( + SELF_PATH / ".github" / "workflows" / "release-marrow.yml", + release_marrow_workflow, + ) + update_workflow( + SELF_PATH / ".github" / "workflows" / "release-serde-arrow.yml", + release_serde_arrow_workflow, + ) + + +def load_script_config(): + with open(SELF_PATH / "arrow-versions.toml", "rb") as fobj: + return tomllib.load(fobj) + + +def workflow_local(arrow_features): + return { + "name": "Local", + "on": { + "workflow_dispatch": {}, + }, + "env": {"CARGO_TERM_COLOR": "always"}, + "jobs": { + "format": { + "runs-on": "ubuntu-latest", + "steps": [ + *local_setup_steps(), + {"name": "Format Python", "run": "uv run ruff format x.py"}, + {"name": "Format Cargo", "run": "cargo fmt"}, + { + "name": "Format generated Rust", + "run": rustfmt_generated_command(), + }, + ], + }, + "check": { + "runs-on": "ubuntu-latest", + "steps": [ + *local_setup_steps(), + {"name": "Check Cargo.toml", "run": check_cargo_toml_command()}, + {"name": "Check workspace", "run": "cargo check"}, + { + "name": "Check serde_arrow", + "run": cargo( + "check", + packages=("serde_arrow",), + features=(arrow_features[0],), + all_targets=True, + ), + }, + { + "name": "Check marrow", + "run": cargo( + "check", + packages=("marrow",), + features=("serde", arrow_features[0]), + all_targets=True, + ), + }, + { + "name": "Clippy serde_arrow", + "run": cargo( + "clippy", + packages=("serde_arrow",), + features=(arrow_features[0],), + all_targets=True, + ), + }, + { + "name": "Clippy marrow", + "run": cargo( + "clippy", + packages=("marrow",), + features=("serde", arrow_features[0]), + all_targets=True, + ), + }, + { + "name": "Check support packages", + "run": cargo( + "check", + packages=( + "serde_arrow_bench", + "serde_arrow_example", + "serde_arrow_integration", + "marrow_integration", + ), + all_targets=True, + all_features=True, + ), + }, + { + "name": "Clippy support packages", + "run": cargo( + "clippy", + packages=( + "serde_arrow_bench", + "serde_arrow_example", + "serde_arrow_integration", + "marrow_integration", + ), + all_targets=True, + all_features=True, + ), + }, + ], + }, + "test": { + "runs-on": "ubuntu-latest", + "steps": [ + *local_setup_steps(), + { + "name": "Test serde_arrow", + "run": cargo( + "test", + packages=("serde_arrow",), + features=(arrow_features[0],), + quiet=True, + ), + }, + { + "name": "Test marrow", + "run": cargo( + "test", + packages=("marrow",), + features=("serde", arrow_features[0]), + quiet=True, + ), + }, + { + "name": "Integration test", + "run": integration_test_command(), + }, + ], + }, + "example": { + "runs-on": "ubuntu-latest", + "steps": [ + *local_setup_steps(), + { + "name": "Run example", + "run": "cargo run -p serde_arrow_example", + }, + { + "name": "Read example output", + "run": "uv run python -c 'import polars as pl; print(pl.read_ipc(\"serde_arrow_example.ipc\"))'", + }, + ], + }, + }, + } + + +def local_setup_steps(): + return [ + {"uses": ACTION_CHECKOUT}, + { + "name": "Install uv", + "uses": ACTION_SETUP_UV, + "with": {"enable-cache": True}, + }, + {"name": "rustc", "run": "rustc --version"}, + {"name": "cargo", "run": "cargo --version"}, + ] + + +def workflow_test(arrow_features): + return { + "name": "Test", + "on": { + "workflow_dispatch": {}, + "pull_request": { + "branches": ["main", "develop-*"], + "types": [ + "opened", + "edited", + "reopened", + "ready_for_review", + "synchronize", + ], + }, + }, + "env": {"CARGO_TERM_COLOR": "always"}, + "jobs": { + "msrv": { + "runs-on": "ubuntu-latest", + "steps": [ + {"uses": ACTION_CHECKOUT}, + { + "name": "Install Rust 1.83", + "uses": ACTION_RUST_TOOLCHAIN, + "with": {"toolchain": "1.83.0"}, + }, + {"name": "rustc", "run": "rustc --version"}, + {"name": "cargo", "run": "cargo --version"}, + { + "name": "Update dependencies", + "run": "cargo +stable update --config 'resolver.incompatible-rust-versions=\"fallback\"'", + }, + { + "name": "Check MSRV with arrow-53", + "run": "cargo +1.83.0 check --package serde_arrow --features arrow-53", + }, + ], + }, + "test": { + "runs-on": "ubuntu-latest", + "steps": [ + {"uses": ACTION_CHECKOUT}, + { + "name": "Install uv", + "uses": ACTION_SETUP_UV, + "with": {"enable-cache": True}, + }, + {"name": "rustc", "run": "rustc --version"}, + {"name": "cargo", "run": "cargo --version"}, + {"name": "Check Cargo.toml", "run": check_cargo_toml_command()}, + {"name": "Check", "run": "cargo check"}, + *( + { + "name": f"Check marrow {feature}", + "run": cargo( + "check", + packages=("marrow",), + features=(feature,), + all_targets=True, + ), + } + for feature in ("serde", *arrow_features) + ), + *( + { + "name": f"Check serde_arrow {feature}", + "run": cargo( + "check", + packages=("serde_arrow",), + features=(feature,), + all_targets=True, + ), + } + for feature in arrow_features + ), + { + "name": "Check support packages", + "run": cargo( + "check", + packages=( + "serde_arrow_bench", + "serde_arrow_example", + "serde_arrow_integration", + "marrow_integration", + ), + all_features=True, + ), + }, + { + "name": "Clippy serde_arrow", + "run": cargo( + "clippy", + packages=("serde_arrow",), + features=(arrow_features[0],), + all_targets=True, + ), + }, + { + "name": "Clippy marrow", + "run": cargo( + "clippy", + packages=("marrow",), + features=("serde", arrow_features[0]), + all_targets=True, + ), + }, + { + "name": "Clippy support packages", + "run": cargo( + "clippy", + packages=( + "serde_arrow_bench", + "serde_arrow_example", + "serde_arrow_integration", + "marrow_integration", + ), + all_targets=True, + all_features=True, + ), + }, + { + "name": "Check Python format", + "run": "uv run ruff format --check x.py", + }, + { + "name": "Check format", + "run": "cargo fmt --check", + }, + { + "name": "Check generated Rust format", + "run": rustfmt_generated_command(check=True), + }, + { + "name": "Build", + "run": cargo( + "build", + packages=("serde_arrow", "marrow"), + features=( + f"serde_arrow/{arrow_features[0]}", + "marrow/serde", + f"marrow/{arrow_features[0]}", + ), + ), + }, + { + "name": "Test", + "run": cargo( + "test", + packages=("serde_arrow", "marrow"), + features=( + f"serde_arrow/{arrow_features[0]}", + "marrow/serde", + f"marrow/{arrow_features[0]}", + ), + ), + }, + { + "name": "Integration test", + "run": integration_test_command(), + }, + { + "name": "Run example", + "run": "cargo run -p serde_arrow_example", + }, + { + "name": "Read example output", + "run": "uv run python -c 'import polars as pl; print(pl.read_ipc(\"serde_arrow_example.ipc\"))'", + }, + ], + }, + }, + } + + +def release_workflow_template(crate, check_steps): + return { + "name": f"Release {crate}", + "on": { + "push": {"tags": [f"{crate}/v*"]}, + }, + "env": {"CARGO_TERM_COLOR": "always"}, + "jobs": { + "publish": { + "runs-on": "ubuntu-latest", + "environment": "release", + "permissions": {"id-token": "write"}, + "steps": [ + {"uses": ACTION_CHECKOUT}, + {"name": "rustc", "run": "rustc --version"}, + {"name": "cargo", "run": "cargo --version"}, + *check_steps, + { + "name": "Auth with crates.io", + "uses": "rust-lang/crates-io-auth-action@v1", + "id": "auth", + }, + { + "name": "Publish to crates.io", + "run": f"cargo publish -p {crate}", + "env": { + "CARGO_REGISTRY_TOKEN": "${{ steps.auth.outputs.token }}", + }, + }, + ], + }, + }, + } + + +def update_workflow(path, workflow): + print(f":: update {path}") + with open(path, "wt", encoding="utf8", newline="\n") as fobj: + json.dump(workflow, fobj, indent=2) + + +def check_cargo_toml_command(): + return "uv run python scripts/check-cargo-toml.py" + + +def integration_test_command(): + return "cargo test -p serde_arrow_integration" + + +def rustfmt_generated_command(*, check=False): + paths = [ + *SELF_PATH.joinpath("marrow", "src", "impl_arrow").glob("impl*.rs"), + *SELF_PATH.joinpath("marrow_integration", "src", "tests").glob("*.rs"), + ] + return shell_args( + [ + "rustfmt", + *(("--check",) if check else ()), + *(path.relative_to(SELF_PATH) for path in sorted(paths)), + ] + ) + + +def cargo( + command, + *extra_args, + packages=(), + features=(), + all_targets=False, + all_features=False, + quiet=False, +): + return " ".join( + part + for part in [ + "cargo", + command, + "-q" if quiet else "", + "--all-targets" if all_targets else "", + "--all-features" if all_features else "", + *(f"--package {package}" for package in packages), + "--features" if features else "", + ",".join(features) if features else "", + *extra_args, + ] + if part + ) + + +def shell_args(args): + return " ".join(shlex.quote(str(arg)) for arg in args) + + +if __name__ == "__main__": + main() diff --git a/serde_arrow/src/internal/schema/tracer.rs b/serde_arrow/src/internal/schema/tracer.rs index 9ea22c12..191583ca 100644 --- a/serde_arrow/src/internal/schema/tracer.rs +++ b/serde_arrow/src/internal/schema/tracer.rs @@ -293,7 +293,7 @@ impl Tracer { StructField { tracer: Tracer::new( field.to_owned(), - format!("{}.{}", tracer.path, &field), + format!("{path}.{field}", path = tracer.path), tracer.options.clone(), ), name: field, diff --git a/serde_arrow_integration/tests/tests/utils.rs b/serde_arrow_integration/tests/tests/utils.rs index 79e9b315..32f8a604 100644 --- a/serde_arrow_integration/tests/tests/utils.rs +++ b/serde_arrow_integration/tests/tests/utils.rs @@ -36,13 +36,13 @@ pub fn execute_python(source: &str, paths: &[&str]) -> Result { let tmp_dir = PathBuf::from(env!("CARGO_TARGET_TMPDIR")); fs::create_dir_all(&tmp_dir)?; - let python = env::var("SERDE_ARROW_PYTHON").unwrap_or_else(|_| "python".into()); + let (mut command, python) = python_command()?; let script = dedent(source); let paths = paths .iter() .map(|path| tmp_dir.join(path)) .collect::>(); - let output = Command::new(&python) + let output = command .arg("-c") .arg(&script) .args(&paths) @@ -69,6 +69,38 @@ pub fn execute_python(source: &str, paths: &[&str]) -> Result { Ok(String::from_utf8(output.stdout)?) } +fn python_command() -> Result<(Command, String)> { + match env::var("SERDE_ARROW_PYTHON") { + Ok(python) => { + let path = PathBuf::from(&python); + let command = if path.is_relative() && path.components().count() > 1 { + resolve_relative_python_path(path)? + } else { + path + }; + Ok((Command::new(command), python)) + } + Err(_) => { + let mut command = Command::new("uv"); + command.args(["run", "python"]); + Ok((command, "uv run python".into())) + } + } +} + +fn resolve_relative_python_path(path: PathBuf) -> Result { + let current_dir_path = env::current_dir()?.join(&path); + if current_dir_path.exists() { + return Ok(current_dir_path); + } + + let workspace_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .parent() + .ok_or_else(|| std::io::Error::other("crate manifest directory has no parent"))? + .join(path); + Ok(workspace_path) +} + fn file_path(name: &str) -> Result { let tmp_dir = PathBuf::from(env!("CARGO_TARGET_TMPDIR")); fs::create_dir_all(&tmp_dir)?; diff --git a/uv.lock b/uv.lock index 2ed59d9e..30e729bf 100644 --- a/uv.lock +++ b/uv.lock @@ -142,31 +142,31 @@ wheels = [ [[package]] name = "numpy" -version = "2.4.6" +version = "2.5.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } +sdist = { url = "https://files.pythonhosted.org/packages/22/fd/89965aa4ac08c74998539fcbf24fa3540f3e15237fbeb6bcf9c908f4aade/numpy-2.5.1.tar.gz", hash = "sha256:a48a113e6afea91f5608793bafa7ef2ad481fefbda87ec5069f483de61cb9fa3", size = 20755553, upload-time = "2026-07-04T17:08:00.933Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/91/3ab2044d05fd16d343c5ac2e69b127f1b2854040dd20b193257c78028bd3/numpy-2.4.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079", size = 16683458, upload-time = "2026-05-18T23:35:38.353Z" }, - { url = "https://files.pythonhosted.org/packages/8e/62/764ce66fa4147ae6d73071a3abf804ffe606f174618697c571acdf26a7c9/numpy-2.4.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7", size = 14704559, upload-time = "2026-05-18T23:35:42.14Z" }, - { url = "https://files.pythonhosted.org/packages/60/61/23f27c172f022e04025b7dc2367f4d63c1a398120607ec896228649a6f48/numpy-2.4.6-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5", size = 5209716, upload-time = "2026-05-18T23:35:45.377Z" }, - { url = "https://files.pythonhosted.org/packages/03/71/21cf70dc6ea3e3acb95fc53a265b2fc248b981f0194ceb5b475271b8809d/numpy-2.4.6-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096", size = 6543947, upload-time = "2026-05-18T23:35:47.926Z" }, - { url = "https://files.pythonhosted.org/packages/d5/91/64288395ee1799bd2e0b04a305dce9666da90c961e1f3fe982a05ee1c036/numpy-2.4.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", size = 15685197, upload-time = "2026-05-18T23:35:50.863Z" }, - { url = "https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", size = 16638245, upload-time = "2026-05-18T23:35:54.752Z" }, - { url = "https://files.pythonhosted.org/packages/b8/0b/54f9da33128d7e350fab89c7455902eeae70349ee52bddb448dc4a576f45/numpy-2.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", size = 17036587, upload-time = "2026-05-18T23:35:58.355Z" }, - { url = "https://files.pythonhosted.org/packages/b6/f0/fdebc1052db1cc37c64beb22072d67cd6d1c71adca1299f53dec2b5e20d3/numpy-2.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", size = 18363226, upload-time = "2026-05-18T23:36:02.845Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b4/298628d98c72b57e57f7165ae6a481a1deaf6f3c28262a6e4c739c275930/numpy-2.4.6-cp314-cp314-win32.whl", hash = "sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1", size = 6010196, upload-time = "2026-05-18T23:36:05.92Z" }, - { url = "https://files.pythonhosted.org/packages/df/ac/46de6dda46478f7942f839e094970be2d4a861e005c4b3bf07c92e291a09/numpy-2.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261", size = 12450334, upload-time = "2026-05-18T23:36:09.107Z" }, - { url = "https://files.pythonhosted.org/packages/78/92/b8b798ac784102c0da830d2257d59358e3d3d90d1e2b3f2575dad976c5cf/numpy-2.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6", size = 10495678, upload-time = "2026-05-18T23:36:12.766Z" }, - { url = "https://files.pythonhosted.org/packages/30/34/ec28d1aa8115971537c01469ab2011ee96827930f0a124de1000cc2a7ed7/numpy-2.4.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a", size = 14823672, upload-time = "2026-05-18T23:36:16.473Z" }, - { url = "https://files.pythonhosted.org/packages/16/bd/f6d1fede4e54e8042a7ff97bb495510f3c220f94bcd9e8b228e87c92cc0d/numpy-2.4.6-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e", size = 5328731, upload-time = "2026-05-18T23:36:19.767Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f0/e105b9e2fd728a9910103884decd6951d9dd73896b914a98d9a231de02ee/numpy-2.4.6-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e", size = 6649805, upload-time = "2026-05-18T23:36:22.266Z" }, - { url = "https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", size = 15730496, upload-time = "2026-05-18T23:36:25.713Z" }, - { url = "https://files.pythonhosted.org/packages/51/e7/38d3ea825dcab85a591734decb2f6c67caa7c8367d374df1a1c3842f9b07/numpy-2.4.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", size = 16679616, upload-time = "2026-05-18T23:36:29.652Z" }, - { url = "https://files.pythonhosted.org/packages/93/b7/caabfdf53edf663e0b4eb74d7d405d83baef09eb5e83bcd32d601d72b93e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895", size = 17085145, upload-time = "2026-05-18T23:36:33.449Z" }, - { url = "https://files.pythonhosted.org/packages/f9/45/68d7c33a6bcf3e5aa3bdbd57a367e6f615286dfd6482f97e8ffeb734306e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", size = 18403813, upload-time = "2026-05-18T23:36:37.369Z" }, - { url = "https://files.pythonhosted.org/packages/9c/50/0753655aa844c99cd9e018aacf76f130f1bd81d881bb74bc0aef5d73a8ba/numpy-2.4.6-cp314-cp314t-win32.whl", hash = "sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063", size = 6156982, upload-time = "2026-05-18T23:36:40.817Z" }, - { url = "https://files.pythonhosted.org/packages/b2/d4/7c67becf668f973cb490cec3e98dfd799d866f9c989a54d355672cfa0db6/numpy-2.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627", size = 12638908, upload-time = "2026-05-18T23:36:43.996Z" }, - { url = "https://files.pythonhosted.org/packages/43/bb/e1c71a4295b1b1d1393d50dbb4f2a36283c6859d9d3892e84f00ec5a91d5/numpy-2.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", size = 10565867, upload-time = "2026-05-18T23:36:47.114Z" }, + { url = "https://files.pythonhosted.org/packages/db/f4/731b6085a83faf6ca843394cbd5e217280c214399f7e8b21b9f552af0ae2/numpy-2.5.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:7c786fe9a5bbe360022e584c5a34cf6b54265c71bd7ec8ac3d8fec38968071f8", size = 16795063, upload-time = "2026-07-04T17:07:07.374Z" }, + { url = "https://files.pythonhosted.org/packages/bf/64/0e215f2048dd11a55bb989ed41b3585ef57452404e638d703a211a3e4157/numpy-2.5.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32985c896d897419ef8da6917872d80b78ad0ea26d85b23245c7366ffde76d75", size = 11776652, upload-time = "2026-07-04T17:07:09.907Z" }, + { url = "https://files.pythonhosted.org/packages/b5/59/2b844c7a6e9deff69b404a66221e1542937734f65d5e6e39411876053862/numpy-2.5.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:efd736408cc97c79b9e6917338dfc8f06013b2274f992e96b1d9a81a71e2a2c2", size = 5335944, upload-time = "2026-07-04T17:07:12.227Z" }, + { url = "https://files.pythonhosted.org/packages/86/51/9bf7cb2cabcebc9e017e4ec7e6322b378317a542c08b4cb68479c1efc716/numpy-2.5.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:ab84dc6b074fa881cae55bea94cc4f68e285181ba7f32497bf7dee6b1496165b", size = 6656266, upload-time = "2026-07-04T17:07:14.368Z" }, + { url = "https://files.pythonhosted.org/packages/83/3e/fb7615b211b82a32f44d5180a6d421b61f84d4fadd578b48ba4ac34e189f/numpy-2.5.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:caf3e317d33d60c37986b452613f4ab51246d0691350c03d0cb4a898627f4a95", size = 15179720, upload-time = "2026-07-04T17:07:16.272Z" }, + { url = "https://files.pythonhosted.org/packages/41/5f/0f992cb24560673496c5d68de61913b57166ce530ffda07c1f280e0cc464/numpy-2.5.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:54ad769f17bc2d833b620851989f62054fb9ab93c969d9e1dc3c8e3d56beea21", size = 16664835, upload-time = "2026-07-04T17:07:19.021Z" }, + { url = "https://files.pythonhosted.org/packages/a2/2f/97d6475ee91afe2587797d09446f9d3e475ad4cb681662d824809327b75a/numpy-2.5.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c12afb53450fa976d4c681c50a7423729a4c51c0465ed9f32b8a9cabbc472373", size = 16539135, upload-time = "2026-07-04T17:07:22.015Z" }, + { url = "https://files.pythonhosted.org/packages/c4/5b/4db81e4ba0be7e2776b1de68c82aa862c7f8ec27e1b4927d4ae075e20678/numpy-2.5.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e8c11c405efc5ff6816d5983c96cdfa215bab3428961243af3ff59b228490438", size = 18426684, upload-time = "2026-07-04T17:07:24.941Z" }, + { url = "https://files.pythonhosted.org/packages/1f/64/c0ba2d90724d450279a7df8f32057241070250a26a7e2b5337d77347f481/numpy-2.5.1-cp314-cp314-win32.whl", hash = "sha256:f2479a47f8d5932d1718168a681ad6e536a9df484c83cfcf9de365e164537ace", size = 6116103, upload-time = "2026-07-04T17:07:27.622Z" }, + { url = "https://files.pythonhosted.org/packages/c1/1a/837f9ed7405adcd7a40538792eb169eddd8fa5630c16a1ef49dae71a30f4/numpy-2.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:24d0eb82c0541d3415a33425db64ae439dffccd7b4dbcb30e7c35120205c506a", size = 12562177, upload-time = "2026-07-04T17:07:29.887Z" }, + { url = "https://files.pythonhosted.org/packages/22/ed/49707938b6dd0a78a9178dd93227dc89e4c11af47f5c798d70366e8d0483/numpy-2.5.1-cp314-cp314-win_arm64.whl", hash = "sha256:5a4c988b38d261deeeaad9954e3deb091ad905c94e8bb6708654ef1d97f286b0", size = 10627739, upload-time = "2026-07-04T17:07:32.568Z" }, + { url = "https://files.pythonhosted.org/packages/a6/c7/bb4b882cfe7f299cbc8b66e42e7dd78cf9d14e40f9469fc5e3db7e15b3bd/numpy-2.5.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a33276be12fa045805f477f22482088b66bb758ffbe89a9d21457de863a32e22", size = 11894709, upload-time = "2026-07-04T17:07:34.941Z" }, + { url = "https://files.pythonhosted.org/packages/40/3f/5af7f4a7f6224aef48017aa82bb6174c7a659d724be0c75017b7e64a55b4/numpy-2.5.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:f089d7b00756190aacf1f5d34bdf38c3c430ac82b4f868f8cede73380460fce7", size = 5453810, upload-time = "2026-07-04T17:07:37.495Z" }, + { url = "https://files.pythonhosted.org/packages/20/c9/3474309bc94d634d3f9c3eddf03250ecb8c22cd948ef16fef69a77cc5d7b/numpy-2.5.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:09e9bfd8d2cf479c7d174804fb3811c53a8e9f20a37444008606b57d6b7a826d", size = 6761189, upload-time = "2026-07-04T17:07:39.563Z" }, + { url = "https://files.pythonhosted.org/packages/90/8a/558ae39fdd55d7e7f7fef9a84a6e964ac6b23edbd2a07e52bb084500507d/numpy-2.5.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e68d8dd1e7eba712948f2053a29ec86917bc70ba1358df869d9f06649ef9cf09", size = 15225039, upload-time = "2026-07-04T17:07:41.682Z" }, + { url = "https://files.pythonhosted.org/packages/63/27/ca7392b2d030277bdf0273e7d23255b3ee57d57a7c170a6f4fb3981e1e5d/numpy-2.5.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:99d5095fa265a0c4152e7bb12759e14381ef5496152f1ce58f44bdf55c44beb4", size = 16701306, upload-time = "2026-07-04T17:07:44.611Z" }, + { url = "https://files.pythonhosted.org/packages/02/42/03d53ae7996c44d4374a8262e9dc41671fd56cbb98f7d47ef85cf5da4c6b/numpy-2.5.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ab87a91b3cc3382b8956095bd8f95e00cf679bb81554339be1a2ba404a1473c1", size = 16589955, upload-time = "2026-07-04T17:07:47.694Z" }, + { url = "https://files.pythonhosted.org/packages/7b/15/6c1784ae469640e65db111e9a34b3d0f14d91e8a38b9ce34810ced370dbb/numpy-2.5.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:224ca51130ef7da85bea2191625181cb4f337f9cb64b471f10c1a12aa8b60077", size = 18464252, upload-time = "2026-07-04T17:07:50.684Z" }, + { url = "https://files.pythonhosted.org/packages/94/a8/f98e50356cf167df656c526c2dfeec2d7dde182f2a3da4b458a5938e2776/numpy-2.5.1-cp314-cp314t-win32.whl", hash = "sha256:6eab239876581b2b3c5a242281b6007bbdbcd1c7085d7709bb57c5929b11e6bf", size = 6263298, upload-time = "2026-07-04T17:07:53.445Z" }, + { url = "https://files.pythonhosted.org/packages/72/ac/96ae880cdecad0b3275d9359fcec72667b49a4863c9f12942e43679dda02/numpy-2.5.1-cp314-cp314t-win_amd64.whl", hash = "sha256:83ce9c80d5b521b0d77ddcbe5447c218d247929b6cc056ca5351342accfff0af", size = 12748623, upload-time = "2026-07-04T17:07:55.384Z" }, + { url = "https://files.pythonhosted.org/packages/a1/5a/4d2b1601df3602dba7a14f3348ba9bfe94a18adb428e693df6154c293831/numpy-2.5.1-cp314-cp314t-win_arm64.whl", hash = "sha256:5a6db61f9aaa57e369905c67d852045d3c4f7126405b29d09b19dec118e9c9cb", size = 10697674, upload-time = "2026-07-04T17:07:58.506Z" }, ] [[package]] @@ -213,52 +213,52 @@ wheels = [ [[package]] name = "polars" -version = "1.41.2" +version = "1.42.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "polars-runtime-32" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ff/f9/aeda46259b0669247a160315d2d51269de9504b9dd2f70acadbcb22f46b7/polars-1.41.2.tar.gz", hash = "sha256:256d6731162371b77f3f29a55eacb8c0fc740ddb1a293a01d2ef5b5393c5c708", size = 737996, upload-time = "2026-05-29T17:39:15.604Z" } +sdist = { url = "https://files.pythonhosted.org/packages/27/99/fe77f10a13a778705ef05b499fc708c9a0b0a3680d9eb6bc6e1b6a6b9914/polars-1.42.1.tar.gz", hash = "sha256:2fe94f3059334650bd850ae19a9c165dcd5d9cb12cd95ea04de2201662e70e8a", size = 741532, upload-time = "2026-06-30T04:57:51.504Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/22/28f62d24f7db56ac4343588f9362d49b7b4177e55ac47a466fe696b0099b/polars-1.41.2-py3-none-any.whl", hash = "sha256:23ce9a2910b6e3e8d4258770bf44aa17170958df7af6e85feedf4458a04d8d29", size = 833445, upload-time = "2026-05-29T17:37:05.576Z" }, + { url = "https://files.pythonhosted.org/packages/be/6a/edd939cc6fa04b6415aaa9bf19720fc74ead81234b3d38542e0005816d4d/polars-1.42.1-py3-none-any.whl", hash = "sha256:3c0c65cdfa21a621650c4bdcbbccf93964d052fd766c3e70e84a55d961c259fd", size = 837622, upload-time = "2026-06-30T04:56:34.686Z" }, ] [[package]] name = "polars-runtime-32" -version = "1.41.2" +version = "1.42.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/56/54e3ea0e9b64f327179049e4742241cc6b1d3e8fa414b05a057dd26df367/polars_runtime_32-1.41.2.tar.gz", hash = "sha256:7af09ec1ab053da2c9669e8d15f809a4083a29be05db57111688b8051062af56", size = 2989474, upload-time = "2026-05-29T17:39:17.257Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/59/15bcc4dac380c6d63efa5446d8317f22671cbd6c9dadd576bd17a334c45a/polars_runtime_32-1.42.1.tar.gz", hash = "sha256:4d4809e1c1b9a6611f6944f27b24abea902b5159e6b6fa262fd716e947af5afd", size = 3045460, upload-time = "2026-06-30T04:57:52.866Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/9b/fe72a3811c0357cdb06c67bdc7695fa1623ad47948fc523195f5ac31037f/polars_runtime_32-1.41.2-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:95a08346dac337357cdb825c8076df7d36da54c4caa59a5cb41d0a30691c5edd", size = 52265283, upload-time = "2026-05-29T17:37:09.407Z" }, - { url = "https://files.pythonhosted.org/packages/0a/93/fab9da803fd80d9e83ef88c20932f637a10bc611b20415fc322eec84bc44/polars_runtime_32-1.41.2-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:dedfaeec2c7f995298da7319dd9431d662e5dd1d0ec51b1459df4a0234ceff52", size = 46571222, upload-time = "2026-05-29T17:37:13.698Z" }, - { url = "https://files.pythonhosted.org/packages/c8/2a/8843f34a8ac57acd058a39b87b03b580dd352a490e9dae0415e02033bdd4/polars_runtime_32-1.41.2-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18eea22c5cc34e27f8a60950458ad81e6a9ea75e89363ca1367e14e7e7f781fc", size = 50409372, upload-time = "2026-05-29T17:37:17.875Z" }, - { url = "https://files.pythonhosted.org/packages/6c/c6/92b352fe88cf51bd0a19fb99e1c0cbe46aa26c14dcf7995b89869cd932ae/polars_runtime_32-1.41.2-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2630540dfdfb0f36f9b04a07c7c2e3f50bf2ad384113263c1c812007ee9141e0", size = 56405484, upload-time = "2026-05-29T17:37:22.684Z" }, - { url = "https://files.pythonhosted.org/packages/74/c4/bae3174c3b02f6b441d2e58594387abcd509f67a098f682a83b195f08966/polars_runtime_32-1.41.2-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:20e969e08f9b137e233c04cc04de73d9795f89eb77d34854e40a025965a43763", size = 50603512, upload-time = "2026-05-29T17:37:27.422Z" }, - { url = "https://files.pythonhosted.org/packages/f4/ed/f2d26ae02d92c2689056838ed59e2a626326ad23c2831d58637d25f6c82a/polars_runtime_32-1.41.2-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e7016a3deb641b64a31447abbbee0f34bd020a6a9ae34ee6b743837def15e2a4", size = 54328561, upload-time = "2026-05-29T17:37:32.587Z" }, - { url = "https://files.pythonhosted.org/packages/9b/c4/9c3831cc885dc7769e59abf8f583821a5fb4403fd0e4eba0ccc6d47a3d4b/polars_runtime_32-1.41.2-cp310-abi3-win_amd64.whl", hash = "sha256:1e5e5377c315e0dcafdfb2a31adc546abbaeb3f9cb1864e6536523d2af473265", size = 51978643, upload-time = "2026-05-29T17:37:37.443Z" }, - { url = "https://files.pythonhosted.org/packages/cd/c6/79e9f3f270270d7ed5575d92b7bfef49f01abd9275447161275b23b553a8/polars_runtime_32-1.41.2-cp310-abi3-win_arm64.whl", hash = "sha256:843d96f69d18eca53429c1198e58891db7f18111f83b9c419bb45ad9d73eaed5", size = 46006901, upload-time = "2026-05-29T17:37:42.522Z" }, + { url = "https://files.pythonhosted.org/packages/62/29/16ff6e4e91d71e530d3581f45e342a9cc35072ac6b31dcbc2fa33de2569e/polars_runtime_32-1.42.1-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bbdc26d68ee5b23b0ce227fa0599220aa35b77c826b6b0a6b2d8e7f6c1c36974", size = 53117325, upload-time = "2026-06-30T04:56:37.972Z" }, + { url = "https://files.pythonhosted.org/packages/04/8e/4f8296fcfd1347f1351342fecf13bf2430d7efbae2f1f45964ec7930a99e/polars_runtime_32-1.42.1-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:f6c0288be940b607dc4a7476c01e67fb6bbee93f5f1dd42c64970274c71008ba", size = 47446251, upload-time = "2026-06-30T04:56:41.459Z" }, + { url = "https://files.pythonhosted.org/packages/88/2e/0d66a7deadc453b890c3391034ca8ab4b05d0beaebbb92a7d65199fba61b/polars_runtime_32-1.42.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635d9dbcae2302ae223afb395d5cd220bffa61a53d0ab6871d17c8bc830101cf", size = 51359402, upload-time = "2026-06-30T04:56:44.595Z" }, + { url = "https://files.pythonhosted.org/packages/5d/10/ffb85fa380bc9c9000dc35f40f44954dde49023018501c54faab94b3a39e/polars_runtime_32-1.42.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d059e8e53cc114ff82f9bd791fd341dc53534a2c745e6f6aa37594c3a93f01fe", size = 57302723, upload-time = "2026-06-30T04:56:47.609Z" }, + { url = "https://files.pythonhosted.org/packages/c2/63/ca50adc62e44224ca5c622a842ba6f35ee87d1d40ef0df7ea2ed6c6edb08/polars_runtime_32-1.42.1-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f91f0b13588324905682809d270e1de5f1990c908721c8527657d77a044c9919", size = 51515673, upload-time = "2026-06-30T04:56:50.88Z" }, + { url = "https://files.pythonhosted.org/packages/63/c3/08fbbf38deaa17bf34a601d327cb7451074098673c78b7c1a8538dde9794/polars_runtime_32-1.42.1-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8b8bf972d99d48aaaa2582e2bce966a6f43bc815bd8725d15f5cab9e2fb15d17", size = 55217259, upload-time = "2026-06-30T04:56:53.834Z" }, + { url = "https://files.pythonhosted.org/packages/d1/0e/51db89361668fe077a835fc579277f824ba526e7daf7b94d23d25439e0d0/polars_runtime_32-1.42.1-cp310-abi3-win_amd64.whl", hash = "sha256:e9364c26da389a8b7339e4d29e20a3d12af730247e6ed3b7804bddce2477f428", size = 52715432, upload-time = "2026-06-30T04:56:57.109Z" }, + { url = "https://files.pythonhosted.org/packages/76/c5/2fb8592d691bd114de25d9c84300b23541dca7060eac11d7b4bed0327786/polars_runtime_32-1.42.1-cp310-abi3-win_arm64.whl", hash = "sha256:7051226e6b42ffc395a7a9190377cd28649fbfb991b8f85c6271f4e1cfb736fb", size = 46718300, upload-time = "2026-06-30T04:56:59.855Z" }, ] [[package]] name = "pyarrow" -version = "24.0.0" +version = "25.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/91/13/13e1069b351bdc3881266e11147ffccf687505dbb0ea74036237f5d454a5/pyarrow-24.0.0.tar.gz", hash = "sha256:85fe721a14dd823aca09127acbb06c3ca723efbd436c004f16bca601b04dcc83", size = 1180261, upload-time = "2026-04-21T10:51:25.837Z" } +sdist = { url = "https://files.pythonhosted.org/packages/27/f3/95428098d1fa7d04432fb750eed06b41304c2f6a5d3319985e64db2d9d41/pyarrow-25.0.0.tar.gz", hash = "sha256:d2d697008b5ec06d75952ef260c2e9a8a0f6ccfce24266c04c9c8ade927cb3b4", size = 1199181, upload-time = "2026-07-10T08:29:50.116Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ad/80/d022a34ff05d2cbedd8ccf841fc1f532ecfa9eb5ed1711b56d0e0ea71fc9/pyarrow-24.0.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:1cc9057f0319e26333b357e17f3c2c022f1a83739b48a88b25bfd5fa2dc18838", size = 35007997, upload-time = "2026-04-21T10:49:48.796Z" }, - { url = "https://files.pythonhosted.org/packages/1a/ff/f01485fda6f4e5d441afb8dd5e7681e4db18826c1e271852f5d3957d6a80/pyarrow-24.0.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e6f1278ee4785b6db21229374a1c9e54ec7c549de5d1efc9630b6207de7e170b", size = 36678720, upload-time = "2026-04-21T10:49:55.858Z" }, - { url = "https://files.pythonhosted.org/packages/9e/c2/2d2d5fea814237923f71b36495211f20b43a1576f9a4d6da7e751a64ec6f/pyarrow-24.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:adbbedc55506cbdabb830890444fb856bfb0060c46c6f8026c6c2f2cf86ae795", size = 45741852, upload-time = "2026-04-21T10:50:04.624Z" }, - { url = "https://files.pythonhosted.org/packages/8e/3a/28ba9c1c1ebdbb5f1b94dfebb46f207e52e6a554b7fe4132540fde29a3a0/pyarrow-24.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:ae8a1145af31d903fa9bb166824d7abe9b4681a000b0159c9fb99c11bc11ad26", size = 48889852, upload-time = "2026-04-21T10:50:12.293Z" }, - { url = "https://files.pythonhosted.org/packages/df/51/4a389acfd31dca009f8fb82d7f510bb4130f2b3a8e18cf00194d0687d8ac/pyarrow-24.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d7027eba1df3b2069e2e8d80f644fa0918b68c46432af3d088ddd390d063ecde", size = 49445207, upload-time = "2026-04-21T10:50:20.677Z" }, - { url = "https://files.pythonhosted.org/packages/19/4b/0bab2b23d2ae901b1b9a03c0efd4b2d070256f8ce3fc43f6e58c167b2081/pyarrow-24.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e56a1ffe9bf7b727432b89104cc0849c21582949dd7bdcb34f17b2001a351a76", size = 51954117, upload-time = "2026-04-21T10:50:29.14Z" }, - { url = "https://files.pythonhosted.org/packages/29/88/f4e9145da0417b3d2c12035a8492b35ff4a3dbc653e614fcfb51d9dedb38/pyarrow-24.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:38be1808cdd068605b787e6ca9119b27eb275a0234e50212c3492331680c3b1e", size = 28001155, upload-time = "2026-04-21T10:51:22.337Z" }, - { url = "https://files.pythonhosted.org/packages/79/4f/46a49a63f43526da895b1a45bbb51d5baf8e4d77159f8528fc3e5490007f/pyarrow-24.0.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:418e48ce50a45a6a6c73c454677203a9c75c966cb1e92ca3370959185f197a05", size = 35250387, upload-time = "2026-04-21T10:50:35.552Z" }, - { url = "https://files.pythonhosted.org/packages/a0/da/d5e0cd5ef00796922404806d5f00325cdadc3441ce2c13fe7115f2df9a64/pyarrow-24.0.0-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:2f16197705a230a78270cdd4ea8a1d57e86b2fdcbc34a1f6aebc72e65c986f9a", size = 36797102, upload-time = "2026-04-21T10:50:42.417Z" }, - { url = "https://files.pythonhosted.org/packages/34/c7/5904145b0a593a05236c882933d439b5720f0a145381179063722fbfc123/pyarrow-24.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:fb24ac194bfc5e86839d7dcd52092ee31e5fe6733fe11f5e3b06ef0812b20072", size = 45745118, upload-time = "2026-04-21T10:50:49.324Z" }, - { url = "https://files.pythonhosted.org/packages/13/d3/cca42fe166d1c6e4d5b80e530b7949104d10e17508a90ae202dac205ce2a/pyarrow-24.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:9700ebd9a51f5895ce75ff4ac4b3c47a7d4b42bc618be8e713e5d56bacf5f931", size = 48844765, upload-time = "2026-04-21T10:50:55.579Z" }, - { url = "https://files.pythonhosted.org/packages/b0/49/942c3b79878ba928324d1e17c274ed84581db8c0a749b24bcf4cbdf15bd3/pyarrow-24.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d8ddd2768da81d3ee08cfea9b597f4abb4e8e1dc8ae7e204b608d23a0d3ab699", size = 49471890, upload-time = "2026-04-21T10:51:02.439Z" }, - { url = "https://files.pythonhosted.org/packages/76/97/ff71431000a75d84135a1ace5ca4ba11726a231a8007bbb320a4c54075d5/pyarrow-24.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:61a3d7eaa97a14768b542f3d284dc6400dd2470d9f080708b13cd46b6ae18136", size = 51932250, upload-time = "2026-04-21T10:51:10.576Z" }, - { url = "https://files.pythonhosted.org/packages/51/be/6f79d55816d5c22557cf27533543d5d70dfe692adfbee4b99f2760674f38/pyarrow-24.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:c91d00057f23b8d353039520dc3a6c09d8608164c692e9f59a175a42b2ae0c19", size = 28131282, upload-time = "2026-04-21T10:51:16.815Z" }, + { url = "https://files.pythonhosted.org/packages/55/c7/581ccbcdb3d897eb2893328d68db3d52eca373bf2a7e964d0a6276b8e85b/pyarrow-25.0.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:72132b9a8a0a1840197794d4dea26080069b6b0981c116bc078762dc9691b21b", size = 35878945, upload-time = "2026-07-10T08:28:18.222Z" }, + { url = "https://files.pythonhosted.org/packages/64/d1/ccb01db7329ea0411ef4fbd9b62a04d3268b36777d4e758d5e39b91ddeab/pyarrow-25.0.0-cp314-cp314-macosx_12_0_x86_64.whl", hash = "sha256:e009ef945e498dca2f050ea10d2e9764cb44017254826fc4574fdb8d2530173b", size = 37630854, upload-time = "2026-07-10T08:28:23.452Z" }, + { url = "https://files.pythonhosted.org/packages/af/9f/2d81ba89d1e4198d0cb25fe7529de936830fdaec0db926bb52a1ef7080d4/pyarrow-25.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:f57a39dbcb416345401c2e77a4373669b45fd111a1768e6cf267a7a0607ff0ec", size = 46905617, upload-time = "2026-07-10T08:28:29.376Z" }, + { url = "https://files.pythonhosted.org/packages/6a/29/0ed312ec800fb536f93783215126cee4b8977dcfeccba6f0f44df0cc87d7/pyarrow-25.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:447df764beb07c544f0178a5f6b70ef44b9ecf382b3cdfad4c2d7867353c3887", size = 50119765, upload-time = "2026-07-10T08:28:35.826Z" }, + { url = "https://files.pythonhosted.org/packages/ca/88/cab5063ba0c4d46a9f6b4b7eb1c9029dc0302d65cd5ab3510c949a386568/pyarrow-25.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac5dfeee59f9ceb4d45ba76e83b026c38c24334135bb329d8274baa49cec3c62", size = 50027563, upload-time = "2026-07-10T08:28:43.848Z" }, + { url = "https://files.pythonhosted.org/packages/7b/fb/4d24f1b7fe2e042dc4ef315ef75e4e702d8e46fe10c37e63caff00502b03/pyarrow-25.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f0f100dacf2c0f400601664a79d1a907ced4740514bb2b00917341038e2ce76f", size = 53162437, upload-time = "2026-07-10T08:28:52.819Z" }, + { url = "https://files.pythonhosted.org/packages/fa/65/da20806de93ca6ee91e72cb6a9b08b3ac890b46efc8d94a7326c651c4c81/pyarrow-25.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:2e093efbecb5317372f819228fa4b4e6157eee48d3f0a7b0303705ebf81a7104", size = 28613262, upload-time = "2026-07-10T08:29:47.544Z" }, + { url = "https://files.pythonhosted.org/packages/86/9f/c632afb1d3ef4a7814cee236718235f3a47eac46e97eb87df40f550b6b48/pyarrow-25.0.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:26be35b80780d2d21f4bae3d568b1666337c3a89722cc1794c956a77017cb24e", size = 36120702, upload-time = "2026-07-10T08:28:59.577Z" }, + { url = "https://files.pythonhosted.org/packages/36/0a/093d53a0e72ad06e45d6443e00651bbc2d21af4211295086cbf4d873d3b9/pyarrow-25.0.0-cp314-cp314t-macosx_12_0_x86_64.whl", hash = "sha256:6f4812bfbf11ca7d8faf59eb8fff8bf4dd25ce3a38b62baa010cc17a0926d1b2", size = 37750674, upload-time = "2026-07-10T08:29:06.916Z" }, + { url = "https://files.pythonhosted.org/packages/8a/18/b37fc31a69cff4bdfb8842683def5612f551b93fff6f44375e4a4a6a5535/pyarrow-25.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:b8af8ceedf0c9c160fd2b63440f2d205b9404db85866c1217bfea601de7cfb50", size = 46912304, upload-time = "2026-07-10T08:29:14.656Z" }, + { url = "https://files.pythonhosted.org/packages/32/35/5cae19ba72493e5598022468b56f6a5571f399f485bf412f157356476caa/pyarrow-25.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:c70a5fd9a82bd1a702fd482bdc62d38dcb672fb2b449b1d7c0d7d1f4be7b7bfe", size = 50073652, upload-time = "2026-07-10T08:29:22.467Z" }, + { url = "https://files.pythonhosted.org/packages/2e/a5/ddd508424bdfd5e6945765e9e2ffc687e2f6115972badc8ecf423076c407/pyarrow-25.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0490a7f8b38ffe11cc26526b50c65d111cb54ddac3717cec781806793f1244dc", size = 50058654, upload-time = "2026-07-10T08:29:29.689Z" }, + { url = "https://files.pythonhosted.org/packages/5f/a4/324d0db203ff5eebe8694ec2d6ec5a23f9aaa5d02e5b8c692914c518c33c/pyarrow-25.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e83916bbcf380866b4e14255850b33323ff678dc9758411d0409cdd2523880b0", size = 53140153, upload-time = "2026-07-10T08:29:36.041Z" }, + { url = "https://files.pythonhosted.org/packages/bd/8d/d236e9c82fe315f9128885c8be3ec719f41965a1eb6b6f4b42470904cd41/pyarrow-25.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:13240f0d3dc5932ccd0bfa90cd76d835680b9d94a7661c635df4b703d40ce849", size = 28743657, upload-time = "2026-07-10T08:29:42.742Z" }, ] [[package]] @@ -284,27 +284,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.17" +version = "0.15.22" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/a9/3abdf488f1bf3d24c699415e454ed554a6350d5d89ce183be1ee0a3361ac/ruff-0.15.17.tar.gz", hash = "sha256:2ec446937fd16c8c4de2674a209cc5af64d9c6f17d21fbf1151054fa0bcf5219", size = 4743346, upload-time = "2026-06-11T17:54:47.663Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/06/ae069393fc66e8ff33036d4b368003833bf6e88ccf182e17e7a2f1c754fd/ruff-0.15.22.tar.gz", hash = "sha256:3f15175b1fb580126f58285a5dae6b2ea89000136d980c64499211f116b54809", size = 4785063, upload-time = "2026-07-16T15:14:13.244Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/4d/e11259f5da07cb6afb2d074c31bf09da9671993f7329d4f15d2fdc458301/ruff-0.15.17-py3-none-linux_armv6l.whl", hash = "sha256:d9feddb927fc68bd295f5eebc587a7e42cfaf9b65f60ca4a2386febff575da8f", size = 10856677, upload-time = "2026-06-11T17:54:49.533Z" }, - { url = "https://files.pythonhosted.org/packages/29/3e/772d679e1a0dc058e58875bd2c0cb713a0530877b4a76fee3c7966df0d49/ruff-0.15.17-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:25805a226d741c47d274a35ad5c10a7dde175fcddfa511d7cf3da0a21eb3eab7", size = 11223443, upload-time = "2026-06-11T17:55:00.573Z" }, - { url = "https://files.pythonhosted.org/packages/68/58/bd41f7688b2fd5623012605130ed70e60aa7f2244baa3d5066bdd61530c8/ruff-0.15.17-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f6ad73b14c2d18a3bf8ad7cb6974294d7f613a7898604826058e6ac64918ef4d", size = 10566458, upload-time = "2026-06-11T17:55:07.52Z" }, - { url = "https://files.pythonhosted.org/packages/d8/5b/733371013fcf1ec339e477ece6ab42bfe10bdd9bba8ee88a9516aa56bfc0/ruff-0.15.17-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ba0c1e4f95bcb3869d0d30cbd5917071ef2e28665abfec970cdab0492c713ed", size = 10914483, upload-time = "2026-06-11T17:55:05.501Z" }, - { url = "https://files.pythonhosted.org/packages/bd/cc/6f24251cc0252f7239391ccb85833f320efad14ebe5b443943f37ced6332/ruff-0.15.17-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:81647960f10bff57d2e51cadd0c3950fe598400c852863a038720ef5b8cca91e", size = 10647497, upload-time = "2026-06-11T17:54:57.733Z" }, - { url = "https://files.pythonhosted.org/packages/68/dd/0d10c17ce1a1624d6fc3156309c3f834fdb5dfaad026ec90c85684f3990e/ruff-0.15.17-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e01a84ddbc8c16c23055ba3924476850f1bbc1917cebbb9376665a63e74260d", size = 11416967, upload-time = "2026-06-11T17:54:51.461Z" }, - { url = "https://files.pythonhosted.org/packages/2f/91/556bfb156f6144f355e831c23db00b2fc4120f86b3ce81cc5f7fd2df51f3/ruff-0.15.17-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fe9f653152f8f294f9f7e03bf3a453d8b4a27f7a59c78c8666167f2b17b96c", size = 12335770, upload-time = "2026-06-11T17:54:45.793Z" }, - { url = "https://files.pythonhosted.org/packages/88/82/8b5999aa13355e926f06d9f42a32dcca862f623bf0363785ff89d607dffd/ruff-0.15.17-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c0fe88a7676e7a05b73174d4d4a59cb2ac21ff8263583f87a81a6018475a978", size = 11575441, upload-time = "2026-06-11T17:54:32.661Z" }, - { url = "https://files.pythonhosted.org/packages/11/93/f10377bb04109ca0e8cbc483ff1982c54b6d418210041776f93e8cdc7fa9/ruff-0.15.17-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecfc3c7878fff94633ab0348524e093f9ce3243080416dd7d14f8ba400174719", size = 11557614, upload-time = "2026-06-11T17:54:34.698Z" }, - { url = "https://files.pythonhosted.org/packages/c7/a6/eeeae7f7d5493df41649ab3db92f086b2d0a30199e4efdf8e3dd7a033f24/ruff-0.15.17-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:b8461180b22420b1bdc289909410930761629fddf2a5aaf60fae1ab26cedc4c4", size = 11544450, upload-time = "2026-06-11T17:54:39.042Z" }, - { url = "https://files.pythonhosted.org/packages/32/88/5991ce565129a24dd4a00db1254b3b5db2e53018cbe4018ea5a89738e727/ruff-0.15.17-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6eccbe50a038b503e7140b441aa9c7fc8c1f36edf23ebef9f4165c2f28f568b7", size = 10892524, upload-time = "2026-06-11T17:55:09.432Z" }, - { url = "https://files.pythonhosted.org/packages/f5/1d/0fdd248313425f55223968af04b0a42125466a8d88d21c1d99c6af0a51e8/ruff-0.15.17-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:382fc0521025f5a8ad447d8bdd523545d0d7646adb718eb1c2dac5065ec27c0f", size = 10659573, upload-time = "2026-06-11T17:54:36.824Z" }, - { url = "https://files.pythonhosted.org/packages/9e/0e/072e8260deb9461062ce9311ced27a8e541229a6ffd483013dd37661e43e/ruff-0.15.17-py3-none-musllinux_1_2_i686.whl", hash = "sha256:456d41fcd1b2777ad63f09a6e7121d43f7b688bbc76a800c10f7f8fb1f912c3f", size = 11127818, upload-time = "2026-06-11T17:55:03.124Z" }, - { url = "https://files.pythonhosted.org/packages/ab/b4/55060a34163121498014696b5f656db5b8c6963768f227dbf0d76b311073/ruff-0.15.17-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b1a04bcc94ae6194e9db05d16ad31f298a7194bfbcb08258bbe589cee1d587b8", size = 11655901, upload-time = "2026-06-11T17:54:53.562Z" }, - { url = "https://files.pythonhosted.org/packages/49/71/9b29d6b87cef468d697f43c6a91e3fae4a80185779d7d5a4ef27d173439f/ruff-0.15.17-py3-none-win32.whl", hash = "sha256:596065960ab1ff593f744220c9fe6580eda00a95003cffa9f4048bb5b1bf0392", size = 10925574, upload-time = "2026-06-11T17:54:55.723Z" }, - { url = "https://files.pythonhosted.org/packages/3d/b2/8fc77f3723228836fa5d12497eb71c808f83782e10d058d2b15cfa14640b/ruff-0.15.17-py3-none-win_amd64.whl", hash = "sha256:6769e5fa1710b179b92e0bfa5a51735b35baea9013dadb06d5f44cbcf9547084", size = 12058788, upload-time = "2026-06-11T17:54:41.042Z" }, - { url = "https://files.pythonhosted.org/packages/2d/c7/c53e8dbff9c9dc4b7928773421ae294a5d28fcb8dcda1a089579d3a7e510/ruff-0.15.17-py3-none-win_arm64.whl", hash = "sha256:f3be1fbb34bcdfd146240d8fb92a709d4c2c8191348580a3c044ec60fa0b4456", size = 11355275, upload-time = "2026-06-11T17:54:43.635Z" }, + { url = "https://files.pythonhosted.org/packages/23/18/ee54b7ae1e121be7a28ea6da4b67564ebb0530e183a54415ab7e3bcd2c4e/ruff-0.15.22-py3-none-linux_armv6l.whl", hash = "sha256:44423e73493737f5e7c5b41d475483898ff37afcdae38bc3da5085e29af1c2d8", size = 10781258, upload-time = "2026-07-16T15:13:19.452Z" }, + { url = "https://files.pythonhosted.org/packages/2f/d2/2520cb14761ddbeaf57642a76942fc36adcbdbe53b4532241995f6fc485c/ruff-0.15.22-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b82c6482946e9eda7ff2e091d25b8bad3f718684e1916d41bd56873cee05b697", size = 10999477, upload-time = "2026-07-16T15:13:23.318Z" }, + { url = "https://files.pythonhosted.org/packages/c9/10/74e53572aa758dfaa678c2a2646b5c5515d884b7ca56be4d2ce03ca4b560/ruff-0.15.22-py3-none-macosx_11_0_arm64.whl", hash = "sha256:11c1c715af53a09f714e011106bffc419751ec8232fcb5da42173284ea3fec6f", size = 10466716, upload-time = "2026-07-16T15:13:26.162Z" }, + { url = "https://files.pythonhosted.org/packages/1e/cc/44eaaf0844e028182f2d0a8f2190d0f359159aed0a9e5ab861d892f1ae2a/ruff-0.15.22-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:742a29cf29bddb7c8327895d6a10e0e6c5b38a96dd407af9b5d0857f809c0576", size = 10892644, upload-time = "2026-07-16T15:13:29.229Z" }, + { url = "https://files.pythonhosted.org/packages/9f/21/8edf559014d2b0f82beea19cfb713993ad802ccda16868769979c6090a84/ruff-0.15.22-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72af58b951b0ae395935ae79763dc349bc0eb706319d28f7a33ad2cfb3cfc178", size = 10576719, upload-time = "2026-07-16T15:13:32.35Z" }, + { url = "https://files.pythonhosted.org/packages/bf/1e/3a13abd392a3b50b62e5938a831f9ab6e588358cacad5c18545b716d2182/ruff-0.15.22-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d425005c1835eb24e2ee4161cb90e8db263415f4a71c8c72c33abaa6c0c224", size = 11376494, upload-time = "2026-07-16T15:13:35.958Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3e/422d3d95bcf04dd78e1aeac22184d4f9a8fb2c01865d39d44618484a0317/ruff-0.15.22-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8b9b3f8779a4f08c969defc3c8c35abffaa757e601ed5ae66d6d1db6519969a", size = 12208370, upload-time = "2026-07-16T15:13:39.185Z" }, + { url = "https://files.pythonhosted.org/packages/1e/91/5d065a0e0a02bf4813f5119ad278462eed081d2b832eb7c021ade0ec9e65/ruff-0.15.22-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1e0dd1b2e4d3d585f897a0d137cbf4eaf6223bef4e8ce34d6bb12556c5f9249e", size = 11581098, upload-time = "2026-07-16T15:13:42.132Z" }, + { url = "https://files.pythonhosted.org/packages/f6/f9/a0d4871d12fae702eb1f41b686caf05f1f8b124dc6db6f784f53d74918fa/ruff-0.15.22-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365523eb91d9224e1bcb03b022fbf0facb8f9e23792a2c53d9d4b3924bdbdebb", size = 11399422, upload-time = "2026-07-16T15:13:45.2Z" }, + { url = "https://files.pythonhosted.org/packages/18/80/c843a5176cddbceb0b7e8dd41cf9993490796c1c469348d384f5a5c13c56/ruff-0.15.22-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:fabfd168afdf29fee5be98b831efa9683c94d7c5a3b58b9ce5a2e38444589a74", size = 11381683, upload-time = "2026-07-16T15:13:48.46Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/8485de0ae92239438a36cfc51350db9b9e85c9ebdfaea91b18e422706662/ruff-0.15.22-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:225dbf095a87f1d9f90f5fd7924d2613ee452a75a4308c63a8f50f761787aa7c", size = 10850295, upload-time = "2026-07-16T15:13:51.655Z" }, + { url = "https://files.pythonhosted.org/packages/fa/91/24977ec2ec72eaf15e4394ace2959fdff2dd1e14f03e005e838023407169/ruff-0.15.22-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1877d63b9d24ed278744f1523fd11b85540566d54641f97c566d7d9dc5ca5296", size = 10579640, upload-time = "2026-07-16T15:13:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/9c/47/9b51216951974df1f263ac19da550d34252e0ed7218c25f10c5ef9ed7517/ruff-0.15.22-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a1606c510bd7215680d32efab38965f7cdec3ef69f5170a3f4791404ffdd5262", size = 11105077, upload-time = "2026-07-16T15:13:57.915Z" }, + { url = "https://files.pythonhosted.org/packages/c2/47/20e9d4a3b8016778acea5fc32bb50d35d207500a17ddb529ffa6996feef8/ruff-0.15.22-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:630479b18625f5ffc373f77603a22a9f8ac0acd7ff0501178b5db28ec71e9c64", size = 11490980, upload-time = "2026-07-16T15:14:01.032Z" }, + { url = "https://files.pythonhosted.org/packages/4d/76/3f72d8fc38c1cb77b38c56a70da9d0c17700cc1cc50f9649c9d3c8f5ba71/ruff-0.15.22-py3-none-win32.whl", hash = "sha256:e5ba0e4a13fd14abbed2a77b517a3911290c6c6c59ef67784328d1668fab76cf", size = 10789165, upload-time = "2026-07-16T15:14:04.16Z" }, + { url = "https://files.pythonhosted.org/packages/cb/46/4965251734c2b6fcdca1b1b187d20bcac3af0ee5b083b89c910bb961ce3a/ruff-0.15.22-py3-none-win_amd64.whl", hash = "sha256:9be63ba1eb936acd2d1342fb8337c356353706fce233b2a15a09a97037e6acde", size = 11938297, upload-time = "2026-07-16T15:14:07.316Z" }, + { url = "https://files.pythonhosted.org/packages/57/c9/e69b1ff4c8b69093ef08b8919ab767af0569666865b39c30a8795d88d3c6/ruff-0.15.22-py3-none-win_arm64.whl", hash = "sha256:e1168075b72158510839f250027659cdd78476f40507dd517892304c41318661", size = 11298172, upload-time = "2026-07-16T15:14:10.51Z" }, ] [[package]] @@ -322,10 +322,10 @@ dependencies = [ [package.metadata] requires-dist = [ { name = "matplotlib", specifier = "~=3.11" }, - { name = "numpy", specifier = "~=2.4" }, - { name = "polars", specifier = "~=1.41" }, - { name = "pyarrow", specifier = "~=24.0" }, - { name = "ruff", specifier = "~=0.15.7" }, + { name = "numpy", specifier = "~=2.5" }, + { name = "polars", specifier = "~=1.42" }, + { name = "pyarrow", specifier = "~=25.0" }, + { name = "ruff", specifier = "~=0.15.22" }, ] [[package]] diff --git a/x.py b/x.py index 8dae871e..170df425 100644 --- a/x.py +++ b/x.py @@ -1,189 +1,20 @@ -self_path = __import__("pathlib").Path(__file__).parent.resolve() -python = __import__("shlex").quote(__import__("sys").executable) +SELF_PATH = __import__("pathlib").Path(__file__).parent.resolve() __effect = lambda effect: lambda func: [func, effect(func.__dict__)][0] cmd = lambda **kw: __effect(lambda d: d.setdefault("@cmd", {}).update(kw)) arg = lambda *a, **kw: __effect(lambda d: d.setdefault("@arg", []).append((a, kw))) -arrow_features = [ - # arrow-version:insert: "arrow-{version}", - "arrow-59", - "arrow-58", - "arrow-57", - "arrow-56", - "arrow-55", - "arrow-54", - "arrow-53", -] -default_serde_arrow_feature = arrow_features[0] -default_marrow_features = f"serde,{arrow_features[0]}" -default_workspace_features = ( - f"serde_arrow/{arrow_features[0]},marrow/serde,marrow/{arrow_features[0]}" -) - -CHECKS_PLACEHOLDER = "<<< checks >>>" - -# actions/checkout v7.0.0 -ACTION_CHECKOUT = "actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0" - -# astral-sh/setup-uv v8.2.0 -ACTION_SETUP_UV = "astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39" -# dtolnay/rust-toolchain branch 1.83.0 -ACTION_RUST_TOOLCHAIN = ( - "dtolnay/rust-toolchain@bd41891a8e7f4b8649f6d684415e1a6155fe4e22" -) - -workflow_test_template = { - "name": "Test", - "on": { - "workflow_dispatch": {}, - "pull_request": { - "branches": ["main", "develop-*"], - "types": [ - "opened", - "edited", - "reopened", - "ready_for_review", - "synchronize", - ], - }, - }, - "env": {"CARGO_TERM_COLOR": "always"}, - "jobs": { - "msrv": { - "runs-on": "ubuntu-latest", - "steps": [ - {"uses": ACTION_CHECKOUT}, - { - "name": "Install Rust 1.83", - "uses": ACTION_RUST_TOOLCHAIN, - "with": {"toolchain": "1.83.0"}, - }, - {"name": "rustc", "run": "rustc --version"}, - {"name": "cargo", "run": "cargo --version"}, - { - "name": "Update dependencies", - "run": "cargo +stable update --config 'resolver.incompatible-rust-versions=\"fallback\"'", - }, - { - "name": "Check MSRV with arrow-53", - "run": "cargo +1.83.0 check --package serde_arrow --features arrow-53", - }, - ], - }, - "build": { - "runs-on": "ubuntu-latest", - "steps": [ - {"uses": ACTION_CHECKOUT}, - { - "name": "Install uv", - "uses": ACTION_SETUP_UV, - "with": {"enable-cache": True}, - }, - {"name": "rustc", "run": "rustc --version"}, - {"name": "cargo", "run": "cargo --version"}, - CHECKS_PLACEHOLDER, - ], - }, - }, -} - - -def _generate_marrow_release_check_steps(): - yield {"name": "Check marrow", "run": "cargo check --all-targets --package marrow"} - - for feature in ("serde", *arrow_features): - yield { - "name": f"Check marrow {feature}", - "run": f"cargo check --all-targets --package marrow --features {feature}", - } - - yield { - "name": "Test marrow", - "run": f"cargo test --package marrow --features {default_marrow_features}", - } - yield {"name": "Package marrow", "run": "cargo package -p marrow --allow-dirty"} - - -def _generate_serde_arrow_release_check_steps(): - yield { - "name": "Check serde_arrow", - "run": "cargo check --all-targets --package serde_arrow", - } - - for feature in arrow_features: - yield { - "name": f"Check serde_arrow {feature}", - "run": f"cargo check --all-targets --package serde_arrow --features {feature}", - } - - yield { - "name": "Test serde_arrow", - "run": f"cargo test --package serde_arrow --features {default_serde_arrow_feature}", - } - yield { - "name": "Package serde_arrow", - "run": "cargo package -p serde_arrow --allow-dirty", - } - - -def _release_workflow_template(crate, check_steps): - return { - "name": f"Release {crate}", - "on": { - "push": {"tags": [f"{crate}/v*"]}, - }, - "env": {"CARGO_TERM_COLOR": "always"}, - "jobs": { - "publish": { - "runs-on": "ubuntu-latest", - "environment": "release", - "permissions": {"id-token": "write"}, - "steps": [ - {"uses": ACTION_CHECKOUT}, - {"name": "rustc", "run": "rustc --version"}, - {"name": "cargo", "run": "cargo --version"}, - *check_steps, - { - "name": "Auth with crates.io", - "uses": "rust-lang/crates-io-auth-action@v1", - "id": "auth", - }, - { - "name": "Publish to crates.io", - "run": f"cargo publish -p {crate}", - "env": { - "CARGO_REGISTRY_TOKEN": "${{ steps.auth.outputs.token }}", - }, - }, - ], - }, - }, - } - - -workflow_release_marrow_template = _release_workflow_template( - "marrow", - [*_generate_marrow_release_check_steps()], -) -workflow_release_serde_arrow_template = _release_workflow_template( - "serde_arrow", - [*_generate_serde_arrow_release_check_steps()], +backtrace = lambda name: arg( + name, + action="store_true", + default=False, + help="If given, print a backtrace on error", ) -benchmark_renames = { - "arrow": "arrow_json::ReaderBuilder", - "arrow_builder": "arrow builder", - "serde_arrow_arrow": "serde_arrow::to_arrow", - "serde_arrow_marrow": "serde_arrow::to_marrow", -} - -BENCHMARK_BASELINE = "arrow builder" - @cmd(help="Run all common development tasks before a commit") -@arg("--backtrace", action="store_true", default=False) +@backtrace("--backtrace") def precommit(backtrace=False): update_workflows() @@ -195,538 +26,69 @@ def precommit(backtrace=False): @cmd(help="Update the github workflows") def update_workflows(): - _update_workflow( - self_path / ".github" / "workflows" / "test.yml", - workflow_test_template, - ) - - _update_workflow( - self_path / ".github" / "workflows" / "release-marrow.yml", - workflow_release_marrow_template, - ) - - _update_workflow( - self_path / ".github" / "workflows" / "release-serde-arrow.yml", - workflow_release_serde_arrow_template, - ) - - -def _update_workflow(path, template): - import copy - import json - - workflow = copy.deepcopy(template) - - for job in workflow["jobs"].values(): - steps = [] - for step in job["steps"]: - if step == CHECKS_PLACEHOLDER: - steps.extend(_generate_workflow_check_steps()) - - else: - assert isinstance(step, dict) - steps.append(step) - - job["steps"] = steps - - print(f":: update {path}") - with open(path, "wt", encoding="utf8", newline="\n") as fobj: - json.dump(workflow, fobj, indent=2) - - -def _generate_workflow_check_steps(): - yield {"name": "Check", "run": "cargo check"} - for feature in ("serde", *arrow_features): - yield { - "name": f"Check marrow {feature}", - "run": f"cargo check --all-targets --package marrow --features {feature}", - } - - for feature in arrow_features: - yield { - "name": f"Check serde_arrow {feature}", - "run": f"cargo check --all-targets --package serde_arrow --features {feature}", - } - - yield { - "name": "Check support packages", - "run": "cargo check --all-features --package serde_arrow_bench --package serde_arrow_example --package serde_arrow_integration --package marrow_integration", - } - - yield { - "name": "Check format", - "run": "cargo fmt --check", - } - yield { - "name": "Build", - "run": ( - "cargo build " - "--package serde_arrow --package marrow " - f"--features {default_workspace_features}" - ), - } - yield { - "name": "Test", - "run": ( - "cargo test " - "--package serde_arrow --package marrow " - f"--features {default_workspace_features}" - ), - } - yield { - "name": "Integration test", - "run": "uv run python x.py test-integration", - } + _sh("uv run python scripts/update-workflows.py") @cmd(help="Format the code") def format(): - _sh(f"{python} -m ruff format {_q(__file__)}") - _sh("cargo fmt") - _sh( - f""" - rustfmt - {_q([*self_path.joinpath("marrow", "src", "impl_arrow").glob("impl*.rs")])} - {_q([*self_path.joinpath("marrow_integration", "src", "tests").glob("*.rs")])} - """ - ) + workflow(SELF_PATH / ".github/workflows/local.yml", "format") @cmd(help="Run the linters") -@arg("--all", action="store_true") -@arg("--fix", action="store_true") -def check(all=False, fix=False): - check_cargo_toml() - _sh("cargo check") - _sh( - f"cargo check --all-targets --package serde_arrow --features {default_serde_arrow_feature}" - ) - _sh( - f"cargo check --all-targets --package marrow --features {default_marrow_features}" - ) - _sh( - f"cargo clippy --all-targets --package serde_arrow --features {default_serde_arrow_feature} {'--fix' if fix else ''}" - ) - _sh( - f"cargo clippy --all-targets --package marrow --features {default_marrow_features} {'--fix' if fix else ''}" - ) - _sh( - "cargo check --all-targets --package serde_arrow_bench --package serde_arrow_example --package serde_arrow_integration --package marrow_integration --all-features" - ) - _sh( - "cargo clippy --all-targets --package serde_arrow_bench --package serde_arrow_example --package serde_arrow_integration --package marrow_integration --all-features" - ) - - if all: - for arrow_feature in arrow_features: - _sh(f"cargo check --package marrow --features {arrow_feature}") - - for arrow_feature in arrow_features: - _sh( - f"cargo check --package serde_arrow --all-targets --features {arrow_feature}" - ) +def check(): + workflow(SELF_PATH / ".github/workflows/local.yml", "check") @cmd(help="Run the serde_arrow_example") -@arg("--backtrace", action="store_true", default=False) +@backtrace("--backtrace") def serde_arrow_example(backtrace=False): - _sh( - "cargo run -p serde_arrow_example", + workflow( + SELF_PATH / ".github/workflows/local.yml", + "example", env=({"RUST_BACKTRACE": "1"} if backtrace else {}), ) - _sh( - f"{python} -c 'import polars as pl; print(pl.read_ipc(\"serde_arrow_example.ipc\"))'" - ) - -@cmd(help="Run both unit and integration tests") -@arg( - "--backtrace", - action="store_true", - default=False, - help="If given, print a backtrace on error", -) -def test(backtrace=False): - test_unit(backtrace=backtrace) - test_integration(backtrace) - - -@cmd(help="Run the tests") -@arg( - "--backtrace", - action="store_true", - default=False, - help="If given, print a backtrace on error", -) -@arg( - "--full", - action="store_true", - default=False, - help="If given, run all feature combinations", -) -@arg("test_name", nargs="?", help="Filter of test names") -def test_unit(test_name=None, backtrace=False, full=False): - if not full: - commands = [ - f"cargo test -q --package serde_arrow --features {default_serde_arrow_feature}", - f"cargo test -q --package marrow --features {default_marrow_features}", - ] - - else: - commands = [ - "cargo test -q --package marrow --features serde", - *( - f"cargo test -q --package marrow --features {feature}" - for feature in arrow_features - ), - *( - f"cargo test -q --package serde_arrow --features {feature}" - for feature in arrow_features - ), - ] - - for command in commands: - _sh( - f""" - {command} - {_q(test_name) if test_name else ""} - """, - env=({"RUST_BACKTRACE": "1"} if backtrace else {}), - ) - - -@cmd(help="Run integration tests") -@arg( - "--backtrace", - action="store_true", - default=False, - help="If given, print a backtrace on error", -) -def test_integration(backtrace=False): - env = {"SERDE_ARROW_PYTHON": __import__("sys").executable} - if backtrace: - env["RUST_BACKTRACE"] = "1" - _sh( - "cargo test -p serde_arrow_integration", - env=env, +@cmd(help="Run the full CI test flow locally") +@backtrace("--backtrace") +def ci_test(backtrace=False): + workflow( + SELF_PATH / ".github/workflows/test.yml", + "test", + env=({"RUST_BACKTRACE": "1"} if backtrace else {}), ) -@cmd() -def check_cargo_toml(): - import tomllib - - def load_config(crate): - with open(self_path / crate / "Cargo.toml", "rb") as fobj: - return tomllib.load(fobj) - - def check_feature_list(crate, label, actual, expected): - actual_features = sorted(actual) - expected_features = sorted(expected) - - if actual_features != expected_features: - raise ValueError( - f"Invalid {crate} {label}. " - f"Expected: {expected_features}, found: {actual_features}" - ) - - def check_dependency(crate, config, name, expected): - actual = config["dependencies"].get(name) - if actual is None: - raise ValueError(f"Missing {crate} dependency {name}") - - if actual != expected: - raise ValueError( - f"Invalid {crate} dependency {name}. " - f"Expected: {expected}, found: {actual}" - ) - - print(":: check Cargo.toml") - serde_arrow_config = load_config("serde_arrow") - marrow_config = load_config("marrow") - marrow_integration_config = load_config("marrow_integration") - - serde_arrow_marrow_dep = serde_arrow_config["dependencies"].get("marrow") - if serde_arrow_marrow_dep is None: - raise ValueError("Missing serde_arrow dependency marrow") - - serde_arrow_marrow_version = serde_arrow_marrow_dep.get("version") - marrow_version = marrow_config["package"]["version"] - if serde_arrow_marrow_version != marrow_version: - raise ValueError( - "Invalid serde_arrow marrow dependency version. " - f"Expected: {marrow_version}, found: {serde_arrow_marrow_version}" - ) - - check_feature_list( - "serde_arrow", - "docs.rs configuration", - serde_arrow_config["package"]["metadata"]["docs"]["rs"]["features"], - [default_serde_arrow_feature], - ) - check_feature_list( - "marrow", - "docs.rs configuration", - marrow_config["package"]["metadata"]["docs"]["rs"]["features"], - default_marrow_features.split(","), +@cmd(help="Run both unit and integration tests") +@backtrace("--backtrace") +def test(backtrace=False): + workflow( + SELF_PATH / ".github/workflows/local.yml", + "test", + env=({"RUST_BACKTRACE": "1"} if backtrace else {}), ) - for feature in arrow_features: - *_, version = feature.partition("-") - check_feature_list( - "serde_arrow", - f"feature definition for {feature}", - serde_arrow_config["features"][feature], - [ - f"dep:arrow-array-{version}", - f"dep:arrow-schema-{version}", - f"marrow/arrow-{version}", - ], - ) - - for component in ["arrow-array", "arrow-schema"]: - check_dependency( - "serde_arrow", - serde_arrow_config, - f"{component}-{version}", - { - "package": component, - "version": version, - "optional": True, - "default-features": False, - }, - ) - - marrow_components = ["arrow-array", "arrow-schema", "arrow-data", "arrow-buffer"] - for feature in arrow_features: - *_, version = feature.partition("-") - check_feature_list( - "marrow", - f"feature definition for {feature}", - marrow_config["features"][feature], - [f"dep:{component}-{version}" for component in marrow_components], - ) - - for component in marrow_components: - check_dependency( - "marrow", - marrow_config, - f"{component}-{version}", - { - "package": component, - "version": version, - "optional": True, - "default-features": False, - }, - ) - - check_feature_list( - "marrow_integration", - f"feature definition for {feature}", - marrow_integration_config["features"][feature], - [ - f"marrow/arrow-{version}", - f"dep:arrow-array-{version}", - f"dep:arrow-schema-{version}", - ], - ) - - for crate, config in [ - ("serde_arrow", serde_arrow_config), - ("marrow", marrow_config), - ]: - for name, dep in config["dependencies"].items(): - if dep.get("default-features", True): - raise ValueError( - f"Default features for {crate} dependency {name} not deactivated" - ) - @cmd(help="Run the benchmarks") @arg("--quick", action="store_true", default=False) def serde_arrow_bench(quick=False): - _sh( - "cargo bench -p serde_arrow_bench", + workflow( + SELF_PATH / ".github/workflows/bench.yml", + "bench", env=({"SERDE_ARROW_BENCH_QUICK": "1"} if quick else {}), ) - summarize_bench() - - -@cmd(help="Run the bench action for the current branch") -def bench_remote(): - branch = _sh("git branch --show-current", capture_output=True).stdout.strip() - if not branch: - raise RuntimeError("Could not determine branch") - - _sh(f"gh workflow run Bench --ref {branch}") -@cmd(help="Summarize the benchmarks") +@cmd(help="Summarize existing benchmarks") @arg("--update", action="store_true", default=False) def summarize_bench(update=False): - mean_times = load_times() - - print(format_benchmark(mean_times)) - - if update: - update_readme(mean_times, ignore_groups={"json_to_arrow"}) - plot_times(mean_times, ignore_groups={"json_to_arrow"}) - - -def load_times(): - import json - import statistics - - root = self_path / "target" / "criterion/" - - results = [] - for p in root.glob("*/*/new/sample.json"): - group = p.parent.parent.parent.name - name = p.parent.parent.name - with open(p) as fobj: - data = json.load(fobj) - - for iterations, time in zip(data["iters"], data["times"]): - results.append( - { - "name": benchmark_renames.get(name, name), - "group": group, - "iterations": iterations, - "time": time, - "seconds_per_iter": time / iterations / 1e9, - } - ) - - grouped_times = collect( - ((d["group"], d["name"]), d["seconds_per_iter"]) for d in results - ) - - mean_times = {} - for k, times in grouped_times.items(): - # remove the top 5% of times - qq = statistics.quantiles(times, n=20) - mean_times[k] = statistics.mean(time for time in times if time < qq[-1]) - - return mean_times - - -def update_readme(mean_times, ignore_groups=()): - print("Update readme") - with open(self_path / "Readme.md", "rt", encoding="utf8") as fobj: - lines = [line.rstrip() for line in fobj] - - active = False - with open(self_path / "Readme.md", "wt", encoding="utf8", newline="\n") as fobj: - for line in lines: - if not active: - print(line, file=fobj) - if line.strip() == "": - active = True - - else: - if line.strip() == "": - print( - format_benchmark(mean_times, ignore_groups=ignore_groups), - file=fobj, - ) - print(line, file=fobj) - active = False - - -def plot_times(mean_times, ignore_groups=()): - print("Plot times") - - import matplotlib.pyplot as plt - import polars as pl - - df = pl.from_dicts( - [ - {"group": group, "impl": impl, "time": time} - for (group, impl), time in mean_times.items() - if group not in ignore_groups - ] - ) - agg_df = ( - df.select( - [ - pl.col("impl"), - ( - pl.col("time") - / pl.col("time") - .filter(pl.col("impl") == BENCHMARK_BASELINE) - .mean() - .over("group") - ), - ] - ) - .group_by("impl") - .agg(pl.col("time").mean()) - .sort("time") - ) - - plt.figure(figsize=(7, 3.5), dpi=150) - b = plt.barh( - [d["impl"] for d in agg_df.to_dicts()], - [d["time"] for d in agg_df.to_dicts()], - zorder=10, - ) - plt.bar_label( - b, - ["{:.1f} x".format(d["time"]) for d in agg_df.to_dicts()], - bbox=dict(boxstyle="square,pad=0.0", fc="white", ec="none"), - padding=2.5, + _sh( + f""" + uv run python scripts/analyze-benchmark.py + --criterion-root target/criterion + {"--update Readme.md" if update else ""} + """ ) - plt.grid(axis="x", zorder=0) - plt.xlim(0, 1.15 * agg_df["time"].max()) - plt.subplots_adjust(left=0.32, right=0.975, top=0.95, bottom=0.15) - plt.xlabel(f"Mean runtime compared to {BENCHMARK_BASELINE}") - plt.savefig(self_path / "timings.png") - - -def format_benchmark(mean_times, ignore_groups=()): - def _parts(): - for group in sorted({g for g, _ in mean_times if g not in ignore_groups}): - times_in_group = {n: v for (g, n), v in mean_times.items() if g == group} - sorted_items = sorted(times_in_group.items(), key=lambda kv: kv[1]) - - rows = [["label", "time [ms]", *(k[:15] for k, _ in sorted_items)]] - for label, time in sorted_items: - rows.append( - [ - label, - f"{1000 * time:7.2f}", - *(f"{time / cmp:.2f}" for _, cmp in sorted_items), - ] - ) - - widths = [max(len(row[i]) for row in rows) for i in range(len(rows[0]))] - - yield f"### `{group}`" - yield "" - for idx, row in enumerate(rows): - padded_row = [ - (str.ljust if idx == 0 else str.rjust)(item, width) - for idx, (item, width) in enumerate(zip(row, widths)) - ] - - if idx == 0: - yield "| " + " | ".join(padded_row) + " |" - yield "|-" + "-|-".join("-" * w for w in widths) + "-|" - else: - yield "| " + " | ".join(padded_row) + " |" - - yield "" - - return "\n".join(_parts()) - - -def collect(kv_pairs): - res = {} - for k, v in kv_pairs: - res.setdefault(k, []).append(v) - - return res @cmd(help="Generate the documentation") @@ -735,78 +97,48 @@ def collect(kv_pairs): def doc(private=False, open=False): _sh( f""" - cargo doc - --package serde_arrow - --package marrow - --features {default_workspace_features} - {"--document-private-items" if private else ""} + uv run python scripts/doc.py + {"--private" if private else ""} {"--open" if open else ""} - """, + """ ) @cmd(help="Add a new arrow version") @arg("version") def add_arrow_version(version): - import re - - if _sh("git diff-files --quiet", check=False).returncode != 0: - print( - "WARNING: potentially destructive changes. " - "Please stage or commit the working tree first." - ) - raise SystemExit(1) - - for p in [ - self_path / "x.py", - *self_path.glob("*/**/*.rs"), - *self_path.glob("*/**/*.toml"), - ]: - content = p.read_text() - if "arrow-version" not in content: - continue - - print(f"process {p}") - new_content = [] - include_next = True - for line in content.splitlines(): - if ( - m := re.match(r"^.*(//|#) arrow-version:(replace|insert): (.*)$", line) - ) is not None: - new_content.append(line) - new_content.append( - m.group(3).format_map({"version": version, "\\n": "\n"}) - ) - include_next = m.group(2) != "replace" - - else: - if include_next: - new_content.append(line) - - include_next = True - - with open(p, "wt", newline="\n", encoding="utf-8") as fobj: - fobj.write("\n".join(new_content)) + import shlex + _sh(f"uv run python scripts/add-arrow-version.py {shlex.quote(version)}") format() update_workflows() +def workflow(path, job, *, env=()): + import json + + with open(path, "rt") as fobj: + workflow = json.load(fobj) + + if not job: + print(sorted(workflow["jobs"])) + return + + for step in workflow["jobs"][job]["steps"]: + if "run" in step: + _sh(step["run"], env=env) + + _sh = lambda c, env=(), **kw: __import__("subprocess").run( [args := __import__("shlex").split(c.replace("\n", " ")), print("::", *args)][0], **{ "check": True, - "cwd": self_path, + "cwd": SELF_PATH, "encoding": "utf-8", "env": {**__import__("os").environ, **dict(env)}, **kw, }, ) -_q = lambda arg: ( - __import__("shlex").quote(str(arg)) - if not isinstance(arg, (tuple, list)) - else " ".join(_q(item) for item in arg) -) if __name__ == "__main__": _sps = (_p := __import__("argparse").ArgumentParser()).add_subparsers()