diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b25ade7 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,94 @@ +name: CI + +on: + pull_request: + paths: + - "src/**" + - "tests/**" + - "Cargo.toml" + - "Cargo.lock" + - "pyproject.toml" + - "uv.lock" + - "rust-toolchain*" + - ".cargo/**" + - ".github/workflows/ci.yml" + push: + branches: [master] + paths: + - "src/**" + - "tests/**" + - "Cargo.toml" + - "Cargo.lock" + - "pyproject.toml" + - "uv.lock" + - "rust-toolchain*" + - ".cargo/**" + - ".github/workflows/ci.yml" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + +jobs: + quality: + runs-on: ubuntu-24.04 + timeout-minutes: 20 + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 + with: + python-version: "3.14" + - name: Install native build dependencies + run: sudo apt-get update && sudo apt-get install -y cmake clang libclang-dev + - name: Install Rust tooling + run: rustup toolchain install stable --profile minimal --component rustfmt --component clippy && rustup default stable + - uses: actions/cache@v5 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: quality-${{ runner.os }}-${{ hashFiles('Cargo.lock', 'Cargo.toml') }} + - run: cargo fmt --check + - run: cargo check --locked --all-targets + - run: cargo clippy --locked --all-targets -- -D warnings + + tests: + runs-on: ubuntu-24.04 + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + python: ["3.10", "3.15"] + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 + with: + python-version: ${{ matrix.python }} + allow-prereleases: ${{ matrix.python == '3.15' }} + - name: Install native build dependencies + run: sudo apt-get update && sudo apt-get install -y cmake clang libclang-dev + - name: Install Rust + run: rustup toolchain install stable --profile minimal && rustup default stable + - uses: actions/cache@v5 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: test-${{ runner.os }}-${{ matrix.python }}-${{ hashFiles('Cargo.lock', 'Cargo.toml') }} + - run: cargo test --locked + - name: Build and install Python extension + run: | + python -m pip install "maturin>=1.7,<2" + maturin build --locked --out dist + python -m pip install dist/*.whl + - name: Test public Python API + run: python -m unittest discover -s tests -v diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..1ec7364 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,26 @@ +# Changelog + +All notable changes are documented here using [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). +Versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +Unreleased changes are assigned a version and date when a release is prepared. +For the 0.x series, breaking Python API or supported-platform changes increment +MINOR; backward-compatible fixes increment PATCH. No release is implied by an +Unreleased entry. + +## [Unreleased] + +### Added +- CI for relevant pull requests, pushes to `master`, and manual runs, with path filters and cancellation of superseded runs. +- Rust checks, regression tests, pedantic Clippy, and Python API tests on Python 3.10 and 3.15. + +### Changed +- Update the Rust `rsloop` dependency to 0.1.56 and `wreq` to the stable 0.16.1 series. +- Update PyO3 to 0.29.3 for compatibility with `rsloop`. +- Require Python 3.10 or newer and Rust 1.98 or newer for the updated dependencies. +- Adapt proxy parsing, idle connection configuration, and body streaming to the current `wreq` API. + +### Fixed +- Reject unsupported proxy schemes before sending requests, preventing silent direct-request fallback with the current `wreq`; preserve bare `host:port` proxy inputs. +- Drain response bodies without accumulating them when `return_response=false`, preserving body-read failures and full body return when enabled (PR #1). + +[Unreleased]: https://github.com/RustedBytes/proxychecker/compare/a82dce87b87247cf33dd6ec676b485d4f157c7c1...HEAD diff --git a/Cargo.lock b/Cargo.lock index 54f21a8..6369a92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - [[package]] name = "aho-corasick" version = "1.1.4" @@ -17,42 +11,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - -[[package]] -name = "antidote" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" - -[[package]] -name = "arc-swap" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a07d1f37ff60921c83bdfc7407723bdefe89b44b98a9b772f225c8f9d67141a6" -dependencies = [ - "rustversion", -] - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - [[package]] name = "async-channel" version = "1.9.0" @@ -237,19 +195,13 @@ dependencies = [ "fs_extra", ] -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - [[package]] name = "bindgen" version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.11.0", + "bitflags", "cexpr", "clang-sys", "itertools", @@ -258,20 +210,14 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn", + "syn 2.0.117", ] [[package]] name = "bitflags" -version = "1.3.2" +version = "2.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" [[package]] name = "blocking" @@ -287,53 +233,28 @@ dependencies = [ ] [[package]] -name = "boring-sys2" -version = "4.15.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab6c876a958d17057d9d3a31075bb9609237413a1fe665432782c31ef596eb6b" -dependencies = [ - "autocfg", - "bindgen", - "cmake", - "fs_extra", - "fslock", -] - -[[package]] -name = "boring2" -version = "4.15.15" +name = "btls" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4470e96bd94533c2f88c08be95a8e6d2d37a3b497a773b0a46273a376978f00" +checksum = "2c5e60b8c8d282c86360cab651ded04ab0335a7b5390c8d34145cbeab8cacf5f" dependencies = [ - "bitflags 2.11.0", - "boring-sys2", - "brotli", - "flate2", + "bitflags", + "btls-sys", "foreign-types", "libc", "openssl-macros", - "zstd", -] - -[[package]] -name = "brotli" -version = "8.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", ] [[package]] -name = "brotli-decompressor" -version = "5.0.0" +name = "btls-sys" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +checksum = "9b1b8638a2e1c38a5ae4efa90ae57e643baec35a30d03fc5b399b893adc4954b" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", + "bindgen", + "cmake", + "fs_extra", + "fslock", ] [[package]] @@ -375,12 +296,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - [[package]] name = "clang-sys" version = "1.8.1" @@ -401,139 +316,6 @@ dependencies = [ "cc", ] -[[package]] -name = "compio" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b84ee96a86948d04388f3a0b8c36b9f0a6b40b3528ac0d65737e53632fb37fe" -dependencies = [ - "compio-buf", - "compio-driver", - "compio-io", - "compio-log", - "compio-net", - "compio-runtime", - "compio-signal", -] - -[[package]] -name = "compio-buf" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00d719dbd8c602ab0d25d219cbc6b517008858de7a8d6c51b4dc95aefff4dce" -dependencies = [ - "arrayvec", - "bytes", - "libc", -] - -[[package]] -name = "compio-driver" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d42d98dc890ee4db00c1e68a723391711aab6d67085880d716b72830f7c715" -dependencies = [ - "cfg-if", - "cfg_aliases", - "compio-buf", - "compio-log", - "crossbeam-queue", - "flume", - "futures-util", - "io-uring 0.7.11", - "io_uring_buf_ring", - "libc", - "once_cell", - "paste", - "pin-project-lite", - "polling", - "slab", - "smallvec", - "socket2 0.6.3", - "synchrony", - "thin-cell", - "windows-sys 0.61.2", -] - -[[package]] -name = "compio-io" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637522f28a64fd5f7dcceaa4ddef13fa8d8020025e8c993f7a069e237835580e" -dependencies = [ - "compio-buf", - "futures-util", - "paste", - "synchrony", -] - -[[package]] -name = "compio-log" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4e560213c1996b618da369b7c9109564b41af9033802ae534465c4ee4e132f" -dependencies = [ - "tracing", -] - -[[package]] -name = "compio-net" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "becd7d40522c885113752a3640cba9f9d347f205b646bb3f8ff3967173a228f2" -dependencies = [ - "cfg-if", - "compio-buf", - "compio-driver", - "compio-io", - "compio-runtime", - "either", - "libc", - "once_cell", - "socket2 0.6.3", - "widestring", - "windows-sys 0.61.2", -] - -[[package]] -name = "compio-runtime" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c1c71f011bdd9c8f30e97d877b606505ee6d241c7782cfaed172f66acbd9cd" -dependencies = [ - "async-task", - "cfg-if", - "compio-buf", - "compio-driver", - "compio-log", - "core_affinity", - "crossbeam-queue", - "futures-util", - "libc", - "once_cell", - "pin-project-lite", - "scoped-tls", - "slab", - "socket2 0.6.3", - "windows-sys 0.61.2", -] - -[[package]] -name = "compio-signal" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f7b5f1f32c0c44441023aa012e252de890a166f773bee49226439ac9a13f16f" -dependencies = [ - "compio-buf", - "compio-driver", - "compio-runtime", - "libc", - "once_cell", - "os_pipe", - "slab", - "windows-sys 0.61.2", -] - [[package]] name = "concurrent-queue" version = "2.5.0" @@ -543,16 +325,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation" version = "0.10.1" @@ -569,26 +341,6 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "core_affinity" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a034b3a7b624016c6e13f5df875747cc25f884156aad2abd12b6c46797971342" -dependencies = [ - "libc", - "num_cpus", - "winapi", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -621,7 +373,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -636,15 +388,6 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -700,31 +443,18 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" -[[package]] -name = "flate2" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "flume" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" -dependencies = [ - "spin", -] - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.5.0" @@ -743,7 +473,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -794,9 +524,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -804,9 +534,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" @@ -821,9 +551,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-lite" @@ -840,32 +570,32 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-channel", "futures-core", @@ -878,21 +608,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generator" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9" -dependencies = [ - "cc", - "cfg-if", - "libc", - "log", - "rustversion", - "windows-link 0.2.1", - "windows-result 0.4.1", -] - [[package]] name = "getrandom" version = "0.2.17" @@ -940,6 +655,15 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "foldhash", +] + [[package]] name = "heck" version = "0.5.0" @@ -954,9 +678,9 @@ checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "http" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", "itoa", @@ -974,9 +698,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", "futures-core", @@ -987,9 +711,9 @@ dependencies = [ [[package]] name = "http2" -version = "0.4.21" +version = "0.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6e23815f8ec982e1452e1d0fda921ec20a9187fb610ad003c90cc5abd65b2c4" +checksum = "92d3114be2f413b2e491e686b93a28cda30c355cffc8d091a57f8be4b1342896" dependencies = [ "atomic-waker", "bytes", @@ -999,6 +723,7 @@ dependencies = [ "http", "indexmap", "slab", + "smallvec", "tokio", "tokio-util", ] @@ -1009,26 +734,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" -[[package]] -name = "hyper2" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1a1bb25e0cbdbe7b21f8ef6c3c4785f147d79e7ded438b5ee2b70e380183294" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http", - "http-body", - "http2", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - [[package]] name = "icu_collections" version = "2.1.1" @@ -1138,17 +843,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown", -] - -[[package]] -name = "io-uring" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595a0399f411a508feb2ec1e970a4a30c249351e30208960d58298de8660b0e5" -dependencies = [ - "bitflags 1.3.2", - "libc", + "hashbrown 0.16.1", ] [[package]] @@ -1157,22 +852,11 @@ version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdd7bddefd0a8833b88a4b68f90dae22c7450d11b354198baee3874fd811b344" dependencies = [ - "bitflags 2.11.0", + "bitflags", "cfg-if", "libc", ] -[[package]] -name = "io_uring_buf_ring" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1838759bb8c2f24cf05a35429d83145c4aa6af43f8ad38477295e12a7320a80e" -dependencies = [ - "bytes", - "io-uring 0.7.11", - "rustix", -] - [[package]] name = "ipnet" version = "2.12.0" @@ -1225,17 +909,11 @@ dependencies = [ "log", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" -version = "0.2.183" +version = "0.2.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78" [[package]] name = "libloading" @@ -1244,22 +922,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-link 0.2.1", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "linked_hash_set" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "984fb35d06508d1e69fc91050cceba9c0b748f983e6739fa2c7a9237154c52c8" -dependencies = [ - "linked-hash-map", + "windows-link", ] [[package]] @@ -1292,33 +955,13 @@ dependencies = [ "value-bag", ] -[[package]] -name = "loom" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" -dependencies = [ - "cfg-if", - "generator", - "pin-utils", - "scoped-tls", - "tracing", - "tracing-subscriber", -] - [[package]] name = "lru" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" - -[[package]] -name = "matchers" -version = "0.2.0" +version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +checksum = "ef9ac18847474e638e3702b76c65d4eb93428471a74778ef0f1be711717f89b5" dependencies = [ - "regex-automata", + "hashbrown 0.17.1", ] [[package]] @@ -1327,28 +970,12 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "minimal-lexical" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - [[package]] name = "mio" version = "1.2.0" @@ -1368,26 +995,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", - "minimal-lexical", -] - -[[package]] -name = "nu-ansi-term" -version = "0.50.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "num_cpus" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" -dependencies = [ - "hermit-abi", - "libc", + "minimal-lexical", ] [[package]] @@ -1410,7 +1018,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1419,16 +1027,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" -[[package]] -name = "os_pipe" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - [[package]] name = "parking" version = "2.2.1" @@ -1455,15 +1053,9 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-link 0.2.1", + "windows-link", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "percent-encoding" version = "2.3.2" @@ -1493,12 +1085,6 @@ dependencies = [ "futures-io", ] -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - [[package]] name = "polling" version = "3.11.0" @@ -1537,30 +1123,11 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "profiling" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" -dependencies = [ - "profiling-procmacros", -] - -[[package]] -name = "profiling-procmacros" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "pyo3" -version = "0.28.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf85e27e86080aafd5a22eae58a162e133a589551542b3e5cee4beb27e54f8e1" +checksum = "700d18fa267b73b9b521fd7e13580e2f446916f176cacee1ab63fcc8191f1655" dependencies = [ "libc", "once_cell", @@ -1572,9 +1139,9 @@ dependencies = [ [[package]] name = "pyo3-async-runtimes" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e7364a95bf00e8377bbf9b0f09d7ff9715a29d8fcf93b47d1a967363b973178" +checksum = "b3ef68daa7316a3fac65e5e18b2203f010346de1c1c53456811a2624673ab046" dependencies = [ "async-std", "futures-channel", @@ -1586,18 +1153,18 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.28.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf94ee265674bf76c09fa430b0e99c26e319c945d96ca0d5a8215f31bf81cf7" +checksum = "7b3fc0c4d08f6bb10e71fe39dfb9e2f59c6eb6854e22ec8092f50c69a4499adb" dependencies = [ "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.28.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "491aa5fc66d8059dd44a75f4580a2962c1862a1c2945359db36f6c2818b748dc" +checksum = "dfc0b8e19df29aad7086cf977bb0c2a2f143e30567eb113e9cf72b62ca698330" dependencies = [ "libc", "pyo3-build-config", @@ -1605,27 +1172,26 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.28.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d671734e9d7a43449f8480f8b38115df67bef8d21f76837fa75ee7aaa5e52e" +checksum = "6100e8a4b5eba53afaa5ed078364851a0b2499c553a44c31026b929049b49dc6" dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn", + "syn 2.0.117", ] [[package]] name = "pyo3-macros-backend" -version = "0.28.2" +version = "0.29.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22faaa1ce6c430a1f71658760497291065e6450d7b5dc2bcf254d49f66ee700a" +checksum = "6143877a16e82b5a727b7127ff4cd86858a24a28d745d72f43e6f227c7b1bdb3" dependencies = [ "heck", "proc-macro2", - "pyo3-build-config", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1649,7 +1215,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.11.0", + "bitflags", ] [[package]] @@ -1697,16 +1263,22 @@ dependencies = [ [[package]] name = "rsloop" -version = "0.1.14" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdadb2c0c2fe489ecff080f12e513774af7900e304fa94cc3fff9fd2c0d26846" +checksum = "457737a5180a61a187fd402b0117cfa431afebe6b3cfc2ceb5b455ba94846b10" dependencies = [ + "async-io", "async-std", - "compio", "crossbeam-channel", + "crossbeam-queue", "futures", + "futures-util", + "io-uring", "libc", - "profiling", + "memchr", + "mio", + "oneshot", + "pin-project-lite", "pyo3", "pyo3-async-runtimes", "pyo3-build-config", @@ -1714,9 +1286,9 @@ dependencies = [ "rustls-native-certs", "rustls-pemfile", "signal-hook", - "socket2 0.6.3", + "slab", + "socket2", "tokio", - "vibeio", "windows-sys 0.61.2", ] @@ -1729,6 +1301,7 @@ dependencies = [ "pyo3", "rsloop", "tokio", + "url", "wreq", ] @@ -1744,7 +1317,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -1814,12 +1387,6 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" -[[package]] -name = "ryu" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" - [[package]] name = "schannel" version = "0.1.29" @@ -1829,12 +1396,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - [[package]] name = "scopeguard" version = "1.2.0" @@ -1847,8 +1408,8 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.0", - "core-foundation 0.10.1", + "bitflags", + "core-foundation", "core-foundation-sys", "libc", "security-framework-sys", @@ -1871,7 +1432,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", - "serde_derive", ] [[package]] @@ -1891,28 +1451,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", + "syn 2.0.117", ] [[package]] @@ -1941,12 +1480,6 @@ dependencies = [ "libc", ] -[[package]] -name = "simd-adler32" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" - [[package]] name = "slab" version = "0.4.12" @@ -1959,16 +1492,6 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "socket2" version = "0.6.3" @@ -1979,15 +1502,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -2012,22 +1526,23 @@ dependencies = [ ] [[package]] -name = "sync_wrapper" -version = "1.0.2" +name = "syn" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee" dependencies = [ - "futures-core", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] -name = "synchrony" -version = "0.1.7" +name = "sync_wrapper" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c174d82fd56da8214ec095cfe4568e59e5ccb49d060e70c2f98e3ba352b23e45" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ - "futures-util", - "loom", + "futures-core", ] [[package]] @@ -2038,28 +1553,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.11.0", - "core-foundation 0.9.4", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", + "syn 2.0.117", ] [[package]] @@ -2068,12 +1562,6 @@ version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" -[[package]] -name = "thin-cell" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4164c6c316ba9733b0ab021e7f9852c788a4b991b49c25820f1be48e1d41345b" - [[package]] name = "thiserror" version = "1.0.69" @@ -2091,16 +1579,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", + "syn 2.0.117", ] [[package]] @@ -2115,9 +1594,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.50.0" +version = "1.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +checksum = "e95f91fcc7a621e8b030f6aa23c71fe9838ae2fb4d8118b75602a328f5144044" dependencies = [ "bytes", "libc", @@ -2125,31 +1604,30 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.3", + "socket2", "tokio-macros", "windows-sys 0.61.2", ] [[package]] -name = "tokio-boring2" -version = "4.15.15" +name = "tokio-btls" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3866209c48e3d69e709a9d6105d7e2aa34e4374bc5dcaec32e0f8e53a28db14a" +checksum = "2e1fd638ec35427faf3b8f412e0fdd6fae76591d79dba40f38fa667d22bc44dd" dependencies = [ - "boring-sys2", - "boring2", + "btls", "tokio", ] [[package]] name = "tokio-macros" -version = "2.6.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.6", ] [[package]] @@ -2204,81 +1682,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" -[[package]] -name = "tracing" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" -dependencies = [ - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex-automata", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - [[package]] name = "try-lock" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "typed-builder" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef81aec2ca29576f9f6ae8755108640d0a86dd3161b2e8bca6cfa554e98f77d" -dependencies = [ - "typed-builder-macro", -] - -[[package]] -name = "typed-builder-macro" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecb9ecf7799210407c14a8cfdfe0173365780968dc57973ed082211958e0b18" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "unicode-ident" version = "1.0.24" @@ -2309,35 +1718,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - [[package]] name = "value-bag" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0" -[[package]] -name = "vibeio" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d5b44e953b7f31cd083e16b3350234b6723c4ca4a70a522821ba8e7fffea16b" -dependencies = [ - "crossbeam-queue", - "futures-util", - "io-uring 0.6.4", - "libc", - "mio", - "oneshot", - "slab", - "tokio", - "windows-sys 0.61.2", -] - [[package]] name = "want" version = "0.3.1" @@ -2404,7 +1790,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wasm-bindgen-shared", ] @@ -2419,28 +1805,13 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "0.26.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" -dependencies = [ - "webpki-root-certs 1.0.6", -] - -[[package]] -name = "webpki-root-certs" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" dependencies = [ "rustls-pki-types", ] -[[package]] -name = "widestring" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" - [[package]] name = "winapi" version = "0.3.9" @@ -2463,56 +1834,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" -[[package]] -name = "windows-registry" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" -dependencies = [ - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings", -] - -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link 0.1.3", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -2528,7 +1855,7 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -2603,42 +1930,66 @@ checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" [[package]] name = "wreq" -version = "5.3.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "137ed11c4c418fb3dc41db7323ebc49aa9b6fe6a24ce152e6b2de9d6fadd9c8f" +checksum = "16454175c8cb23d4a7285bab53b72460686195f5aef655d1abad70ab97ef46d4" dependencies = [ - "antidote", - "arc-swap", - "base64", - "boring2", + "btls", + "btls-sys", "bytes", - "encoding_rs", "futures-util", "http", "http-body", "http-body-util", - "hyper2", + "http2", + "httparse", "ipnet", - "linked_hash_set", - "log", + "libc", "lru", - "mime", "percent-encoding", "pin-project-lite", - "serde", - "serde_urlencoded", - "socket2 0.5.10", + "socket2", "sync_wrapper", - "system-configuration", "tokio", - "tokio-boring2", + "tokio-btls", "tokio-socks", + "tokio-util", "tower", - "tower-service", - "typed-builder", "url", - "webpki-root-certs 0.26.11", - "windows-registry", + "webpki-root-certs", + "wreq-proto", + "wreq-rt", +] + +[[package]] +name = "wreq-proto" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4d829f0427a5064829976fe790641ca21abb1d83d844812baf022dc0bdf2db" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "http2", + "httparse", + "pin-project-lite", + "smallvec", + "tokio", + "tokio-util", + "want", +] + +[[package]] +name = "wreq-rt" +version = "0.2.2-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99e9bce67a3fa3dd3f1503f066d86661c9caf399a763d3bd184da7afaf886c8b" +dependencies = [ + "pin-project-lite", + "tokio", + "wreq-proto", ] [[package]] @@ -2666,7 +2017,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", "synstructure", ] @@ -2687,7 +2038,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", "synstructure", ] @@ -2727,33 +2078,5 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "zstd" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" -dependencies = [ - "cc", - "pkg-config", + "syn 2.0.117", ] diff --git a/Cargo.toml b/Cargo.toml index ae880d1..ccfce01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ name = "rsloop-rust-proxychecker" version = "0.1.0" edition = "2021" +rust-version = "1.98" publish = false [lib] @@ -11,10 +12,12 @@ crate-type = ["cdylib"] [dependencies] async-std = "1" futures = "0.3" -pyo3 = { version = "0.28", features = ["extension-module"] } -rsloop = { version = "0.1.14" } +pyo3 = { version = "0.29.3", features = ["extension-module"] } +rsloop = { version = "0.1.56" } tokio = { version = "1", features = ["full"] } -wreq = { version = "5.3.0", features = ["socks"] } +wreq = { version = "0.16.1", features = ["socks", "stream"] } + +url = "2" [profile.release] opt-level = 3 @@ -22,3 +25,6 @@ lto = "fat" codegen-units = 1 incremental = false # strip = true + +[lints.clippy] +pedantic = { level = "warn", priority = -1 } diff --git a/README.md b/README.md index 6a992e3..576dc41 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,25 @@ The example passes the proxy string directly to `wreq`, so support follows the proxy schemes that `wreq` accepts. In practice that includes normal HTTP/HTTPS proxies and, with the enabled `socks` feature, SOCKS proxies as well. +## Development + +Requires Python 3.10+ and Rust 1.98+. Native builds also need CMake, a C/C++ +compiler, and libclang (on Ubuntu: `sudo apt-get install cmake clang libclang-dev`). + +```bash +cargo fmt --check +cargo check --locked --all-targets +cargo clippy --locked --all-targets -- -D warnings +cargo test --locked +uv run python -m unittest discover -s tests -v +``` + +Pedantic Clippy is enabled in `Cargo.toml`. CI checks relevant pull requests and +pushes to `master`, supports manual runs, and skips documentation-only changes. +The Python API is tested on Python 3.10 and 3.15. Release notes are maintained in +[CHANGELOG.md](CHANGELOG.md); dependency compatibility changes remain under +`Unreleased` until the next version is prepared. + ## Run From the repository root: diff --git a/pyproject.toml b/pyproject.toml index 7e133e0..2a11233 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,9 +5,9 @@ build-backend = "maturin" [project] name = "rsloop-rust-proxychecker" version = "0.1.0" -requires-python = ">=3.8" +requires-python = ">=3.10" dependencies = [ - "rsloop>=0.1.14", + "rsloop>=0.1.56", ] [tool.maturin] diff --git a/src/lib.rs b/src/lib.rs index 16363f8..872b98e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,7 +57,7 @@ fn check_proxies( } let check_url = check_url.unwrap_or_else(|| DEFAULT_CHECK_URL.to_string()); - wreq::Url::parse(&check_url) + url::Url::parse(&check_url) .map_err(|err| PyValueError::new_err(format!("invalid check_url: {err}")))?; let config = CheckerConfig { @@ -136,7 +136,7 @@ async fn run_proxy_checks_async( .boxed(); while let Some(outcome) = outcomes.next().await { - emit_stream_result(&loop_obj, &queue, outcome) + emit_stream_result(loop_obj, queue, outcome) .map_err(|err| format!("failed to emit proxy result: {err}"))?; } @@ -147,7 +147,7 @@ fn build_client(config: &CheckerConfig) -> Result { let mut builder = wreq::Client::builder() .user_agent(config.user_agent.clone()) .no_proxy() - .no_keepalive() + .pool_max_idle_per_host(0) .timeout(config.timeout) .read_timeout(config.timeout) .connect_timeout(config.timeout) @@ -163,22 +163,53 @@ fn build_client(config: &CheckerConfig) -> Result { .map_err(|err| format!("failed to build wreq client: {err}")) } +fn parse_proxy(proxy: &str) -> Result { + // Preserve support for host:port inputs while rejecting schemes that wreq's + // matcher silently ignores (which would otherwise send the request directly). + let uri = if proxy.contains("://") { + url::Url::parse(proxy) + } else { + url::Url::parse(&format!("http://{proxy}")) + } + .map_err(|err| format!("invalid proxy URL: {err}"))?; + if !matches!( + uri.scheme(), + "http" | "https" | "socks4" | "socks4a" | "socks5" | "socks5h" + ) { + return Err(format!("unsupported proxy scheme: {}", uri.scheme())); + } + wreq::Proxy::all(uri.as_str()).map_err(|err| err.to_string()) +} + async fn check_one_proxy( client: wreq::Client, config: CheckerConfig, proxy: String, ) -> ProxyOutcome { let started = Instant::now(); + let request_proxy = match parse_proxy(&proxy) { + Ok(request_proxy) => request_proxy, + Err(err) => { + return ProxyOutcome { + proxy, + elapsed_ms: started.elapsed().as_millis(), + status: None, + ok: false, + error: Some(err), + response_text: None, + }; + } + }; let request = client .post(config.check_url.clone()) - .proxy(proxy.clone()) + .proxy(request_proxy) .header(header::CONTENT_TYPE, "text/plain; charset=utf-8") .timeout(config.timeout) .read_timeout(config.timeout) .body(REQUEST_BODY); match request.send().await { - Ok(mut response) => { + Ok(response) => { let status = response.status(); let status_code = status.as_u16(); let body = if config.return_response { @@ -188,7 +219,10 @@ async fn check_one_proxy( .map(|bytes| Some(String::from_utf8_lossy(&bytes).into_owned())) } else { async { - while response.chunk().await?.is_some() {} + let mut chunks = response.bytes_stream().boxed(); + while let Some(chunk) = chunks.next().await { + drop(chunk?); + } Ok(None) } .await @@ -237,7 +271,7 @@ fn build_outcome_dict(py: Python<'_>, outcome: ProxyOutcome) -> PyResult, py: Python<'_>) -> PyResult> { let queue = slf.borrow(py).queue.clone_ref(py); let locals = rsloop::rust_async::get_current_locals(py)?; @@ -357,6 +393,32 @@ mod tests { use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpListener; + #[test] + fn proxy_parser_rejects_unsupported_schemes() { + for proxy in [ + "invalid://proxy", + "ftp://127.0.0.1:8080", + "file:///tmp/proxy", + ] { + assert!(parse_proxy(proxy).is_err()); + } + } + + #[test] + fn proxy_parser_preserves_supported_schemes_and_bare_addresses() { + for proxy in [ + "http://127.0.0.1:8080", + "https://127.0.0.1:8080", + "socks4://127.0.0.1:1080", + "socks4a://127.0.0.1:1080", + "socks5://user:pass@127.0.0.1:1080", + "socks5h://127.0.0.1:1080", + "127.0.0.1:8080", + ] { + assert!(parse_proxy(proxy).is_ok(), "failed to parse {proxy}"); + } + } + async fn check_response(status: u16, return_response: bool, truncated: bool) -> ProxyOutcome { let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let proxy = format!("http://{}", listener.local_addr().unwrap()); diff --git a/tests/test_api.py b/tests/test_api.py new file mode 100644 index 0000000..4b398ed --- /dev/null +++ b/tests/test_api.py @@ -0,0 +1,67 @@ +import asyncio +import threading +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +import unittest + +import rsloop_rust_proxychecker as checker + + +class ApiTests(unittest.TestCase): + def test_empty_input_ends_stream(self): + async def run(): + stream = await checker.check_proxies([], user_agent="test") + self.assertEqual([item async for item in stream], []) + + asyncio.run(run()) + + def test_invalid_proxy_returns_failed_outcome(self): + requests = [] + + class Handler(BaseHTTPRequestHandler): + def do_POST(self): + requests.append(self.path) + self.rfile.read(int(self.headers.get("Content-Length", "0"))) + self.send_response(200) + self.send_header("Content-Length", "0") + self.end_headers() + + def log_message(self, *args): + pass + + with ThreadingHTTPServer(("127.0.0.1", 0), Handler) as server: + thread = threading.Thread(target=server.serve_forever) + thread.start() + target = f"http://127.0.0.1:{server.server_port}/check" + + async def run(): + # The target succeeds if reached directly, making proxy bypass + # observable without depending on an external HTTP service. + for proxy in ["invalid://proxy", "ftp://127.0.0.1:8080"]: + with self.subTest(proxy=proxy): + stream = await checker.check_proxies( + [proxy], user_agent="test", check_url=target + ) + results = [item async for item in stream] + self.assertEqual(len(results), 1) + self.assertEqual(results[0]["proxy"], proxy) + self.assertFalse(results[0]["ok"]) + self.assertIn("unsupported proxy scheme", results[0]["error"]) + self.assertNotIn("status", results[0]) + self.assertNotIn("response_text", results[0]) + + try: + asyncio.run(run()) + finally: + server.shutdown() + thread.join() + self.assertEqual(requests, [], "invalid proxy must not bypass to the target") + + def test_invalid_arguments(self): + for kwargs in [ + {"user_agent": ""}, + {"user_agent": "test", "timeout_ms": 0}, + {"user_agent": "test", "concurrency": 0}, + {"user_agent": "test", "check_url": "not a URL"}, + ]: + with self.subTest(kwargs=kwargs), self.assertRaises(ValueError): + checker.check_proxies([], **kwargs) diff --git a/uv.lock b/uv.lock index 2277efb..c2b0eca 100644 --- a/uv.lock +++ b/uv.lock @@ -1,58 +1,58 @@ version = 1 revision = 3 -requires-python = ">=3.8" +requires-python = ">=3.10" [[package]] name = "rsloop" -version = "0.1.14" +version = "0.1.59" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/65/e8/fa01b8eaaca37bf5b34bf1793f84a6fd907d7c2d43b5c45dec9b0a85a3c3/rsloop-0.1.14.tar.gz", hash = "sha256:3f03e3225c5f2fba67227664dc265c53c4529e2aa9db96a8955c7b30ac5baf49", size = 325737, upload-time = "2026-03-30T12:02:59.732Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4a/4f/64c0d6d69d9e9dda5a89feb553468734a87a9f161ed52f37eea91709b035/rsloop-0.1.59.tar.gz", hash = "sha256:63e20c8930c44a422efcbb1c5a21931e7660132f8f3a7b6fde516afd934c607e", size = 1040803, upload-time = "2026-10-07T17:30:37.971Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/61/4b30244061c2cc70ccfd2a78781664ae7467d512080e646d07490988887d/rsloop-0.1.14-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a99364a23f05f9cdbcf40c8d0746d471e4bb0d53bc3f14ca6b53ccdfc1492e16", size = 2535377, upload-time = "2026-03-30T12:01:48.545Z" }, - { url = "https://files.pythonhosted.org/packages/e7/a5/b38e208ecf6a400f05315d9d306de79a1bc2529cea6b17f809db525d0f7b/rsloop-0.1.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:434dea91e14bcb4d99438c2afcabfe91262428d6625e17b23305851a987ddfa4", size = 2384485, upload-time = "2026-03-30T12:01:50.308Z" }, - { url = "https://files.pythonhosted.org/packages/39/a4/f4e51388bf494e0957336a53028257f074701f1bdcd1369f9fdc3e4ea3c7/rsloop-0.1.14-cp310-cp310-manylinux_2_39_aarch64.whl", hash = "sha256:64c402b5e12ee33500523c0f572d109eb1734d78eacfa2ee1c3d6b9fe4349fe2", size = 2474747, upload-time = "2026-03-30T12:01:51.694Z" }, - { url = "https://files.pythonhosted.org/packages/39/af/e2581a5320a4b77fb0a8c57ff745ea97788a88314db6a47f4f174dc2e3eb/rsloop-0.1.14-cp310-cp310-manylinux_2_39_x86_64.whl", hash = "sha256:273c6132b91a493ffcc8286e6437986578f1a567acb23c10e048b52653a80365", size = 2609173, upload-time = "2026-03-30T12:01:53.304Z" }, - { url = "https://files.pythonhosted.org/packages/7c/78/f5a4e74635d7aca451c5e51665a2efc115dee917c78b61e6ea87d34fdc45/rsloop-0.1.14-cp310-cp310-win_amd64.whl", hash = "sha256:be264d859c3af7b3238297d55fc0c9b8cb951a235c054d2b5baa19782024196f", size = 2208848, upload-time = "2026-03-30T12:01:54.75Z" }, - { url = "https://files.pythonhosted.org/packages/2c/93/aa5eff7fc5fb9734f3fbb315a9e78091c8cbd3b49196a147c6db83f200fe/rsloop-0.1.14-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:dcd117c59ff0ae8bc0ac302fc7e89d60fd2d7ba590676fd0d35c62de547887ab", size = 2535329, upload-time = "2026-03-30T12:01:56.104Z" }, - { url = "https://files.pythonhosted.org/packages/15/02/cb3f933bd3a0cb6c0b039c850843113895e869cbfea5c658553871191348/rsloop-0.1.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a6a9422345d5071ff5c2d68e9e44b706c5cf1a238df61d949c5b703aa884534", size = 2384371, upload-time = "2026-03-30T12:01:57.686Z" }, - { url = "https://files.pythonhosted.org/packages/a7/bd/defb8e19f04abbd045cf998d4f85daa1caeb3701d5ad62f479b0ed3cef90/rsloop-0.1.14-cp311-cp311-manylinux_2_39_aarch64.whl", hash = "sha256:e740e6ef470bc8ab9aa85654eafc2e6b4cf237a8904e74d412c77124a70113dc", size = 2475602, upload-time = "2026-03-30T12:01:59.099Z" }, - { url = "https://files.pythonhosted.org/packages/23/35/95cbde90886bb8df9505a1cae99eae7df633b5f499581e3cc22bd2640056/rsloop-0.1.14-cp311-cp311-manylinux_2_39_x86_64.whl", hash = "sha256:18493b86e674330420f290631125b37f56a365a357b52c756a545da8dbed9679", size = 2610116, upload-time = "2026-03-30T12:02:00.435Z" }, - { url = "https://files.pythonhosted.org/packages/5b/1e/f531663f67be718dbcc79a68d82168e6992d65f8f723ebf226b02d58ce3b/rsloop-0.1.14-cp311-cp311-win_amd64.whl", hash = "sha256:d82dda06c50cd53c64c1b8b106cba352965ae9927211c4d187e86bfc67e86d3a", size = 2208821, upload-time = "2026-03-30T12:02:02.471Z" }, - { url = "https://files.pythonhosted.org/packages/cd/17/cd2792740a92d7cdd046ffff2700dbb66e87e792f48edd1885a11019c193/rsloop-0.1.14-cp311-cp311-win_arm64.whl", hash = "sha256:8ed141b0726ed7a7fbe7469ad4b6e52961a109f717845a604869c1bf6bfc8a96", size = 2266106, upload-time = "2026-03-30T12:02:04.083Z" }, - { url = "https://files.pythonhosted.org/packages/52/d2/6f7b577caba2e2363e2f497ba0544fac1ecf2cd9a43fefb7e536e1371126/rsloop-0.1.14-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a81ef2fcbbb11a0f92d21a0788d7be4ad454cd3a64f22071c57c0c77a0c4dc8c", size = 2538584, upload-time = "2026-03-30T12:02:05.741Z" }, - { url = "https://files.pythonhosted.org/packages/1d/7b/929639954b02d6904a1e7c367dbc6b45add6ff46e196188de4e910059411/rsloop-0.1.14-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c0b902d84cda2fccc85857602de64b0850e4a75a7ef8f270eeda601df57836bb", size = 2384043, upload-time = "2026-03-30T12:02:07.464Z" }, - { url = "https://files.pythonhosted.org/packages/11/86/674cd68b907d8540aed8a56069e61675c828e4d37308879b645979d12328/rsloop-0.1.14-cp312-cp312-manylinux_2_39_aarch64.whl", hash = "sha256:6c50e44ab4381fce49ffb030de7a86d6b1e76a0dee5995b69c9e6489357158eb", size = 2484291, upload-time = "2026-03-30T12:02:09.113Z" }, - { url = "https://files.pythonhosted.org/packages/88/bd/5ea8f6b0fbbc3bcd69eff28ca9406726b6a8b48dbdf9e0d781edd1cfc7f7/rsloop-0.1.14-cp312-cp312-manylinux_2_39_x86_64.whl", hash = "sha256:f9d272473bddeeb160d4484af939aed2ad3995b2b73921fcdadd42a85924dd6b", size = 2621691, upload-time = "2026-03-30T12:02:10.972Z" }, - { url = "https://files.pythonhosted.org/packages/04/cd/d30a85f2491987e7b6edfbd2e7cba6f4abf8fe05dfcfd6da853cf6e1c354/rsloop-0.1.14-cp312-cp312-win_amd64.whl", hash = "sha256:325e4afe88737c592a8f9453a1993d1d324981d5a7a548fc575ca02b0a162fd2", size = 2208971, upload-time = "2026-03-30T12:02:12.417Z" }, - { url = "https://files.pythonhosted.org/packages/b1/48/46a4c4b95a9001ecea60ca9cf0d2d6ff635c77df93a0a0020f09cd1eb093/rsloop-0.1.14-cp312-cp312-win_arm64.whl", hash = "sha256:ab5cee828a07e5d312b46f7e11bbf0452a7072aa54b93eb89d88115afa02b719", size = 2265181, upload-time = "2026-03-30T12:02:13.865Z" }, - { url = "https://files.pythonhosted.org/packages/8a/ca/92b6476bce481e4d3477a72c14e5437613e03c6c73f35e9c04489068301c/rsloop-0.1.14-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0a38cfd15114dd4a7456a95edc990bd4ecadc526b646c54c9a307c9b41a22572", size = 2538044, upload-time = "2026-03-30T12:02:15.544Z" }, - { url = "https://files.pythonhosted.org/packages/12/64/7aa6e58eedca65e7a803b76742736b0a7cd17f70f61de18bddde47221267/rsloop-0.1.14-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:00e8059f499a91aab0cb3750e0131cd5bd3827ba5e78e45e67f4878f97ba7bc3", size = 2383614, upload-time = "2026-03-30T12:02:17.234Z" }, - { url = "https://files.pythonhosted.org/packages/98/86/82c06d8afe51bc0404ce7f40179babd7f42ca9d8fdfb485cf6d0e7245431/rsloop-0.1.14-cp313-cp313-manylinux_2_39_aarch64.whl", hash = "sha256:fc8e53f617cc2d952ad5107c33e7b6a778a917d7b8f996b7cb9867eec8db80cd", size = 2483907, upload-time = "2026-03-30T12:02:18.997Z" }, - { url = "https://files.pythonhosted.org/packages/f5/b8/58cc1f957e6c544d5ee717cc9c44cf443134a984e5af59d403e2dccb0bba/rsloop-0.1.14-cp313-cp313-manylinux_2_39_x86_64.whl", hash = "sha256:2022fd1373ca764e944e090adde72930dcad01643c5a48021027c06e97450e55", size = 2621240, upload-time = "2026-03-30T12:02:20.702Z" }, - { url = "https://files.pythonhosted.org/packages/ad/68/bfa44c445825b0b1b4d4571cd4d1a23813775c1de64fbdab15551b1973f3/rsloop-0.1.14-cp313-cp313-win_amd64.whl", hash = "sha256:78d019ef329fe6b12aa751af31461e819d956ec0896824d5508a4a911e15f5a1", size = 2208419, upload-time = "2026-03-30T12:02:22.293Z" }, - { url = "https://files.pythonhosted.org/packages/28/46/c2c64fa5a402c9f85f6283d205e2efb6d78105d1fdb6a51d318475368924/rsloop-0.1.14-cp313-cp313-win_arm64.whl", hash = "sha256:a5299c7ec4fbb4dbc259c1571f5dfa3233880e6569c9ccdf3f9f3c78f5b47a4e", size = 2264466, upload-time = "2026-03-30T12:02:23.606Z" }, - { url = "https://files.pythonhosted.org/packages/4a/ce/d5ac1969fe77f2caf70ae23210ec95607ee3426f842c4ccdbcee4faf3718/rsloop-0.1.14-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:842ec12e279b3bf67d8d0557e7ddbceb795a34d88d33f370bb60a1cb8e334c6f", size = 2533617, upload-time = "2026-03-30T12:02:24.93Z" }, - { url = "https://files.pythonhosted.org/packages/3c/cb/782c4dc1b4a3dfeec32656151c9c7bf7bc65b8f8eb3962e8ec15d43901a2/rsloop-0.1.14-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fad090b15cc6c8be7a57e332aa35b9c7e3904f8fe04132d41f8d039efcc794d8", size = 2379348, upload-time = "2026-03-30T12:02:26.407Z" }, - { url = "https://files.pythonhosted.org/packages/97/7b/d0280c00c65656a54c1c3b978b7037b2ba38fe122132f5c6866634521ff8/rsloop-0.1.14-cp314-cp314-manylinux_2_39_aarch64.whl", hash = "sha256:9038518236d918928ba1c61698192063cf82ff6929fb509f9cc0c72101d39ca7", size = 2480220, upload-time = "2026-03-30T12:02:27.783Z" }, - { url = "https://files.pythonhosted.org/packages/6d/90/316e030650bc74118ae65f586d6d98cb1aa488835298cf994255ac05bfe7/rsloop-0.1.14-cp314-cp314-manylinux_2_39_x86_64.whl", hash = "sha256:3fa78597dc18c2b3696b847efa86db82a375809e47c4fc4b8e145d5e4698a203", size = 2617807, upload-time = "2026-03-30T12:02:29.237Z" }, - { url = "https://files.pythonhosted.org/packages/04/82/bcf5cd41c1952ca032adb1c0a1683f324099d6050f0803e53f233ac67d4a/rsloop-0.1.14-cp314-cp314-win_amd64.whl", hash = "sha256:d07f9219117ade0eb9eb79590d5d819dfcb1b4aed7521ffcbee5b35286d705e6", size = 2206492, upload-time = "2026-03-30T12:02:30.601Z" }, - { url = "https://files.pythonhosted.org/packages/94/39/f940535e4843a09f571e62139180634563c773964000ba1aea87e477476a/rsloop-0.1.14-cp314-cp314-win_arm64.whl", hash = "sha256:0b1b0ff7ccf5fa969b676ba3d2171a42c7ce2f74320405b46e435f58aca3e1ce", size = 2262192, upload-time = "2026-03-30T12:02:32.161Z" }, - { url = "https://files.pythonhosted.org/packages/3a/93/87fd9bb5a4a1abdc162ce61e0d36e74d31def85b5910a749e84a3b3f9faf/rsloop-0.1.14-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:1681cd7c22484d1ba0487e446c3788face488f9ca74a189c8bf3bc786cb00c83", size = 2519893, upload-time = "2026-03-30T12:02:33.801Z" }, - { url = "https://files.pythonhosted.org/packages/db/35/4703c6f0b084d806ff3e8d90576174517ce1516201ed8dcdee4f2c727d3a/rsloop-0.1.14-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:367ad43e590ced5d608bc9ce5fefb0753ab0cad9abfa4f67759499ead46802ef", size = 2367665, upload-time = "2026-03-30T12:02:35.719Z" }, - { url = "https://files.pythonhosted.org/packages/2f/c9/27b04013e7200a18006e133f96d278fb57d2c95428f99c16de5939a9b50d/rsloop-0.1.14-cp314-cp314t-manylinux_2_39_aarch64.whl", hash = "sha256:15f1d00f9e4bd80f88dc25429f041a9b1bb69c8f65dc405e55427c90f70ce2f8", size = 2467427, upload-time = "2026-03-30T12:02:37.462Z" }, - { url = "https://files.pythonhosted.org/packages/6e/66/366ce42bd268902ef63e68bdac3feb3e21b4ae2443520b075f059cd0e85b/rsloop-0.1.14-cp314-cp314t-manylinux_2_39_x86_64.whl", hash = "sha256:4b1b3acfbebfcc856ca1685621e1b8909470cba6093461bc68b71c385c10f0c6", size = 2609639, upload-time = "2026-03-30T12:02:39.303Z" }, - { url = "https://files.pythonhosted.org/packages/f8/7d/9c531f8e0d9b07f9721e7f2d574204eb2bf084694ec40c7310aed08fa092/rsloop-0.1.14-cp314-cp314t-win_amd64.whl", hash = "sha256:7d1dc20c9040bc0a13ee213a5bac7cc108eaef178402c68ccf87c87ca5465f24", size = 2197083, upload-time = "2026-03-30T12:02:40.995Z" }, - { url = "https://files.pythonhosted.org/packages/a0/3f/9a33650320023b0a1a036dd742c30e38191627f1d9ca22122fe77f734b03/rsloop-0.1.14-cp314-cp314t-win_arm64.whl", hash = "sha256:26c13131199b660a2ace836c703cc2fe5db184685335908f6109751121e3a753", size = 2247666, upload-time = "2026-03-30T12:02:42.32Z" }, - { url = "https://files.pythonhosted.org/packages/b2/93/78f39636f8bb2de8d3a74f8102dcbfdae4f3207b80d7c351cb603f421d1e/rsloop-0.1.14-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:3167002986161de532ca812622081ed7ee16eda0de1a56fd071b0d2bc782e130", size = 2539474, upload-time = "2026-03-30T12:02:43.827Z" }, - { url = "https://files.pythonhosted.org/packages/7a/a8/ed9e9b6ec99d0bba2205d12695856ec0e898152ec9d565f2babfdd9f0ef2/rsloop-0.1.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:114a4903d391ade4b0e40516aa64271dc52ef31861c1882b7474a1122ce8c159", size = 2387540, upload-time = "2026-03-30T12:02:45.527Z" }, - { url = "https://files.pythonhosted.org/packages/9d/b3/d73e73ed0f5176113b1414a492e47c78f9a032b1f64b12b282c11f87c9d6/rsloop-0.1.14-cp38-cp38-manylinux_2_39_aarch64.whl", hash = "sha256:2540612ee61aee282af4088e44b27e603fd8c92ad85cd25081fa254b227287cc", size = 2477819, upload-time = "2026-03-30T12:02:46.889Z" }, - { url = "https://files.pythonhosted.org/packages/cc/d7/e100bdb1c689fb61a186196d545ff716a27705a5213322fa23bec53b71db/rsloop-0.1.14-cp38-cp38-manylinux_2_39_x86_64.whl", hash = "sha256:acb304352bffaf7c50348f0124d20270720dcac0ea1701b797fc392fa442fe81", size = 2612599, upload-time = "2026-03-30T12:02:48.59Z" }, - { url = "https://files.pythonhosted.org/packages/78/d3/0a2b5f39deadab7aa236ccf99635c4ecf1bacc00df08ee188613a0865774/rsloop-0.1.14-cp38-cp38-win_amd64.whl", hash = "sha256:d251a568d55ea9bd575608f551373388a778c46e3c4b8b0221e4d414288657da", size = 2212008, upload-time = "2026-03-30T12:02:50.041Z" }, - { url = "https://files.pythonhosted.org/packages/a8/15/2473fd00249d261f7e07f7523000e55c30c1c1c114a2d328290326b31db5/rsloop-0.1.14-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:4e9ec458d016781198de0fed07100d196993706859c2bc159dbe8f4e93465bb1", size = 2538564, upload-time = "2026-03-30T12:02:51.834Z" }, - { url = "https://files.pythonhosted.org/packages/74/ea/bc3266210f7f72a66553e37f09367378be867c70c2edc180b69a8af061dc/rsloop-0.1.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08d5c364f13da115fade0a070d71711615344639a68372eee758a22e1a83cfa2", size = 2387304, upload-time = "2026-03-30T12:02:53.381Z" }, - { url = "https://files.pythonhosted.org/packages/29/3f/878860ee659aeca966beb63e1d8001a2b3dc17097bcc0f7dd94df77032d7/rsloop-0.1.14-cp39-cp39-manylinux_2_39_aarch64.whl", hash = "sha256:c13b5172cae2effba012637b2019dd78cb681d38d235920482d3936c2c5b68dd", size = 2477800, upload-time = "2026-03-30T12:02:54.783Z" }, - { url = "https://files.pythonhosted.org/packages/c3/9a/901ccfaf419067dc9bf8f9f82eade9310efa3ba2ac310af824e270bf8f68/rsloop-0.1.14-cp39-cp39-manylinux_2_39_x86_64.whl", hash = "sha256:b2d67543859b3d87d18bd98729d667eca7ff6c1f8533ac9400b9fd013b300728", size = 2612558, upload-time = "2026-03-30T12:02:56.194Z" }, - { url = "https://files.pythonhosted.org/packages/f0/85/74beb1aec1d8282949fbe7c50b06abd7a4724a4fa311a498d4635b9f3519/rsloop-0.1.14-cp39-cp39-win_amd64.whl", hash = "sha256:db1d57081ddede30615a338500a90ad925ce62ac40d8d5fd673a727948b90e3b", size = 2212907, upload-time = "2026-03-30T12:02:57.955Z" }, + { url = "https://files.pythonhosted.org/packages/65/1c/35cbb1e696722ec3d7c3fa5cded18bf4da0d3dddf9decd74891ba3af247f/rsloop-0.1.59-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:5ecafa2a3ededf82a656de07a2c7b60ec00837c967f0a0573ca1118b8d96320a", size = 2462448, upload-time = "2026-10-07T17:29:26.267Z" }, + { url = "https://files.pythonhosted.org/packages/4d/8c/7ec75dfdec104b948b2fc93606bb6de701bfc980eb07ec5bf794a4127173/rsloop-0.1.59-cp310-cp310-macosx_13_0_x86_64.whl", hash = "sha256:163337d95bd5897104d6d87206b35a2b916a00b6b8e3c351e0cb1103d864d8d6", size = 2601959, upload-time = "2026-10-07T17:29:28.202Z" }, + { url = "https://files.pythonhosted.org/packages/2a/3e/9fdf20629f22d53fab928e02a403e6e8bf4a937edbd965809793f21d0edc/rsloop-0.1.59-cp310-cp310-manylinux_2_39_aarch64.whl", hash = "sha256:6bc1c73ccfb009098ac4cabcda2051e5ded43a139592ee4981b8872761f1e8ec", size = 2544145, upload-time = "2026-10-07T17:29:29.857Z" }, + { url = "https://files.pythonhosted.org/packages/1f/e9/63ad54b6533e692ec33a947adde0def3db956fe47a7154c558fc94e7bbed/rsloop-0.1.59-cp310-cp310-manylinux_2_39_x86_64.whl", hash = "sha256:64ed2a225bad465bed2aca429b6f6f6565458764dc2fdd4bab7991aa1083dd90", size = 2660431, upload-time = "2026-10-07T17:29:31.259Z" }, + { url = "https://files.pythonhosted.org/packages/5f/19/725842eb28b542a3c00e0395c3848c2bca8a936dad042f9f9a237072c818/rsloop-0.1.59-cp310-cp310-win_amd64.whl", hash = "sha256:026195623f1836612aaa7281220fe44997e85a02f41be48a41a5c52199f77b79", size = 2292001, upload-time = "2026-10-07T17:29:32.843Z" }, + { url = "https://files.pythonhosted.org/packages/0f/55/5b5eac818c038d941015476d5d727858124ce6788f3a840ad816c0589b66/rsloop-0.1.59-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:58cccdeb80c48f9c0c037ac53645934039d8b130123dbf9c50683cb406e5f320", size = 2463603, upload-time = "2026-10-07T17:29:34.291Z" }, + { url = "https://files.pythonhosted.org/packages/b3/f6/96817a5e11c1257a70dde15af66cb2fcf4729f0adde55f45067b942833fc/rsloop-0.1.59-cp311-cp311-macosx_13_0_x86_64.whl", hash = "sha256:45185e931cfa176933bb0e60b8d5e547c9f55e236c223e229468d93cac53a869", size = 2602788, upload-time = "2026-10-07T17:29:35.857Z" }, + { url = "https://files.pythonhosted.org/packages/23/3a/86b3f06c9bf8bb5f3f7cc1162075749714a145734bce72b9c2a957e8e67d/rsloop-0.1.59-cp311-cp311-manylinux_2_39_aarch64.whl", hash = "sha256:fcebc7574017217f321a49f51b3049af08d5a7283b35a6d36e37803aae92776a", size = 2545159, upload-time = "2026-10-07T17:29:37.443Z" }, + { url = "https://files.pythonhosted.org/packages/fa/fe/7c6d2112a802710a83f3274ea05f084d813f240f74851267d6403493d4cc/rsloop-0.1.59-cp311-cp311-manylinux_2_39_x86_64.whl", hash = "sha256:c577a20153d16a18f2bd4729eb76b6cabad646a5e0f4ffd7a56cb55683e77f04", size = 2661435, upload-time = "2026-10-07T17:29:38.852Z" }, + { url = "https://files.pythonhosted.org/packages/07/3b/35fd4cb409585a51be9b3ba93820363334a35d2eda7d0546f19533325860/rsloop-0.1.59-cp311-cp311-win_amd64.whl", hash = "sha256:8ec520d8e2fb477af90285de088771bd0f02f9ae8c57ca79d73f60ef325060c3", size = 2293025, upload-time = "2026-10-07T17:29:40.416Z" }, + { url = "https://files.pythonhosted.org/packages/85/f3/bfc9179d59a1ed4e8acfe82cad16a6b2aa22542efed6cede3cea96ba943c/rsloop-0.1.59-cp311-cp311-win_arm64.whl", hash = "sha256:cd83d09c4b71f714eb250564fa6b84a5fb0089401dd930116130ec95afb38c34", size = 2311506, upload-time = "2026-10-07T17:29:42.245Z" }, + { url = "https://files.pythonhosted.org/packages/31/9f/9b147b41b43ad8bb384d5c524946d447cea70b2d1d0a594617bbb6b41c99/rsloop-0.1.59-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:eeb496468829ebf8178d4cf93963c18fe135809733812484a73556d98801af9c", size = 2449643, upload-time = "2026-10-07T17:29:43.572Z" }, + { url = "https://files.pythonhosted.org/packages/73/ad/9b76b5bff994d90bd4266fb06d975d2b3653cc0aef0f41fac1c917de1a43/rsloop-0.1.59-cp312-cp312-macosx_13_0_x86_64.whl", hash = "sha256:b592ac7d49e381652136d7bfb9691b6ce710670ef81eb6edc3a8e29faca35e65", size = 2632476, upload-time = "2026-10-07T17:29:44.976Z" }, + { url = "https://files.pythonhosted.org/packages/f3/3b/29365a29a95daf7ef801d5e87b59e3c223e69d65cddb926aab8fbaf99451/rsloop-0.1.59-cp312-cp312-manylinux_2_39_aarch64.whl", hash = "sha256:ba6057499475b2efccae982b93e4ad9b60520f6512d122be3c4c0cb601e8da8f", size = 2539803, upload-time = "2026-10-07T17:29:46.512Z" }, + { url = "https://files.pythonhosted.org/packages/b0/b3/09fc0183df2f58639ebc15f508b3f486ab68d09ce28fcec8b785d97a10bf/rsloop-0.1.59-cp312-cp312-manylinux_2_39_x86_64.whl", hash = "sha256:040a7d27b63f547d1fe5986df489cbaebc2ab5d9bef7530b15b678949357ba16", size = 2659176, upload-time = "2026-10-07T17:29:48.23Z" }, + { url = "https://files.pythonhosted.org/packages/81/d0/20a214403a1f40bed1152b3485488a6d36871246d40719e1066325bf6f7f/rsloop-0.1.59-cp312-cp312-win_amd64.whl", hash = "sha256:00ca267fc0d4548f99010a3d7f44761b4d97f8d9d3125a86616239b5ef783b61", size = 2284827, upload-time = "2026-10-07T17:29:49.705Z" }, + { url = "https://files.pythonhosted.org/packages/27/f9/81c93142ed29f8e6100e7b886e8f858ea820e75c8ca51ec977ec5e49bd73/rsloop-0.1.59-cp312-cp312-win_arm64.whl", hash = "sha256:56080e71d20afaea18e7e97a4c10bea78aaf1fe1959076696074db87dba4267c", size = 2301576, upload-time = "2026-10-07T17:29:51.223Z" }, + { url = "https://files.pythonhosted.org/packages/3f/1e/3a18997285310d4c72f174d431e682a18265a2d5524eed22ffcf1ed530d8/rsloop-0.1.59-cp313-cp313-macosx_13_0_arm64.whl", hash = "sha256:2c44258a208e8c7ba7b2013db612d43119bc9740208ea78193f0bb7b52ad312f", size = 2454989, upload-time = "2026-10-07T17:29:52.65Z" }, + { url = "https://files.pythonhosted.org/packages/04/62/54847856467e25cf901bf7025bcf1f8b7e1741a534c61736aa350133855d/rsloop-0.1.59-cp313-cp313-macosx_13_0_x86_64.whl", hash = "sha256:213f4c9d1c43af793599915bbbfb24df5b3a52e558fdfc1934134a2158dd174b", size = 2639456, upload-time = "2026-10-07T17:29:54.32Z" }, + { url = "https://files.pythonhosted.org/packages/24/ce/5276a4cba7c9aea6e816d0416546a545cd870ef5da6b356a959ff432a88a/rsloop-0.1.59-cp313-cp313-manylinux_2_39_aarch64.whl", hash = "sha256:faf1b73e3995427238d7e7633b42f4c30f01324ac90a21c1f16e2a42864c95ad", size = 2545123, upload-time = "2026-10-07T17:29:56.353Z" }, + { url = "https://files.pythonhosted.org/packages/52/41/1e9cc4b2f02f615be75e3972da8b5bb392bd00ca7b64b940f3eb844dfbc8/rsloop-0.1.59-cp313-cp313-manylinux_2_39_x86_64.whl", hash = "sha256:e132770d7b78d70947edbc426c1c718ac43784101865d11f049722d1ee90f1b1", size = 2667152, upload-time = "2026-10-07T17:29:57.735Z" }, + { url = "https://files.pythonhosted.org/packages/38/ad/e4e5bb4ab46e4704b2c46b9f0b066b3e7714add8a73186f5736102860fa2/rsloop-0.1.59-cp313-cp313-win_amd64.whl", hash = "sha256:c331862bd47397cfded0688be10e9d996ee5f36e779fbddf67155592f486607d", size = 2292066, upload-time = "2026-10-07T17:29:59.175Z" }, + { url = "https://files.pythonhosted.org/packages/f5/c6/fedfea94ed0fbbd056011bcb4e96116fd1956df96368ee44abaa4709154f/rsloop-0.1.59-cp313-cp313-win_arm64.whl", hash = "sha256:1927dea32892efe506a70925a5b4338e105a38ee215c8d7f437f6b8c089a7e2e", size = 2307161, upload-time = "2026-10-07T17:30:00.786Z" }, + { url = "https://files.pythonhosted.org/packages/85/70/f39e1060e6f54763857f2d9952e84f852b3faf1265b72c85a63203c32403/rsloop-0.1.59-cp314-cp314-macosx_13_0_arm64.whl", hash = "sha256:2869a279103ae1cd0bdc6b1387ed4f441db85de39960c687b87b00557817cbfc", size = 2453847, upload-time = "2026-10-07T17:30:02.549Z" }, + { url = "https://files.pythonhosted.org/packages/5a/b4/940f564762b3bfd6469545afae0ea4bf4e6e2e31989030967a76c419b09f/rsloop-0.1.59-cp314-cp314-macosx_13_0_x86_64.whl", hash = "sha256:255b53382f52e896acbd333eacf8ae3f488e8417d1c5b41c9772a49e388ff3e4", size = 2637481, upload-time = "2026-10-07T17:30:04.08Z" }, + { url = "https://files.pythonhosted.org/packages/1b/c8/9834e226de5846f4b5a49a70d0a95c4ea6d9f054a4fe1b553ac4faade7e8/rsloop-0.1.59-cp314-cp314-manylinux_2_39_aarch64.whl", hash = "sha256:cf8a539051b32a61923fbeb88f32282b54e8197c6fd3bc0d554cece6f863edea", size = 2544005, upload-time = "2026-10-07T17:30:05.673Z" }, + { url = "https://files.pythonhosted.org/packages/5b/48/44518f93800ec0c774654de36dffe54e78c1f633f8c87a8d9d5683a96097/rsloop-0.1.59-cp314-cp314-manylinux_2_39_x86_64.whl", hash = "sha256:af6b7191966446d75f77c003ba781743b71231e621b6ee412898af5dae8779db", size = 2666297, upload-time = "2026-10-07T17:30:07.526Z" }, + { url = "https://files.pythonhosted.org/packages/ab/93/3fba76bca79f5acfd3f4cc28f48a87f232e970e26ea02b2ad6d1868c995b/rsloop-0.1.59-cp314-cp314-win_amd64.whl", hash = "sha256:55061abeeb0f0d5a94f69062a1f73893e6255bb2915b791c1f66d0e580e9064f", size = 2289887, upload-time = "2026-10-07T17:30:09.339Z" }, + { url = "https://files.pythonhosted.org/packages/b3/10/21c0deb2b1bb6db3fb88ff65a207dec446760f4ba1c5e8e78f04054d23be/rsloop-0.1.59-cp314-cp314-win_arm64.whl", hash = "sha256:d0d41ef4b8614e94eb253ac06100c2c495df998eef2c26e880c3cec49deaaed9", size = 2304956, upload-time = "2026-10-07T17:30:10.866Z" }, + { url = "https://files.pythonhosted.org/packages/5f/8e/fb0ac151e28d736e2a9757d104ba145bf9aeb5edf71eff69112ca0e03d6c/rsloop-0.1.59-cp314-cp314t-macosx_13_0_arm64.whl", hash = "sha256:112741bda43d11df6a5afc26d3c382a20d5991ef10599e0e403b3a6d7e1f0d22", size = 2438567, upload-time = "2026-10-07T17:30:12.296Z" }, + { url = "https://files.pythonhosted.org/packages/61/5c/c0f028158c901dba240b6ba17cff3619efc81d68b1649dbe6689ac766d8e/rsloop-0.1.59-cp314-cp314t-macosx_13_0_x86_64.whl", hash = "sha256:3e7e7586e2ad7627c38d8c46176365a9055ab6ab15af13ad96d0da1a3f586cb8", size = 2625108, upload-time = "2026-10-07T17:30:13.818Z" }, + { url = "https://files.pythonhosted.org/packages/18/ef/1100877562cd6efc89358876c25319b961a981c14ee2c73153f7d133d708/rsloop-0.1.59-cp314-cp314t-manylinux_2_39_aarch64.whl", hash = "sha256:51b16c03bb79e226a9ca9415ec54a7f43d6c1d8fcc2679dcce68cdbcddfbf1bf", size = 2536469, upload-time = "2026-10-07T17:30:15.247Z" }, + { url = "https://files.pythonhosted.org/packages/41/33/896b489ad8b46df0a5a82125f984b640eeaa45151bbbbb9ee41a7efcbe8d/rsloop-0.1.59-cp314-cp314t-manylinux_2_39_x86_64.whl", hash = "sha256:edde99af1ca37e1ad55fb0693b40ce54b465cc289dd119dcfdf1f0bb2004bf9a", size = 2663297, upload-time = "2026-10-07T17:30:16.732Z" }, + { url = "https://files.pythonhosted.org/packages/ad/d7/82573457a5ccf4828f7c150b355fe10a505b0a174b2b103738e2bbc2c5a5/rsloop-0.1.59-cp314-cp314t-win_amd64.whl", hash = "sha256:7ae891c9783f12c8cbb13e107406e01e7d1fd59c93b4dffb514e88fc053c86a2", size = 2281066, upload-time = "2026-10-07T17:30:18.458Z" }, + { url = "https://files.pythonhosted.org/packages/2f/f5/ffeadcee87a0445e6d7e33f045a15ac452e79fa06b6218bb144ba3f6fcae/rsloop-0.1.59-cp315-cp315-macosx_13_0_arm64.whl", hash = "sha256:fc9e95f939adba7bca9a19870663c248824ca8be98ba368310a2deede0936ca6", size = 2453726, upload-time = "2026-10-07T17:30:20.502Z" }, + { url = "https://files.pythonhosted.org/packages/b3/24/f12fdc577800d27a5cb604b91e80112e757556bb544ebe840ff0868344fd/rsloop-0.1.59-cp315-cp315-macosx_13_0_x86_64.whl", hash = "sha256:7b8fe9f763a6c8a98f93af622cf212ca902cfa51b8b4ecba8405330d5d1aad31", size = 2637408, upload-time = "2026-10-07T17:30:22.003Z" }, + { url = "https://files.pythonhosted.org/packages/a0/f3/d87c95bc749173955fb94b61b5ff77fcfadf6840a483b505dc83d8708daf/rsloop-0.1.59-cp315-cp315-manylinux_2_39_aarch64.whl", hash = "sha256:72b57a4b8a7a86af4fda52d3eda26444c8b87ec32dc5b865a005bb093e6800d6", size = 2544132, upload-time = "2026-10-07T17:30:23.424Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f1/9601ec02b6b0db83e5923197214837573cf26e892141e15c8c59ab8251d7/rsloop-0.1.59-cp315-cp315-manylinux_2_39_x86_64.whl", hash = "sha256:35feee622ebb138a3fc4667aa48fd66c433dc6b4394d9116f4b61534392d0ec0", size = 2666412, upload-time = "2026-10-07T17:30:24.995Z" }, + { url = "https://files.pythonhosted.org/packages/d2/07/3be1c780e811457950b85ac1523d0df13f772a86dee841e9aaf3f41c32fa/rsloop-0.1.59-cp315-cp315-win_amd64.whl", hash = "sha256:d8b7dd462be10249a715d5d2d1701041f76948603f1887e4f83cc26a5773dc1d", size = 2289915, upload-time = "2026-10-07T17:30:26.536Z" }, + { url = "https://files.pythonhosted.org/packages/6d/11/eaceda460dc20894db53b8ac3ab126415528b3ad6b02f5c2d03ee45d12f8/rsloop-0.1.59-cp315-cp315-win_arm64.whl", hash = "sha256:564a802a071c546dc0d7f22d4b3029c94b9a2cb3f0afcf51d177446880400361", size = 2305107, upload-time = "2026-10-07T17:30:28.307Z" }, + { url = "https://files.pythonhosted.org/packages/4f/5b/99b99663e8d4d04dd7216b9dab53fc875a6098dc00bc4de2712a6a38dd2c/rsloop-0.1.59-cp315-cp315t-macosx_13_0_arm64.whl", hash = "sha256:a0715fc2d21f951082a5a8e7eb735e120d3af950e79e1685584792e772317f8c", size = 2438837, upload-time = "2026-10-07T17:30:29.9Z" }, + { url = "https://files.pythonhosted.org/packages/6f/1b/c7537dcbaf87278813493c0cd81a8e5c3146950312fde0b205e317844069/rsloop-0.1.59-cp315-cp315t-macosx_13_0_x86_64.whl", hash = "sha256:219ae5b144645737cf1e55f613ee465fd2a74eb38696130796995f9df6eb3f98", size = 2625139, upload-time = "2026-10-07T17:30:31.527Z" }, + { url = "https://files.pythonhosted.org/packages/5c/4a/58b8b0f904fdc5bb313f296c991a826eb2524ac528c42b06811f90460d11/rsloop-0.1.59-cp315-cp315t-manylinux_2_39_aarch64.whl", hash = "sha256:b76ee48deb7fdf0a860d4afe26149a2bf6dbe1e132bf0ea6e934136d353a7d5e", size = 2536596, upload-time = "2026-10-07T17:30:33.028Z" }, + { url = "https://files.pythonhosted.org/packages/a1/01/7b2a4a9effc9741f833f87448e26647f8ee617b7f6fa5a874825de0abab3/rsloop-0.1.59-cp315-cp315t-manylinux_2_39_x86_64.whl", hash = "sha256:0d022fdef74e3953afdd0fb3e7300c239e20d84058ae07332387120310f8128c", size = 2663400, upload-time = "2026-10-07T17:30:34.774Z" }, + { url = "https://files.pythonhosted.org/packages/46/00/aedfd34d6d943dba5976c2cbe9f2d58a10c82187dfcee6f375e15248d848/rsloop-0.1.59-cp315-cp315t-win_amd64.whl", hash = "sha256:423998fedf242f65672aad6aeafcfc482dccc92b38b27ffc7567559a6f3305b0", size = 2281165, upload-time = "2026-10-07T17:30:36.537Z" }, ] [[package]] @@ -69,7 +69,7 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "rsloop", specifier = ">=0.1.14" }] +requires-dist = [{ name = "rsloop", specifier = ">=0.1.56" }] [package.metadata.requires-dev] dev = [{ name = "ruff", specifier = ">=0.15.8" }]