You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iggy.apache.org by ri...@apache.org on 2026/08/31 07:37:40 UTC
(iggy) branch feat/add-python-stream-management-functions updated (2c84dd2b2 -> c92f914a2)
This is an automated email from the ASF dual-hosted git repository.
slbotbm pushed a change to branch feat/add-python-stream-management-functions
in repository https://gitbox.apache.org/repos/asf/iggy.git
omit 2c84dd2b2 fixes
omit 263666597 add test clean up
omit a96ef13fa stub_gen
omit fcc135129 add tests and stubs
omit be1c32140 add proper docs
omit b9107f615 add stream getters and docs
omit f1255a495 feat(python): add stream listing, update, delete, and purge
add ec456d237 ci(security): replace package tokens with OIDC (#3892)
add f42f5abc8 chore: remove resolved TODO comments (#3887)
add be5012ec9 fix(server): restore get_user self-read without read_users permission (#3897)
add 338cd2eaf refactor(configs): clean up server config after full field audit (#3895)
add 3e805f30f fix(ci): restore Docker and PyPI releases (#3902)
add aeee0fc54 perf(connectors): add opt-in CSV output format to Doris sink (#3575)
add d24b69fda fix(cli): bound ping retries, macOS boot smoke, java PAT expiry (#3903)
add 1890c35f3 feat(csharp): add heartbeat mechanism (#3894)
add 0490a1c85 fix(metadata): enforce namespace caps at admission to stop aliasing (#3907)
add 18a159a13 refactor(sdk)!: remove v2 bridges and legacy message wire format (#3904)
add 6043d1940 refactor(consensus): build replies in Owned and clear stale todos (#3908)
add e71e3c61e chore(deps): Bump the csharp group with 1 update (#3906)
add 15fe5dce9 test(integration): add SIGKILL crash-durability cluster tests (#3905)
add c9d38ee33 test(bdd): add stream CRUD coverage for Rust and Java (#3875)
add af9ce9548 feat(connectors): add source batch acknowledgments (#3855)
add ab257a039 refactor(consensus): single restore constructor + wedge/replay/ack fixes (#3909)
add 3cd0860a9 fix(connectors): stop rendering counter metrics with a doubled _total (#3921)
add 3db955eae ci: bound apt-get so a dead mirror cannot wedge a job (#3924)
add 8ed41c7db refactor(server): consensus restore, fail-stop, linear cleanup batch (#3911)
add 565e1a7b2 refactor(shard): drop journal generic, metrics scrape, poll cursor (#3914)
add 21fc4d849 feat(shard): split the inbox into consensus and client-reply lanes (#3915)
add 89dea0ed3 fix(metadata): truncate the WAL suffix above the state-transfer floor (#3918)
add 9f3468bd5 chore(repo): remove incubating references after TLP graduation (#3928)
add 2b52fe0bd ci: replace Ana06/get-changed-files with dorny/paths-filter (#3916)
add 35d2c4244 feat(python): let poll_messages take a consumer (#3877)
add c0c74931b chore(deps): Bump taiki-e/install-action from 2.85.8 to 2.85.11 in the github-actions group (#3920)
add 0f48afd62 chore(deps): Bump the node group across 2 directories with 7 updates (#3938)
add 3a3d32387 chore(deps): Bump googletest from 1.17.0.bcr.2 to 1.18.0 in /foreign/cpp in the cpp group across 1 directory (#3937)
add ba10371a4 chore(deps): Bump the web group across 1 directory with 9 updates (#3936)
add 127a33c3b ci(rust): don't fail when a DAG scope matches no tests (#3943)
add 2b1406b18 chore(deps): Bump the python group across 3 directories with 1 update (#3926)
add cc269ef70 ci(rust): fail the build on rustdoc and rustc warnings (#3925)
add e1c868165 chore: migrate HawkEye to v7 (#3952)
add a65f177dc fix(server): truncate torn segment tails instead of resurrecting them (#3946)
add 69429e5e2 feat(connectors): store source state on an HTTP state server (#3940)
add f8311d651 feat(cpp): add functions related to user management, and initial high-level client (#3733)
add 2bd9d0bce fix(shard): tell an unknown consensus operation from a corrupt header (#3931)
add a2a8f0491 chore(deps): Bump the csharp group with 12 updates (#3961)
add 228f47e0c refactor(csharp): cleanup tcp connection after vsr implementation (#3858)
add 7207c640a ci(csharp): separate baseline coverage reports per framework (#3960)
add 4e5ec2586 fix(consensus): keep a client's dedup fence across capacity eviction (#3934)
add 2cbf6c15e chore(repo): bump Rust toolchain to 1.98.0 (#3962)
add 1a9874859 fix(connectors): Harden Elasticsearch sink test readiness (#3729)
add 4c475dfcf fix(ci): bump cargo-zigbuild so arm64 images link under Rust 1.98 (#3963)
add 37d7eee35 refactor(sdk): introduce NonZeroIggyDuration for retries and heartbeats (#3891)
add 2e420398b feat(connectors): add Redshift sink connector (#3654)
add 1e2d2220f fix(sdk): error callback should await shard flush on producer shutdown (#3953)
add 5068a960a chore(deps): Bump the github-actions group across 1 directory with 2 updates (#3968)
add d7c2b6180 fix(python): read consumer metadata without the consumer lock (#3888)
add 03f5b3034 fix(server): restore the mimalloc global allocator (#3971)
add ed59b955d chore(deps): Bump gradle from 9.6.1-jdk17 to 9.7.0-jdk17 in /bdd/java in the docker group across 1 directory (#3972)
add 37aec0877 feat(sdk): fail over to a surviving node when the current one dies (#3944)
add 6a1c84c39 fix(partitions): stop reserving 16 MiB per active segment index (#3974)
add ffb186dba feat(gateways): iggy gateway for kafka listener (#3519)
add 9c6451d62 fix(consensus): keep a late retry's reply instead of refusing it (#3945)
add 7b491c09f fix(cluster): prevent repaired prepares from rewinding WAL parent (#3978)
add 76f2dda5d feat(simulator): drive the workload under network and replica faults (#3942)
add 1ad3f654c chore(deps): Bump the web group across 1 directory with 4 updates (#3983)
add 0fdf9d688 chore(deps): Bump the node group across 1 directory with 10 updates (#3984)
add db14a4b17 fix(cluster): make the advertised leader accept partition writes (#3985)
add 90e38b10f feat(node): support connection string syntax for nodejs client creation (#3917)
add 996ac04c8 fix(cluster): recover writes after a fast partition primary rejoin (#3987)
add 5916e6f58 feat(partitions): persist log and index concurrently, harden recovery (#3970)
add eb410a96a fix(server): apply thread pool limit carve-out to all of macOS (#3994)
add c8ef3b9a4 fix(go): tear down only the connection a request failed on (#3986)
new 2567de371 feat(python): add stream listing, update, delete, and purge
new 9a93dc7bd add stream getters and docs
new 21e5177a5 add proper docs
new 7000a3de2 add tests and stubs
new 3781412f7 add test clean up
new 76520fe4a fixes
new efee3daf0 test fixture fixes
new af3e0aabd fix test
new e47f23347 address comments
new 88ba2b335 address comments
new c92f914a2 fix precommit
This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version. This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:
* -- * -- B -- O -- O -- O (2c84dd2b2)
\
N -- N -- N refs/heads/feat/add-python-stream-management-functions (c92f914a2)
You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
The 11 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.claude/skills/connector-runtime/SKILL.md | 4 +-
.devcontainer/Dockerfile | 4 +-
.github/actions/cpp-bazel/pre-merge/action.yml | 28 +-
.../actions/csharp-dotnet/post-merge/action.yml | 27 +-
.github/actions/csharp-dotnet/pre-merge/action.yml | 1 -
.github/actions/node-npm/post-merge/action.yml | 29 +-
.github/actions/node-npm/pre-merge/action.yml | 2 +-
.github/actions/php/pre-merge/action.yml | 3 +-
.../actions/python-maturin/post-merge/action.yml | 26 +-
.github/actions/rust/post-merge/action.yml | 6 +-
.github/actions/rust/pre-merge/action.yml | 85 +-
.github/actions/utils/docker-buildx/action.yml | 6 +-
.../actions/utils/setup-rust-with-cache/action.yml | 4 +-
.github/config/components.yml | 12 +-
.github/config/hawkeye.version | 2 +-
.github/workflows/_build_rust_artifacts.yml | 2 +-
.github/workflows/_common.yml | 4 +-
.github/workflows/_detect.yml | 9 +-
.github/workflows/_publish_rust_crates.yml | 63 +-
.github/workflows/_test_examples.yml | 5 +-
.github/workflows/coverage-baseline.yml | 39 +-
.github/workflows/edge-release.yml | 6 -
.github/workflows/post-merge.yml | 81 +-
.github/workflows/pr-title.yml | 1 +
.github/workflows/publish.yml | 115 +-
.gitignore | 1 +
AGENTS.md | 2 +-
CONTRIBUTING.md | 2 +-
Cargo.lock | 599 ++-
Cargo.toml | 23 +-
DISCLAIMER | 5 -
Dockerfile | 14 +-
LICENSE | 4 +-
NOTICE | 2 +-
README.md | 4 +-
SECURITY.md | 6 +-
about.hbs | 4 +-
.../features/step_definitions/background_steps.cpp | 5 +-
.../features/step_definitions/messaging_steps.cpp | 18 +-
bdd/csharp/Dockerfile | 12 -
bdd/docker-compose.coverage.yml | 12 +-
bdd/docker-compose.yml | 4 +
bdd/go/Dockerfile | 12 -
bdd/go/go.mod | 2 +
bdd/go/go.sum | 6 +
bdd/java/Dockerfile | 14 +-
.../org/apache/iggy/bdd/BasicMessagingSteps.java | 50 +
.../test/java/org/apache/iggy/bdd/TestContext.java | 1 +
bdd/node/Dockerfile | 12 -
bdd/php/Dockerfile | 2 +-
bdd/php/phpunit.xml.dist | 31 +-
bdd/python/Dockerfile | 13 +-
bdd/python/pylock.toml | 74 +-
bdd/python/tests/test_basic_messaging.py | 3 +-
bdd/python/uv.lock | 293 +-
bdd/rust/Cargo.toml | 8 +
bdd/rust/Dockerfile | 14 +-
bdd/rust/tests/common/global_context.rs | 1 +
bdd/rust/tests/helpers/cluster.rs | 19 +
bdd/rust/tests/steps/leader_redirection.rs | 14 +-
bdd/rust/tests/steps/streams.rs | 137 +-
.../tests/{basic_messaging.rs => stream_crud.rs} | 2 +-
bdd/scenarios/stream_crud.feature | 52 +
core/ai/mcp/Cargo.toml | 5 +-
core/ai/mcp/Dockerfile | 4 +-
core/bench/Cargo.toml | 5 +-
core/bench/dashboard/frontend/Cargo.toml | 5 +-
core/bench/dashboard/frontend/assets/style.css | 11 -
core/bench/dashboard/frontend/index.dev.html | 31 +-
core/bench/dashboard/frontend/index.html | 28 +-
core/bench/dashboard/frontend/index.prod.html | 31 +-
.../frontend/src/components/chart/trend_chart.rs | 2 +-
.../dashboard/frontend/src/components/footer.rs | 1 -
core/bench/dashboard/server/Cargo.toml | 5 +-
core/bench/dashboard/server/Dockerfile | 14 +-
core/bench/dashboard/shared/Cargo.toml | 3 +
core/bench/report/Cargo.toml | 5 +-
core/bench/report/src/types/group_metrics.rs | 28 +-
core/bench/report/src/types/individual_metrics.rs | 94 +-
core/bench/report/src/utils.rs | 30 +-
core/bench/runner/Cargo.toml | 3 +
.../bench/src/actors/consumer/client/high_level.rs | 21 +-
core/bench/src/actors/consumer/client/low_level.rs | 11 +-
.../actors/consumer/typed_benchmark_consumer.rs | 12 +-
.../bench/src/actors/producer/client/high_level.rs | 18 +-
core/bench/src/actors/producer/client/low_level.rs | 11 +-
core/bench/src/analytics/metrics/group.rs | 48 +-
core/bench/src/analytics/metrics/individual.rs | 65 +-
core/bench/src/args/common.rs | 17 +-
core/bench/src/args/examples.rs | 6 +
core/bench/src/args/kinds/balanced/producer.rs | 19 +-
core/bench/src/benchmarks/benchmark.rs | 34 +-
core/bench/src/benchmarks/common.rs | 11 +-
core/bench/src/runner.rs | 9 +-
core/bench/src/utils/client_factory.rs | 16 +-
core/bench/src/utils/mod.rs | 2 +-
core/binary_protocol/Cargo.toml | 5 +-
core/binary_protocol/README.md | 6 -
core/binary_protocol/src/batch.rs | 663 +++
core/binary_protocol/src/codes.rs | 4 -
core/binary_protocol/src/consensus/command.rs | 10 +-
core/binary_protocol/src/consensus/error.rs | 23 +-
core/binary_protocol/src/consensus/header.rs | 382 +-
core/binary_protocol/src/consensus/mod.rs | 4 +-
core/binary_protocol/src/consensus/operation.rs | 31 +-
core/binary_protocol/src/dispatch.rs | 96 +-
core/binary_protocol/src/error.rs | 19 +
core/binary_protocol/src/framing.rs | 361 +-
core/binary_protocol/src/lib.rs | 15 +-
core/binary_protocol/src/message_layout.rs | 56 -
core/binary_protocol/src/message_view.rs | 617 ---
core/binary_protocol/src/namespace.rs | 18 +-
core/binary_protocol/src/primitives/consumer.rs | 3 +-
.../consumer_offsets/delete_consumer_offset.rs | 50 +-
.../consumer_offsets/delete_consumer_offset_2.rs | 199 -
.../src/requests/consumer_offsets/mod.rs | 4 -
.../consumer_offsets/store_consumer_offset.rs | 45 +-
.../consumer_offsets/store_consumer_offset_2.rs | 211 -
core/binary_protocol/src/requests/messages/mod.rs | 4 +-
.../src/requests/messages/send_messages.rs | 661 +--
.../consumer_offsets/delete_consumer_offset_2.rs | 19 -
.../src/responses/consumer_offsets/mod.rs | 4 -
.../consumer_offsets/store_consumer_offset_2.rs | 19 -
.../src/responses/messages/poll_messages.rs | 294 +-
core/binary_protocol/src/version.rs | 2 +-
core/cli/Cargo.toml | 5 +-
core/cli/README.md | 6 -
core/cli/src/args/context.rs | 2 +-
core/cli/src/commands/binary_client/get_clients.rs | 4 +-
.../get_personal_access_tokens.rs | 2 +-
core/clock/Cargo.toml | 3 +
core/common/Cargo.toml | 6 +-
core/common/README.md | 6 -
core/common/src/error/iggy_error.rs | 20 +
core/common/src/lib.rs | 21 +-
.../src/traits/binary_impls/consumer_offsets.rs | 3 +
core/common/src/traits/binary_impls/messages.rs | 16 +-
.../traits/binary_impls/personal_access_tokens.rs | 10 +-
core/common/src/traits/binary_impls/system.rs | 6 +-
core/common/src/traits/binary_impls/users.rs | 14 +-
core/common/src/traits/binary_transport.rs | 26 +-
core/common/src/traits/system_client.rs | 6 +-
core/common/src/types/args/mod.rs | 12 +-
.../configuration/auth_config/connection_string.rs | 8 +-
.../auth_config/connection_string_options.rs | 4 +-
.../http_config/http_client_config.rs | 9 +-
.../http_config/http_client_config_builder.rs | 22 +-
.../http_config/http_connection_string_options.rs | 34 +-
.../quic_config/quic_client_config.rs | 6 +-
.../quic_config/quic_client_config_builder.rs | 9 +-
.../quic_config/quic_client_reconnection_config.rs | 9 +-
.../quic_config/quic_connection_string_options.rs | 17 +-
.../configuration/tcp_config/tcp_client_config.rs | 6 +-
.../tcp_config/tcp_client_config_builder.rs | 7 +-
.../tcp_config/tcp_client_reconnection_config.rs | 40 +-
.../tcp_config/tcp_connection_string_options.rs | 17 +-
.../websocket_config/websocket_client_config.rs | 6 +-
.../websocket_client_config_builder.rs | 9 +-
.../websocket_client_reconnection_config.rs | 6 +-
.../websocket_connection_string_options.rs | 17 +-
core/common/src/types/message/message_view_mut.rs | 117 -
core/common/src/types/message/mod.rs | 2 -
core/common/src/types/message/polled_messages.rs | 104 +-
core/common/src/types/options/mod.rs | 12 +-
core/common/src/utils/duration.rs | 395 +-
core/common/src/utils/topic_size.rs | 7 +-
core/common/src/wire_conversions.rs | 4 +-
core/configs/Cargo.toml | 4 +-
core/configs/src/common/cache_indexes.rs | 89 -
core/configs/src/common/defaults.rs | 84 +-
core/configs/src/common/displays.rs | 50 +-
core/configs/src/common/http.rs | 48 +-
core/configs/src/common/mod.rs | 1 -
core/configs/src/common/server.rs | 27 +-
core/configs/src/common/system.rs | 48 +-
core/configs/src/common/validators.rs | 33 +-
.../configs/src/configs_impl/typed_env_provider.rs | 13 +-
core/configs/src/lib.rs | 2 +-
core/configs/src/server_config/cluster.rs | 82 +-
core/configs/src/server_config/defaults.rs | 61 +-
core/configs/src/server_config/displays.rs | 59 +-
core/configs/src/server_config/message_bus.rs | 26 +-
core/configs/src/server_config/partition.rs | 32 +-
core/configs/src/server_config/quic.rs | 110 +-
core/configs/src/server_config/server.rs | 40 +-
core/configs/src/server_config/sharding.rs | 46 +-
core/configs/src/server_config/tcp.rs | 21 -
core/configs/src/server_config/validators.rs | 372 +-
core/configs_derive/Cargo.toml | 3 +
core/configs_derive/src/lib.rs | 4 +-
core/connectors/README.md | 1 +
core/connectors/runtime/Cargo.toml | 9 +-
core/connectors/runtime/Dockerfile | 4 +-
core/connectors/runtime/README.md | 61 +
core/connectors/runtime/config.toml | 23 +-
core/connectors/runtime/example_config/config.toml | 22 +-
.../example_config/connectors/doris_sink.toml | 5 +
core/connectors/runtime/src/api/auth.rs | 7 +-
core/connectors/runtime/src/api/source.rs | 1 -
.../connectors/http_provider/response_extractor.rs | 2 +-
core/connectors/runtime/src/configs/runtime.rs | 241 +-
core/connectors/runtime/src/context.rs | 7 +-
core/connectors/runtime/src/error.rs | 10 +
core/connectors/runtime/src/main.rs | 24 +-
core/connectors/runtime/src/manager/source.rs | 50 +-
core/connectors/runtime/src/metrics.rs | 91 +-
core/connectors/runtime/src/source.rs | 492 +-
core/connectors/runtime/src/state.rs | 146 +
core/connectors/runtime/src/state/http.rs | 1539 +++++++
core/connectors/runtime/src/stream.rs | 102 +-
core/connectors/sdk/Cargo.toml | 5 +-
core/connectors/sdk/README.md | 29 +
core/connectors/sdk/src/lib.rs | 27 +
core/connectors/sdk/src/source.rs | 897 +++-
core/connectors/sinks/README.md | 1 +
core/connectors/sinks/clickhouse_sink/Cargo.toml | 5 +-
core/connectors/sinks/delta_sink/Cargo.toml | 5 +-
core/connectors/sinks/doris_sink/Cargo.toml | 5 +-
core/connectors/sinks/doris_sink/README.md | 7 +-
core/connectors/sinks/doris_sink/config.toml | 5 +
core/connectors/sinks/doris_sink/src/lib.rs | 364 +-
.../connectors/sinks/elasticsearch_sink/Cargo.toml | 5 +-
core/connectors/sinks/elasticsearch_sink/README.md | 2 +-
.../connectors/sinks/elasticsearch_sink/src/lib.rs | 20 +-
core/connectors/sinks/http_sink/Cargo.toml | 5 +-
core/connectors/sinks/http_sink/src/lib.rs | 2 +-
core/connectors/sinks/iceberg_sink/Cargo.toml | 5 +-
core/connectors/sinks/influxdb_sink/Cargo.toml | 5 +-
core/connectors/sinks/meilisearch_sink/Cargo.toml | 5 +-
core/connectors/sinks/mongodb_sink/Cargo.toml | 5 +-
core/connectors/sinks/postgres_sink/Cargo.toml | 5 +-
core/connectors/sinks/quickwit_sink/Cargo.toml | 5 +-
.../sinks/{s3_sink => redshift_sink}/Cargo.toml | 20 +-
core/connectors/sinks/redshift_sink/README.md | 216 +
.../{postgres_sink => redshift_sink}/config.toml | 21 +-
core/connectors/sinks/redshift_sink/src/config.rs | 159 +
core/connectors/sinks/redshift_sink/src/lib.rs | 1491 ++++++
core/connectors/sinks/s3_sink/Cargo.toml | 5 +-
core/connectors/sinks/stdout_sink/Cargo.toml | 5 +-
core/connectors/sinks/surrealdb_sink/Cargo.toml | 5 +-
core/connectors/sources/README.md | 33 +-
.../sources/elasticsearch_source/Cargo.toml | 5 +-
core/connectors/sources/influxdb_source/Cargo.toml | 5 +-
core/connectors/sources/postgres_source/Cargo.toml | 5 +-
core/connectors/sources/random_source/Cargo.toml | 5 +-
core/connectors/sources/random_source/src/lib.rs | 91 +-
core/consensus/Cargo.toml | 7 +-
core/consensus/src/client_table.rs | 1330 +++++-
core/consensus/src/dvc_merge.rs | 6 +-
core/consensus/src/fatal.rs | 4 +
core/consensus/src/impls.rs | 288 +-
core/consensus/src/lib.rs | 9 +-
core/consensus/src/metadata_helpers.rs | 32 +-
core/consensus/src/observability.rs | 2 -
core/consensus/src/plane_helpers.rs | 189 +-
core/consensus/src/state_manifest.rs | 2 +-
core/consensus/src/view_change_quorum.rs | 4 +-
core/consensus/src/vsr_state.rs | 2 +-
core/consensus/src/vsr_timeout.rs | 12 +-
core/cpu_allocation/Cargo.toml | 3 +
core/harness_derive/Cargo.toml | 3 +
core/harness_derive/src/attrs.rs | 51 +-
core/harness_derive/src/codegen.rs | 24 +-
core/harness_derive/src/lib.rs | 10 +-
core/integration/Cargo.toml | 12 +-
core/integration/src/harness/config/resolve.rs | 27 +-
core/integration/src/harness/disk.rs | 493 ++
.../src/harness/handle/client_builder.rs | 61 +-
.../src/harness/handle/connectors_runtime.rs | 56 +-
core/integration/src/harness/handle/server.rs | 34 +-
core/integration/src/harness/mod.rs | 1 +
.../src/harness/orchestrator/harness.rs | 173 +-
.../cli/context/test_context_create_command.rs | 2 +-
.../tests/cli/general/test_help_command.rs | 6 +-
.../tests/cluster/client_table_adversarial.rs | 463 ++
.../tests/cluster/client_table_restart.rs | 8 +-
core/integration/tests/cluster/crash_durability.rs | 519 +++
.../tests/cluster/crash_offset_reuse.rs | 143 +
.../tests/cluster/crash_recovery_corruption.rs | 946 ++++
.../tests/cluster/failover_client_continuity.rs | 183 +
.../tests/cluster/fast_primary_rejoin.rs | 472 ++
.../tests/cluster/metadata_checkpoint_restart.rs | 2 +-
core/integration/tests/cluster/mod.rs | 8 +
.../tests/cluster/partition_primary_routing.rs | 198 +
.../tests/cluster/staggered_bootstrap.rs | 180 +
core/integration/tests/config_provider/mod.rs | 56 +-
.../tests/connectors/doris/doris_sink.rs | 86 +-
.../doris/doris_stream_load_format_bench.rs | 285 ++
core/integration/tests/connectors/doris/mod.rs | 1 +
.../tests/connectors/fixtures/doris/container.rs | 45 +
.../tests/connectors/fixtures/doris/mod.rs | 4 +-
.../connectors/fixtures/elasticsearch/container.rs | 385 +-
.../connectors/fixtures/elasticsearch/sink.rs | 103 +-
.../connectors/fixtures/elasticsearch/source.rs | 2 -
core/integration/tests/connectors/fixtures/mod.rs | 9 +-
.../connectors/fixtures/redshift/container.rs | 276 ++
.../fixtures/{clickhouse => redshift}/mod.rs | 5 +-
.../fixtures/redshift/redshift_mock/ddl.rs | 77 +
.../fixtures/redshift/redshift_mock/dml.rs | 209 +
.../fixtures/redshift/redshift_mock/dql.rs | 92 +
.../fixtures/redshift/redshift_mock/handler.rs | 256 ++
.../fixtures/redshift/redshift_mock/load.rs | 314 ++
.../fixtures/redshift/redshift_mock}/mod.rs | 8 +-
.../fixtures/redshift/redshift_mock/parser.rs | 556 +++
.../fixtures/redshift/redshift_mock/util.rs | 152 +
.../tests/connectors/fixtures/redshift/sink.rs | 480 ++
core/integration/tests/connectors/mod.rs | 1 +
.../tests/connectors/random/random_source.rs | 123 +
.../tests/connectors/{http => redshift}/mod.rs | 2 +-
.../tests/connectors/redshift/redshift_sink.rs | 418 ++
.../tests/connectors/{delta => redshift}/sink.toml | 2 +-
.../tests/connectors/runtime/benchmark.rs | 7 +
.../tests/connectors/runtime/http_state.rs | 417 ++
.../{benchmark_json.toml => http_state.toml} | 16 +-
.../random_source.toml | 11 +-
core/integration/tests/connectors/runtime/mod.rs | 1 +
.../data_integrity/verify_after_server_restart.rs | 31 +-
.../verify_cluster_replica_data_identical.rs | 234 +-
.../verify_consumer_group_partition_assignment.rs | 74 +-
core/integration/tests/sdk/consumer_group.rs | 10 +-
.../tests/sdk/consumer_group_membership.rs | 17 +-
core/integration/tests/sdk/disconnect_relogin.rs | 66 +
core/integration/tests/sdk/mod.rs | 1 +
core/integration/tests/sdk/protocol_version.rs | 6 +-
core/integration/tests/server/cg.rs | 21 +-
core/integration/tests/server/flush_vsr.rs | 3 +-
core/integration/tests/server/general.rs | 18 -
core/integration/tests/server/http_client.rs | 3 +-
core/integration/tests/server/http_rbac.rs | 22 +-
core/integration/tests/server/legacy_login_vsr.rs | 6 +-
core/integration/tests/server/message_cleanup.rs | 12 +
core/integration/tests/server/message_retrieval.rs | 50 +-
core/integration/tests/server/mod.rs | 2 +-
.../tests/server/partition_view_durability_vsr.rs | 22 +-
.../integration/tests/server/poll_semantics_vsr.rs | 15 +-
core/integration/tests/server/purge_delete.rs | 32 +-
core/integration/tests/server/purge_vsr.rs | 3 +-
.../server/scenarios/authentication_scenario.rs | 11 -
.../concurrent_produce_consume_scenario.rs | 2 +-
...umer_group_auto_commit_reconnection_scenario.rs | 2 +-
.../consumer_group_offset_cleanup_scenario.rs | 2 +-
.../consumer_timestamp_polling_scenario.rs | 2 +-
.../scenarios/cross_protocol_pat_scenario.rs | 15 +-
.../server/scenarios/message_cleanup_scenario.rs | 72 +-
.../tests/server/scenarios/permissions_scenario.rs | 18 +
.../server/scenarios/purge_delete_scenario.rs | 8 +-
.../scenarios/read_during_persistence_scenario.rs | 35 +-
.../scenarios/reconnect_after_restart_scenario.rs | 4 +-
.../scenarios/restart_offset_skip_scenario.rs | 3 +-
.../scenarios/segment_rotation_race_scenario.rs | 1 -
.../stale_client_consumer_group_scenario.rs | 12 +-
.../scenarios/stream_size_validation_scenario.rs | 8 +-
core/integration/tests/server/specific.rs | 19 +-
core/integration/tests/server/stats_vsr.rs | 3 +-
.../tests/server/topic_admission_vsr.rs | 177 +-
core/journal/Cargo.toml | 3 +
core/journal/src/file_storage.rs | 5 +
core/journal/src/lib.rs | 25 +-
core/journal/src/prepare_journal.rs | 67 +-
core/message_bus/Cargo.toml | 7 +-
core/message_bus/src/config.rs | 43 +-
core/message_bus/src/framing.rs | 8 +-
core/message_bus/src/installer/tcp.rs | 4 +-
core/message_bus/src/lib.rs | 10 +-
.../src/lifecycle/connection_registry.rs | 6 +-
core/message_bus/src/replica/auth.rs | 2 +-
core/message_bus/src/replica/handshake.rs | 18 +-
core/message_bus/src/transports/quic.rs | 43 +-
core/message_bus/src/transports/tcp.rs | 12 +-
core/message_bus/src/transports/tcp_tls.rs | 22 +-
core/message_bus/src/transports/tls/mod.rs | 33 +-
core/message_bus/src/transports/ws.rs | 20 +-
core/message_bus/src/transports/wss.rs | 20 +-
core/message_bus/tests/backpressure.rs | 4 +-
core/message_bus/tests/common/mod.rs | 4 +-
core/message_bus/tests/duplicate_client_id.rs | 4 +-
core/message_bus/tests/graceful_shutdown.rs | 2 +-
core/message_bus/tests/head_of_line.rs | 12 +-
core/message_bus/tests/quic_client_roundtrip.rs | 14 +-
core/message_bus/tests/replica_auth_handshake.rs | 12 +-
core/message_bus/tests/replica_roundtrip.rs | 10 +-
core/message_bus/tests/replica_tls_bench.rs | 4 +-
core/message_bus/tests/replica_tls_roundtrip.rs | 10 +-
core/message_bus/tests/tcp_client_roundtrip.rs | 12 +-
core/message_bus/tests/tcp_tls_client_listener.rs | 10 +-
core/message_bus/tests/tcp_tls_client_roundtrip.rs | 10 +-
core/message_bus/tests/vectored_batch.rs | 4 +-
core/message_bus/tests/ws_client_roundtrip.rs | 10 +-
core/message_bus/tests/wss_client_listener.rs | 10 +-
core/message_bus/tests/wss_client_roundtrip.rs | 10 +-
core/metadata/Cargo.toml | 8 +-
core/metadata/src/impls/metadata.rs | 528 ++-
core/metadata/src/impls/mod.rs | 5 +
core/metadata/src/impls/recovery.rs | 55 +-
core/metadata/src/stm/authz.rs | 14 +-
core/metadata/src/stm/consumer_group.rs | 8 +-
core/metadata/src/stm/id_slab.rs | 353 ++
core/metadata/src/stm/mod.rs | 9 +-
core/metadata/src/stm/result.rs | 41 +-
core/metadata/src/stm/snapshot.rs | 87 +-
core/metadata/src/stm/stream.rs | 541 ++-
core/metadata/src/stm/user.rs | 49 +-
core/partitions/Cargo.toml | 7 +-
core/partitions/src/iggy_index.rs | 6 +
core/partitions/src/iggy_index_reader.rs | 91 +-
core/partitions/src/iggy_index_writer.rs | 68 +-
core/partitions/src/iggy_partition.rs | 1547 +++++--
core/partitions/src/iggy_partitions.rs | 29 +-
core/partitions/src/journal.rs | 61 +-
core/partitions/src/lib.rs | 34 +-
core/partitions/src/log.rs | 140 +-
core/partitions/src/messages_writer.rs | 76 +-
core/partitions/src/poll_plan.rs | 231 +-
core/partitions/src/state_transfer.rs | 54 +-
core/partitions/src/types.rs | 118 +-
core/sdk/Cargo.toml | 5 +-
core/sdk/README.md | 8 +-
core/sdk/src/client_provider.rs | 40 +-
.../src/client_wrappers/binary_system_client.rs | 6 +-
.../src/clients/binary_personal_access_tokens.rs | 10 +
core/sdk/src/clients/binary_system.rs | 6 +-
core/sdk/src/clients/binary_users.rs | 10 +
core/sdk/src/clients/client_builder.rs | 20 +-
core/sdk/src/clients/consumer.rs | 448 +-
core/sdk/src/clients/consumer_builder.rs | 18 +-
core/sdk/src/clients/mod.rs | 33 +
core/sdk/src/clients/producer.rs | 8 +-
core/sdk/src/clients/producer_builder.rs | 9 +-
core/sdk/src/clients/producer_dispatcher.rs | 110 +-
core/sdk/src/http/http_client.rs | 18 +-
core/sdk/src/http/system.rs | 4 +-
core/sdk/src/leader_aware.rs | 835 +++-
core/sdk/src/prelude.rs | 9 +-
core/sdk/src/quic/quic_client.rs | 407 +-
.../stream_builder/config/config_iggy_consumer.rs | 55 +-
.../stream_builder/config/config_iggy_producer.rs | 20 +-
core/sdk/src/tcp/tcp_client.rs | 2055 ++++++++-
core/sdk/src/vsr.rs | 71 +-
core/sdk/src/websocket/websocket_client.rs | 453 +-
core/server/Cargo.toml | 11 +-
core/server/Dockerfile | 16 +-
core/server/config.toml | 428 +-
core/server/src/args.rs | 4 +-
core/server/src/auth.rs | 14 +-
core/server/src/bootstrap.rs | 649 ++-
core/server/src/cluster_meta.rs | 8 +-
core/server/src/consumer_group.rs | 28 +-
core/server/src/dispatch.rs | 423 +-
core/server/src/dispatch/authz.rs | 68 +-
core/server/src/http.rs | 65 +-
core/server/src/http/forward.rs | 201 +-
core/server/src/http/handlers.rs | 56 +-
core/server/src/http/jwt.rs | 22 +-
core/server/src/http/metrics.rs | 48 +-
core/server/src/http/reads.rs | 15 +
core/server/src/http/reply.rs | 20 +-
core/server/src/http/submit.rs | 8 +-
core/server/src/http/wire.rs | 144 +-
core/server/src/lib.rs | 8 +
core/server/src/main.rs | 8 +-
core/server/src/partition_helpers.rs | 197 +-
core/server/src/partition_reconciler.rs | 822 +++-
core/server/src/responses.rs | 400 +-
core/server/src/segment_cleaner.rs | 178 +-
core/server/src/segment_recovery.rs | 4856 ++++++++++++++++++--
core/server/src/server_error.rs | 296 +-
core/server/src/session_manager.rs | 11 +-
core/server/src/users.rs | 4 +-
core/server/src/wire.rs | 4 +-
core/server_common/Cargo.toml | 3 +
core/server_common/src/buffer.rs | 4 +-
core/server_common/src/consensus_message.rs | 397 +-
core/server_common/src/executor.rs | 102 +-
core/server_common/src/in_flight.rs | 100 -
core/server_common/src/indexes_mut.rs | 388 --
core/server_common/src/iobuf.rs | 10 +-
core/server_common/src/lib.rs | 29 +-
core/server_common/src/memory_pool.rs | 23 +-
core/server_common/src/messages_batch_mut.rs | 749 ---
core/server_common/src/messages_batch_set.rs | 378 --
core/server_common/src/reactor_yield.rs | 100 +
.../src/segment_storage/index_reader.rs | 360 +-
.../src/segment_storage/index_writer.rs | 62 +-
.../src/segment_storage/messages_reader.rs | 119 +-
.../src/segment_storage/messages_writer.rs | 55 +-
core/server_common/src/segment_storage/mod.rs | 66 +-
.../src/{send_messages2.rs => send_messages.rs} | 1132 ++---
core/server_common/src/sharding/mod.rs | 6 +-
core/server_common/src/sharding/namespace.rs | 222 +-
.../segments.rs => server_common/src/storage.rs} | 23 +-
core/shard/Cargo.toml | 7 +-
core/shard/src/builder.rs | 9 +-
core/shard/src/config.rs | 9 +-
core/shard/src/coordinator.rs | 12 +-
core/shard/src/lib.rs | 947 ++--
core/shard/src/metrics.rs | 169 +-
core/shard/src/router.rs | 323 +-
core/shard_allocator/Cargo.toml | 3 +
core/simulator/Cargo.toml | 11 +-
core/simulator/src/bin/simulator-ui.rs | 4 +-
core/simulator/src/bin/workload-fuzz.rs | 793 +++-
core/simulator/src/bus.rs | 2 +-
core/simulator/src/client.rs | 177 +-
core/simulator/src/deps.rs | 168 +-
core/simulator/src/executor/mod.rs | 12 +-
core/simulator/src/lib.rs | 4616 ++++++++++++-------
core/simulator/src/network.rs | 25 +-
core/simulator/src/packet.rs | 388 +-
core/simulator/src/ready_queue.rs | 4 +-
core/simulator/src/replica.rs | 128 +-
core/simulator/src/seeds.rs | 111 +
core/simulator/src/workload/actions.rs | 6 +-
core/simulator/src/workload/auditor.rs | 66 +-
core/simulator/src/workload/ids.rs | 4 +-
core/simulator/src/workload/invariants.rs | 27 +-
core/simulator/src/workload/mod.rs | 864 +++-
core/simulator/src/workload/ops/change_password.rs | 4 +-
.../src/workload/ops/create_consumer_group.rs | 4 +-
.../src/workload/ops/create_partitions.rs | 12 +-
.../workload/ops/create_personal_access_token.rs | 4 +-
core/simulator/src/workload/ops/create_stream.rs | 15 +-
core/simulator/src/workload/ops/create_topic.rs | 15 +-
core/simulator/src/workload/ops/create_user.rs | 4 +-
.../src/workload/ops/delete_consumer_group.rs | 4 +-
.../src/workload/ops/delete_consumer_offset.rs | 21 +-
.../src/workload/ops/delete_consumer_offset_2.rs | 90 -
.../src/workload/ops/delete_partitions.rs | 4 +-
.../workload/ops/delete_personal_access_token.rs | 4 +-
core/simulator/src/workload/ops/delete_segments.rs | 4 +-
core/simulator/src/workload/ops/delete_stream.rs | 4 +-
core/simulator/src/workload/ops/delete_topic.rs | 4 +-
core/simulator/src/workload/ops/delete_user.rs | 4 +-
core/simulator/src/workload/ops/mod.rs | 32 +-
core/simulator/src/workload/ops/purge_stream.rs | 4 +-
core/simulator/src/workload/ops/purge_topic.rs | 4 +-
core/simulator/src/workload/ops/send_messages.rs | 4 +-
.../src/workload/ops/store_consumer_offset.rs | 27 +-
.../src/workload/ops/store_consumer_offset_2.rs | 112 -
.../src/workload/ops/update_permissions.rs | 4 +-
core/simulator/src/workload/ops/update_stream.rs | 4 +-
core/simulator/src/workload/ops/update_topic.rs | 4 +-
core/simulator/src/workload/ops/update_user.rs | 4 +-
core/simulator/src/workload/options.rs | 143 +-
core/simulator/src/workload/oracle.rs | 505 +-
core/simulator/src/workload/shadow.rs | 16 +-
core/simulator/src/workload/state_checker.rs | 434 ++
core/system_stats/Cargo.toml | 3 +
core/tools/Cargo.toml | 3 +
.../Iggy_SDK.Examples.Basic.Consumer.csproj | 39 +-
.../Iggy_SDK.Examples.Basic.Producer.csproj | 41 +-
...ggy_SDK.Examples.GettingStarted.Consumer.csproj | 35 +-
...ggy_SDK.Examples.GettingStarted.Producer.csproj | 35 +-
.../Iggy_SDK.Examples.Shared.csproj | 33 +-
...gy_SDK.Examples.MessageEnvelope.Consumer.csproj | 41 +-
...gy_SDK.Examples.MessageEnvelope.Producer.csproj | 41 +-
...ggy_SDK.Examples.MessageHeaders.Consumer.csproj | 35 +-
...ggy_SDK.Examples.MessageHeaders.Producer.csproj | 35 +-
.../Iggy_SDK.Examples.NewSdk.Consumer.csproj | 45 +-
.../Iggy_SDK.Examples.NewSdk.Producer.csproj | 41 +-
.../Iggy_SDK.Examples.TcpTls.Consumer.csproj | 35 +-
.../Iggy_SDK.Examples.TcpTls.Producer.csproj | 35 +-
examples/go/go.mod | 3 +
examples/go/go.sum | 8 +
examples/node/eslint.config.ts | 1 -
examples/node/package-lock.json | 19 +-
examples/node/package.json | 4 +-
examples/node/src/basic/consumer.ts | 1 -
examples/node/src/basic/producer.ts | 1 -
examples/node/src/getting-started/consumer.ts | 1 -
examples/node/src/getting-started/producer.ts | 1 -
examples/node/src/index.ts | 1 -
examples/node/src/message-envelope/consumer.ts | 1 -
examples/node/src/message-envelope/producer.ts | 1 -
examples/node/src/message-headers/consumer.ts | 1 -
examples/node/src/message-headers/producer.ts | 1 -
examples/node/src/multi-tenant/consumer.ts | 1 -
examples/node/src/multi-tenant/producer.ts | 1 -
examples/node/src/sink-data-producer/producer.ts | 1 -
examples/node/src/stream-builder/example.ts | 1 -
examples/node/src/tcp-tls/consumer.ts | 1 -
examples/node/src/tcp-tls/producer.ts | 1 -
examples/node/src/utils/index.ts | 1 -
examples/python/basic/consumer.py | 4 +-
examples/python/getting-started/consumer.py | 3 +
examples/python/message-headers/common.py | 7 +-
.../message-headers/plain-headers/consumer.py | 2 +-
.../message-headers/typed-headers/consumer.py | 2 +-
examples/python/pylock.toml | 62 +-
examples/python/uv.lock | 40 +-
examples/rust/Cargo.toml | 3 +
.../stream-builder/stream-consumer-config/main.rs | 4 +-
.../stream-builder/stream-producer-config/main.rs | 2 +-
foreign/cpp/.bazelrc | 5 +-
foreign/cpp/Cargo.toml | 2 +-
foreign/cpp/MODULE.bazel | 4 +-
foreign/cpp/MODULE.bazel.lock | 21 +-
foreign/cpp/README.md | 6 -
foreign/cpp/include/iggy.hpp | 917 +++-
foreign/cpp/src/client.cpp | 200 +
foreign/cpp/src/client.rs | 197 +-
foreign/cpp/src/lib.rs | 89 +-
foreign/cpp/src/type_conversion.rs | 146 +-
foreign/cpp/tests/e2e/client.cpp | 1606 ++++++-
foreign/cpp/tests/e2e/test_helpers.hpp | 202 +-
foreign/cpp/tests/e2e/topic.cpp | 10 +-
foreign/cpp/tests/unit/unit_tests.cpp | 169 +-
foreign/csharp/Benchmarks/Benchmarks.csproj | 35 +-
foreign/csharp/Directory.Build.props | 31 +-
foreign/csharp/Directory.Packages.props | 45 +-
.../Iggy_SDK.Tests.BDD/Iggy_SDK.Tests.BDD.csproj | 31 +-
.../Fixtures/IggyServerFixture.cs | 18 +-
.../Iggy_SDK.Tests.Integration/HeartbeatTests.cs | 166 +
.../Iggy_SDK.Tests.Integration.csproj | 31 +-
.../Iggy_SDK.Tests.Integration/OptionsTests.cs | 189 +
.../Iggy_SDK/Configuration/AutoLoginSettings.cs | 40 +-
.../Configuration/IggyClientConfigurator.cs | 9 +
.../Iggy_SDK/Configuration/ReconnectionSettings.cs | 8 +-
.../Iggy_SDK/ConnectionStream/IConnectionStream.cs | 26 -
.../ConnectionStream/TcpConnectionStream.cs | 53 -
.../Iggy_SDK/Consumers/IggyConsumer.Rented.cs | 3 +-
foreign/csharp/Iggy_SDK/Consumers/IggyConsumer.cs | 99 +-
.../Iggy_SDK/Consumers/IggyConsumerBuilder.cs | 56 +-
.../Iggy_SDK/Consumers/IggyConsumerBuilderOfT.cs | 3 +-
.../Iggy_SDK/Consumers/IggyConsumerConfig.cs | 15 +-
foreign/csharp/Iggy_SDK/Contracts/StatsResponse.cs | 1 -
.../csharp/Iggy_SDK/Contracts/StreamResponse.cs | 1 -
.../csharp/Iggy_SDK/Contracts/Tcp/TcpContracts.cs | 108 +-
foreign/csharp/Iggy_SDK/Contracts/TopicResponse.cs | 1 -
foreign/csharp/Iggy_SDK/Enums/IdKind.cs | 1 -
foreign/csharp/Iggy_SDK/Enums/PartitioningKind.cs | 1 -
.../csharp/Iggy_SDK/Factory/IggyClientFactory.cs | 9 +
.../Implementations/TcpMessageStream.Vsr.cs | 590 +--
.../IggyClient/Implementations/TcpMessageStream.cs | 850 ++--
foreign/csharp/Iggy_SDK/Iggy_SDK.csproj | 33 +-
foreign/csharp/Iggy_SDK/Mappers/BinaryMapper.cs | 225 +-
.../Messages/BatchWireFormat.cs} | 21 +-
.../Iggy_SDK/Publishers/IggyPublisherBuilder.cs | 56 +-
.../Iggy_SDK/Publishers/IggyPublisherBuilderOfT.cs | 3 +-
.../Iggy_SDK/Publishers/IggyPublisherConfig.cs | 15 +-
.../Utils/ArrayPoolHelper.cs} | 34 +-
foreign/csharp/Iggy_SDK/Utils/BufferSizes.cs | 23 -
foreign/csharp/Iggy_SDK/Utils/CommandCodes.cs | 2 -
.../Iggy_SDK/Utils/TcpMessageStreamHelpers.cs | 23 +-
.../Iggy_SDK/Vsr/{Command2.cs => Command.cs} | 2 +-
foreign/csharp/Iggy_SDK/Vsr/ConsensusSession.cs | 19 +
.../{Command2.cs => ISessionGenerationProvider.cs} | 14 +-
foreign/csharp/Iggy_SDK/Vsr/VsrConnection.cs | 372 ++
foreign/csharp/Iggy_SDK/Vsr/VsrHeader.cs | 10 +-
foreign/csharp/Iggy_SDK/Vsr/VsrOperation.cs | 17 +-
foreign/csharp/Iggy_SDK/Vsr/VsrReplyDecoder.cs | 4 +-
.../ClientTests/IggyClientFactoryTests.cs | 46 +
.../ConsumerSessionGenerationTests.cs | 245 +
.../ConsumerTests/IggyConsumerBuilderTests.cs | 22 +
.../ConsumerTests/RentedConsumerTests.cs | 4 +-
.../MessageBatchGoldenVectorTests.cs | 182 +
.../csharp/Iggy_SDK_Tests/Iggy_SDK_Tests.csproj | 35 +-
.../Iggy_SDK_Tests/MapperTests/BinaryMapper.cs | 95 +-
.../PublisherTests/MessageEncryptionTests.cs | 16 +-
.../UtilityTests/SlicedMemoryOwnerTests.cs | 85 -
.../csharp/Iggy_SDK_Tests/Utils/BinaryFactory.cs | 61 +-
.../VsrTests/ConsensusSessionTests.cs | 20 +
.../Iggy_SDK_Tests/VsrTests/DialCandidatesTests.cs | 79 +
.../VsrTests/EndpointFailoverTests.cs | 702 +++
.../Iggy_SDK_Tests/VsrTests/VsrHeaderTests.cs | 12 +-
.../Iggy_SDK_Tests/VsrTests/VsrOperationTests.cs | 8 +-
.../VsrTests/VsrProtocolDriftTests.cs | 8 +-
.../VsrTests/VsrReplyDecoderTests.cs | 4 +-
.../Iggy_SDK_Tests/VsrTests/VsrTestPayloads.cs | 4 +-
foreign/csharp/NOTICE | 2 +-
foreign/csharp/README.md | 66 +-
foreign/csharp/Shared/Shared.csproj | 31 +-
foreign/csharp/scripts/pack.sh | 1 -
foreign/go/NOTICE | 2 +-
foreign/go/README.md | 6 -
.../binary_response_deserializer.go | 110 +-
.../binary_response_deserializer_test.go | 15 +-
.../vsr_response_deserializer_test.go | 121 +-
foreign/go/client/tcp/tcp_connect_test.go | 15 +-
foreign/go/client/tcp/tcp_core.go | 551 ++-
foreign/go/client/tcp/tcp_core_review_test.go | 13 +-
foreign/go/client/tcp/tcp_failover_test.go | 846 ++++
.../go/client/tcp/tcp_session_credentials_test.go | 66 +
foreign/go/client/tcp/tcp_session_management.go | 182 +-
foreign/go/contracts/message_header.go | 49 +-
foreign/go/contracts/version.go | 2 +-
foreign/go/errors/errors.yaml | 220 +-
foreign/go/errors/errors_gen.go | 680 ++-
foreign/go/go.mod | 3 +
foreign/go/go.sum | 8 +
foreign/go/internal/batch/batch.go | 129 +
foreign/go/internal/command/code.go | 102 +-
foreign/go/internal/command/message.go | 84 +-
foreign/go/internal/command/message_test.go | 190 +-
foreign/go/internal/command/offset.go | 14 +-
foreign/go/internal/vsr/operation.go | 65 +-
foreign/go/internal/vsr/operation_test.go | 10 +-
foreign/go/internal/vsr/protocol_parity_test.go | 12 +-
foreign/go/tests/e2e_helpers_test.go | 14 +-
foreign/go/tests/e2e_test.go | 10 +-
foreign/java/LICENSE | 2 +-
foreign/java/NOTICE | 2 +-
foreign/java/README.md | 6 -
foreign/java/bench/src/main/resources/logback.xml | 31 +-
foreign/java/dev-support/checkstyle/checkstyle.xml | 35 +-
.../java/dev-support/checkstyle/suppressions.xml | 31 +-
.../docker/Dockerfile.flink2_10-java21 | 12 -
foreign/java/gradle/libs.versions.toml | 6 +
foreign/java/java-sdk/build.gradle.kts | 5 +-
.../client/async/PersonalAccessTokensClient.java | 16 +-
.../iggy/client/async/tcp/AsyncIggyTcpClient.java | 408 +-
.../iggy/client/async/tcp/AsyncTcpConnection.java | 116 +-
.../client/async/tcp/ConsumerOffsetsTcpClient.java | 3 +
.../iggy/client/async/tcp/LeaderAwareness.java | 109 +-
.../iggy/client/async/tcp/LoginRoutingHook.java | 6 +
.../iggy/client/async/tcp/MessagesTcpClient.java | 30 +-
.../iggy/client/async/tcp/ReconnectPlan.java | 17 +-
.../iggy/client/async/tcp/UsersTcpClient.java | 1 +
.../iggy/client/async/tcp/vsr/VsrHeaders.java | 2 +-
.../iggy/client/async/tcp/vsr/VsrOperation.java | 12 +-
.../client/async/tcp/vsr/VsrResponseHandler.java | 11 +-
.../blocking/PersonalAccessTokensClient.java | 21 +
.../exception/IggyAuthenticationException.java | 6 +-
.../iggy/exception/IggyConflictException.java | 9 +-
.../org/apache/iggy/exception/IggyErrorCode.java | 84 +-
.../exception/IggyResourceNotFoundException.java | 4 +-
.../iggy/exception/IggyValidationException.java | 11 +-
.../org/apache/iggy/message/MessageHeader.java | 6 +-
.../org/apache/iggy/serde/BytesDeserializer.java | 128 +-
.../org/apache/iggy/serde/BytesSerializer.java | 156 +-
.../apache/iggy/client/BaseIntegrationTest.java | 11 +-
.../AsyncIggyTcpClientEndpointFailoverTest.java | 562 +++
.../AsyncIggyTcpClientTransientFailoverTest.java | 323 +-
.../tcp/AsyncTcpConnectionConcurrencyTest.java | 4 +-
.../iggy/client/async/tcp/LeaderAwarenessTest.java | 141 +-
.../iggy/client/async/tcp/ReconnectPlanTest.java | 18 -
.../async/tcp/vsr/VsrResponseHandlerTest.java | 10 +-
.../blocking/PersonalAccessTokensBaseTest.java | 8 +-
.../client/blocking/tcp/BytesSerializerTest.java | 102 -
.../exception/IggyAuthenticationExceptionTest.java | 12 +-
.../iggy/exception/IggyConflictExceptionTest.java | 18 +-
.../apache/iggy/exception/IggyErrorCodeTest.java | 84 +-
.../IggyResourceNotFoundExceptionTest.java | 8 +-
.../exception/IggyValidationExceptionTest.java | 22 +-
.../java/org/apache/iggy/message/MessageTest.java | 4 +-
.../apache/iggy/serde/BytesDeserializerTest.java | 92 -
.../iggy/serde/MessagesBatchWireFormatTest.java | 193 +
.../java-sdk/src/test/resources/logback-test.xml | 35 +-
foreign/node/NOTICE | 2 +-
foreign/node/README.md | 53 +-
foreign/node/commitlint.config.js | 34 +-
foreign/node/eslint.config.mjs | 34 +-
foreign/node/package-lock.json | 673 +--
foreign/node/package.json | 9 +-
foreign/node/scripts/check-vsr-protocol.mjs | 22 +-
foreign/node/src/bdd/auth.ts | 1 -
foreign/node/src/bdd/message.ts | 1 -
foreign/node/src/bdd/stream.ts | 1 -
foreign/node/src/bdd/topic.ts | 1 -
foreign/node/src/bdd/world.ts | 1 -
foreign/node/src/client.e2e.ts | 1 -
foreign/node/src/client/client.config.test.ts | 79 +
foreign/node/src/client/client.config.ts | 56 +-
.../src/client/client.connection-string.test.ts | 310 ++
.../node/src/client/client.connection-string.ts | 226 +
foreign/node/src/client/client.connection.test.ts | 508 +-
foreign/node/src/client/client.connection.ts | 338 +-
foreign/node/src/client/client.debug.ts | 1 -
foreign/node/src/client/client.frame.test.ts | 4 +-
foreign/node/src/client/client.socket.test.ts | 631 ++-
foreign/node/src/client/client.socket.ts | 443 +-
foreign/node/src/client/client.ts | 58 +-
foreign/node/src/client/client.type.ts | 47 +-
foreign/node/src/client/client.utils.test.ts | 1 -
foreign/node/src/client/client.utils.ts | 1 -
foreign/node/src/client/index.ts | 2 +-
.../theme/mod.rs => foreign/node/src/constant.ts | 3 +-
foreign/node/src/debug-send.ts | 1 -
foreign/node/src/debug.ts | 5 +-
foreign/node/src/duration.utils.test.ts | 180 +
foreign/node/src/duration.utils.ts | 393 ++
foreign/node/src/e2e/tcp.client.e2e.ts | 1 -
foreign/node/src/e2e/tcp.cluster.e2e.ts | 1 -
foreign/node/src/e2e/tcp.connection-string.e2e.ts | 146 +
foreign/node/src/e2e/tcp.consumer-group.e2e.ts | 1 -
foreign/node/src/e2e/tcp.consumer-stream.e2e.ts | 1 -
foreign/node/src/e2e/tcp.parallel.e2e.ts | 1 -
foreign/node/src/e2e/tcp.raw.e2e.ts | 1 -
foreign/node/src/e2e/tcp.send-message.e2e.ts | 1 -
foreign/node/src/e2e/tcp.stream.e2e.ts | 1 -
foreign/node/src/e2e/tcp.system.e2e.ts | 1 -
foreign/node/src/e2e/tcp.token.e2e.ts | 1 -
foreign/node/src/e2e/tcp.topic.e2e.ts | 1 -
foreign/node/src/e2e/tcp.user.e2e.ts | 1 -
foreign/node/src/e2e/test-client.utils.ts | 1 -
foreign/node/src/e2e/tls.system.e2e.ts | 65 +-
foreign/node/src/examples/stream-file-to-topic.ts | 1 -
foreign/node/src/examples/stream-topic-to-file.ts | 1 -
foreign/node/src/examples/utils.ts | 1 -
foreign/node/src/index.ts | 1 -
foreign/node/src/stream/consumer-stream.ts | 7 +-
foreign/node/src/stream/index.ts | 1 -
foreign/node/src/tcp.e2e.ts | 1 -
foreign/node/src/tcp.sm.utils.ts | 1 -
foreign/node/src/tls.system.e2e.ts | 1 -
foreign/node/src/type.utils.ts | 1 -
foreign/node/src/wire/client/client.utils.ts | 1 -
foreign/node/src/wire/client/get-client.command.ts | 1 -
.../node/src/wire/client/get-clients.command.ts | 1 -
foreign/node/src/wire/client/get-me.command.ts | 1 -
foreign/node/src/wire/client/index.ts | 1 -
foreign/node/src/wire/cluster/cluster.type.ts | 1 -
foreign/node/src/wire/cluster/cluster.utils.ts | 1 -
.../wire/cluster/get-cluster-metadata.command.ts | 1 -
foreign/node/src/wire/cluster/index.ts | 1 -
foreign/node/src/wire/command-set.test.ts | 1 -
foreign/node/src/wire/command-set.ts | 1 -
foreign/node/src/wire/command.code.ts | 3 -
foreign/node/src/wire/command.utils.ts | 1 -
.../consumer-group/create-group.command.test.ts | 1 -
.../wire/consumer-group/create-group.command.ts | 1 -
.../wire/consumer-group/delete-group.command.ts | 1 -
.../consumer-group/ensure-group.virtual.command.ts | 1 -
.../src/wire/consumer-group/get-group.command.ts | 1 -
.../src/wire/consumer-group/get-groups.command.ts | 1 -
.../src/wire/consumer-group/group.command.test.ts | 1 -
.../node/src/wire/consumer-group/group.utils.ts | 1 -
foreign/node/src/wire/consumer-group/index.ts | 1 -
.../src/wire/consumer-group/join-group.command.ts | 1 -
.../src/wire/consumer-group/leave-group.command.ts | 1 -
.../wire/consumer-group/sync-group.command.test.ts | 1 -
.../src/wire/consumer-group/sync-group.command.ts | 1 -
foreign/node/src/wire/error.code.test.ts | 29 +-
foreign/node/src/wire/error.code.ts | 103 +-
foreign/node/src/wire/error.utils.ts | 1 -
foreign/node/src/wire/identifier.utils.test.ts | 1 -
foreign/node/src/wire/identifier.utils.ts | 1 -
foreign/node/src/wire/index.ts | 1 -
.../wire/message/flush-unsaved-buffers.command.ts | 1 -
foreign/node/src/wire/message/header.type.ts | 1 -
foreign/node/src/wire/message/header.utils.test.ts | 1 -
foreign/node/src/wire/message/header.utils.ts | 1 -
foreign/node/src/wire/message/iggy-header.utils.ts | 212 +-
foreign/node/src/wire/message/index.ts | 1 -
.../node/src/wire/message/message-batch.test.ts | 217 +
foreign/node/src/wire/message/message.utils.ts | 193 +-
.../node/src/wire/message/partitioning.utils.ts | 1 -
.../src/wire/message/poll-messages.command.test.ts | 3 +-
.../node/src/wire/message/poll-messages.command.ts | 1 -
foreign/node/src/wire/message/poll.utils.ts | 128 +-
.../src/wire/message/send-messages.command.test.ts | 5 +-
.../node/src/wire/message/send-messages.command.ts | 1 -
foreign/node/src/wire/number.utils.ts | 1 -
.../node/src/wire/offset/delete-offset.command.ts | 5 +-
foreign/node/src/wire/offset/get-offset.command.ts | 1 -
foreign/node/src/wire/offset/index.ts | 1 -
foreign/node/src/wire/offset/offset.utils.ts | 27 +-
.../node/src/wire/offset/store-offset.command.ts | 1 -
foreign/node/src/wire/options.utils.test.ts | 1 -
foreign/node/src/wire/options.utils.ts | 1 -
.../src/wire/partition/create-partition.command.ts | 1 -
.../src/wire/partition/delete-partition.command.ts | 1 -
foreign/node/src/wire/partition/index.ts | 1 -
.../src/wire/partition/partition.utils.test.ts | 1 -
foreign/node/src/wire/partition/partition.utils.ts | 1 -
.../src/wire/segment/delete-segments.command.ts | 1 -
foreign/node/src/wire/segment/index.ts | 1 -
foreign/node/src/wire/segment/segment.utils.ts | 1 -
foreign/node/src/wire/serialize.utils.ts | 1 -
foreign/node/src/wire/session/index.ts | 1 -
.../wire/session/login-with-token.command.test.ts | 1 -
.../src/wire/session/login-with-token.command.ts | 1 -
.../node/src/wire/session/login.command.test.ts | 1 -
foreign/node/src/wire/session/login.command.ts | 1 -
foreign/node/src/wire/session/login.utils.ts | 1 -
foreign/node/src/wire/session/logout.command.ts | 1 -
.../src/wire/stream/create-stream.command.test.ts | 1 -
.../node/src/wire/stream/create-stream.command.ts | 1 -
.../node/src/wire/stream/delete-stream.command.ts | 1 -
.../wire/stream/ensure-stream.virtual.command.ts | 1 -
foreign/node/src/wire/stream/get-stream.command.ts | 1 -
.../node/src/wire/stream/get-streams.command.ts | 1 -
foreign/node/src/wire/stream/index.ts | 1 -
.../node/src/wire/stream/purge-stream.command.ts | 1 -
foreign/node/src/wire/stream/stream.utils.ts | 1 -
.../node/src/wire/stream/update-stream.command.ts | 1 -
.../src/wire/system/describe-options.command.ts | 1 -
foreign/node/src/wire/system/get-stats.command.ts | 1 -
foreign/node/src/wire/system/index.ts | 1 -
foreign/node/src/wire/system/ping.command.ts | 1 -
.../src/wire/token/create-token.command.test.ts | 1 -
.../node/src/wire/token/create-token.command.ts | 1 -
.../src/wire/token/delete-token.command.test.ts | 1 -
.../node/src/wire/token/delete-token.command.ts | 1 -
foreign/node/src/wire/token/get-tokens.command.ts | 1 -
foreign/node/src/wire/token/index.ts | 1 -
foreign/node/src/wire/token/token.utils.ts | 1 -
.../src/wire/topic/create-topic.command.test.ts | 1 -
.../node/src/wire/topic/create-topic.command.ts | 1 -
.../node/src/wire/topic/delete-topic.command.ts | 1 -
.../src/wire/topic/ensure-topic.virtual.command.ts | 1 -
foreign/node/src/wire/topic/get-topic.command.ts | 1 -
foreign/node/src/wire/topic/get-topics.command.ts | 1 -
foreign/node/src/wire/topic/index.ts | 1 -
foreign/node/src/wire/topic/purge-topic.command.ts | 1 -
foreign/node/src/wire/topic/topic.utils.test.ts | 1 -
foreign/node/src/wire/topic/topic.utils.ts | 1 -
.../node/src/wire/topic/update-topic.command.ts | 1 -
.../node/src/wire/user/change-password.command.ts | 1 -
.../node/src/wire/user/create-user.command.test.ts | 1 -
foreign/node/src/wire/user/create-user.command.ts | 1 -
foreign/node/src/wire/user/delete-user.command.ts | 1 -
foreign/node/src/wire/user/get-user.command.ts | 1 -
foreign/node/src/wire/user/get-users.command.ts | 1 -
foreign/node/src/wire/user/index.ts | 1 -
.../node/src/wire/user/permissions.utils.test.ts | 1 -
foreign/node/src/wire/user/permissions.utils.ts | 1 -
.../src/wire/user/update-permissions.command.ts | 1 -
foreign/node/src/wire/user/update-user.command.ts | 1 -
foreign/node/src/wire/user/user.utils.ts | 1 -
foreign/node/src/wire/uuid.utils.ts | 1 -
foreign/node/src/wire/vsr/header.test.ts | 6 +-
foreign/node/src/wire/vsr/header.ts | 7 +-
foreign/node/src/wire/vsr/index.ts | 1 -
foreign/node/src/wire/vsr/operation.test.ts | 8 +-
foreign/node/src/wire/vsr/operation.ts | 11 +-
foreign/node/src/wire/vsr/register.ts | 1 -
foreign/node/src/wire/vsr/reply.test.ts | 8 +-
foreign/node/src/wire/vsr/reply.ts | 7 +-
foreign/node/src/wire/vsr/session.ts | 1 -
foreign/node/src/wire/vsr/vsr.test.ts | 3 +-
foreign/php/Cargo.toml | 2 +-
foreign/php/Dockerfile.test | 2 +-
foreign/php/NOTICE | 2 +-
foreign/php/composer.json | 2 +-
foreign/php/phpunit.xml.dist | 31 +-
foreign/php/src/client.rs | 15 +-
foreign/php/src/consumer.rs | 25 +-
foreign/php/tests/IggySdkTest.php | 58 +-
foreign/python/Cargo.toml | 4 +-
foreign/python/Dockerfile.test | 11 -
foreign/python/NOTICE | 2 +-
foreign/python/README.md | 6 -
foreign/python/apache_iggy.pyi | 126 +-
foreign/python/pylock.toml | 134 +-
foreign/python/pyproject.toml | 6 +-
foreign/python/src/client.rs | 57 +-
foreign/python/src/config.rs | 40 +-
foreign/python/src/consumer.rs | 155 +-
foreign/python/src/duration.rs | 16 +-
foreign/python/src/identifier.rs | 20 +-
foreign/python/src/lib.rs | 3 +-
foreign/python/src/stream.rs | 26 +-
foreign/python/src/topic.rs | 23 +-
foreign/python/tests/__init__.py | 1 +
foreign/python/tests/conftest.py | 56 +-
foreign/python/tests/test_client_config.py | 77 +-
foreign/python/tests/test_consumer_group.py | 118 +
foreign/python/tests/test_message_operations.py | 377 ++
foreign/python/tests/test_stream.py | 34 +-
foreign/python/tests/test_tls.py | 3 +-
foreign/python/uv.lock | 754 +--
gateways/README.md | 9 +
{core/message_bus => gateways/kafka}/Cargo.toml | 52 +-
gateways/kafka/README.md | 63 +
gateways/kafka/docs/MANUAL_TESTING.md | 307 ++
gateways/kafka/docs/SCOPE.md | 138 +
gateways/kafka/docs/TEST_SUITE.md | 66 +
gateways/kafka/docs/kafka_api_keys_reference.md | 316 ++
gateways/kafka/scripts/ci-wire-fixtures.sh | 57 +
gateways/kafka/src/error.rs | 45 +
.../steps/mod.rs => gateways/kafka/src/lib.rs | 12 +-
gateways/kafka/src/main.rs | 240 +
gateways/kafka/src/protocol/api.rs | 637 +++
gateways/kafka/src/protocol/bounds_guard.rs | 906 ++++
gateways/kafka/src/protocol/header.rs | 40 +
.../theme => gateways/kafka/src/protocol}/mod.rs | 5 +-
gateways/kafka/src/protocol/responses.rs | 318 ++
gateways/kafka/src/server.rs | 896 ++++
gateways/kafka/tests/api_handler_tests.rs | 989 ++++
gateways/kafka/tests/broker_advertise_tests.rs | 117 +
gateways/kafka/tests/common/codec.rs | 292 ++
gateways/kafka/tests/common/fixtures.rs | 91 +
.../mod.rs => gateways/kafka/tests/common/scope.rs | 33 +-
gateways/kafka/tests/common/server.rs | 68 +
gateways/kafka/tests/common/tcp.rs | 258 ++
gateways/kafka/tests/common/wire.rs | 447 ++
.../kafka/tests/fixtures_canary_tests.rs | 36 +-
gateways/kafka/tests/golden_wire_fixtures_tests.rs | 122 +
gateways/kafka/tests/header_tests.rs | 282 ++
gateways/kafka/tests/listener_robustness_tests.rs | 624 +++
gateways/kafka/tests/response_negative_tests.rs | 277 ++
gateways/kafka/tests/server_e2e_tests.rs | 451 ++
gateways/kafka/tests/server_integration_tests.rs | 129 +
gateways/kafka/tests/version_firewall_tests.rs | 799 ++++
.../kafka/tools/kafka-tool}/Cargo.toml | 17 +-
gateways/kafka/tools/kafka-tool/README.md | 251 +
gateways/kafka/tools/kafka-tool/src/main.rs | 864 ++++
gateways/kafka/tools/kafka-tool/src/response.rs | 389 ++
.../tools/kafka-tool/tests/generate_cli_tests.rs | 82 +
helm/charts/iggy/README.md | 3 +-
helm/charts/iggy/templates/servicemonitor.yaml | 4 +
helm/charts/iggy/values.yaml | 7 +
licenserc.toml | 28 +-
rust-toolchain.toml | 2 +-
scripts/ci/apt-install.sh | 78 +
scripts/ci/coverage-baseline-affected.sh | 2 +-
scripts/ci/license-headers.sh | 27 +-
scripts/ci/render-node-licenses.mjs | 4 +-
scripts/dashboard/build_release.sh | 1 -
scripts/dashboard/run_dev.sh | 1 -
scripts/prepare-release.sh | 7 +-
scripts/run-bdd-tests.sh | 36 +-
web/Dockerfile | 12 -
web/package-lock.json | 594 +--
web/package.json | 26 +-
web/src/app.html | 31 +-
web/src/lib/components/AppToasts.svelte | 35 +-
web/src/lib/components/Breadcrumbs.svelte | 35 +-
web/src/lib/components/Button.svelte | 31 +-
web/src/lib/components/Checkbox.svelte | 35 +-
web/src/lib/components/Combobox.svelte | 35 +-
.../components/DeleteButtonWithConfirmation.svelte | 31 +-
.../components/DropdownMenu/DropdownMenu.svelte | 31 +-
web/src/lib/components/DurationInput.svelte | 35 +-
web/src/lib/components/FixedSvelteComponent.svelte | 35 +-
web/src/lib/components/Header.svelte | 31 +-
web/src/lib/components/Icon.svelte | 31 +-
web/src/lib/components/Input.svelte | 31 +-
.../lib/components/Layouts/SettingsLayout.svelte | 31 +-
web/src/lib/components/Listbox.svelte | 31 +-
web/src/lib/components/Loader.svelte | 35 +-
web/src/lib/components/LoadingIndicator.svelte | 31 +-
web/src/lib/components/Logo/Logo.svelte | 31 +-
web/src/lib/components/Logo/LogoMark.svelte | 31 +-
web/src/lib/components/Logo/LogoType.svelte | 31 +-
.../MessageDecoder/MessageDecoder.svelte | 35 +-
web/src/lib/components/ModalConfirmation.svelte | 31 +-
.../components/Modals/AddPartitionsModal.svelte | 31 +-
.../lib/components/Modals/AddStreamModal.svelte | 31 +-
web/src/lib/components/Modals/AddTopicModal.svelte | 35 +-
web/src/lib/components/Modals/AddUserModal.svelte | 35 +-
web/src/lib/components/Modals/AppModals.svelte | 31 +-
.../components/Modals/DeletePartitionsModal.svelte | 35 +-
.../lib/components/Modals/DeleteUserModal.svelte | 35 +-
web/src/lib/components/Modals/EditUserModal.svelte | 35 +-
.../Modals/EditUserPermissionsModal.svelte | 35 +-
.../lib/components/Modals/InspectMessage.svelte | 35 +-
web/src/lib/components/Modals/ModalBase.svelte | 31 +-
.../components/Modals/StreamSettingsModal.svelte | 35 +-
.../components/Modals/TopicSettingsModal.svelte | 35 +-
web/src/lib/components/Navbar.svelte | 31 +-
web/src/lib/components/Paginator.svelte | 35 +-
web/src/lib/components/PasswordInput.svelte | 31 +-
web/src/lib/components/PeriodicInvalidator.svelte | 31 +-
web/src/lib/components/PermissionsManager.svelte | 35 +-
.../lib/components/PreventEventsPropagation.svelte | 31 +-
web/src/lib/components/RangeInput.svelte | 31 +-
.../RouteComponents/Settings/UsersTab.svelte | 35 +-
.../Settings/UsersTabActions.svelte | 31 +-
web/src/lib/components/SegmentedControl.svelte | 31 +-
web/src/lib/components/Select.svelte | 31 +-
web/src/lib/components/SlimSortableList.svelte | 35 +-
web/src/lib/components/SortableList.svelte | 35 +-
web/src/lib/components/StopPropagation.svelte | 31 +-
web/src/lib/components/ThemeController.svelte | 31 +-
web/src/lib/components/Toggler.svelte | 35 +-
web/src/routes/+error.svelte | 31 +-
web/src/routes/+layout.svelte | 31 +-
web/src/routes/auth/+layout.svelte | 31 +-
web/src/routes/auth/logout/+page.svelte | 31 +-
web/src/routes/auth/sign-in/+page.svelte | 35 +-
web/src/routes/dashboard/+layout.svelte | 35 +-
web/src/routes/dashboard/clients/+page.svelte | 31 +-
web/src/routes/dashboard/logs/+page.svelte | 31 +-
web/src/routes/dashboard/overview/+page.svelte | 35 +-
.../routes/dashboard/settings/server/+page.svelte | 31 +-
.../dashboard/settings/terminal/+page.svelte | 31 +-
.../routes/dashboard/settings/users/+page.svelte | 35 +-
.../routes/dashboard/settings/webUI/+page.svelte | 31 +-
web/src/routes/dashboard/streams/+layout.svelte | 31 +-
web/src/routes/dashboard/streams/+page.svelte | 31 +-
.../dashboard/streams/[streamId=i32]/+page.svelte | 31 +-
.../streams/[streamId=i32]/topics/+page.svelte | 31 +-
.../topics/[topicId=i32]/+page.svelte | 31 +-
.../partitions/[partitionId=i32]/+page.svelte | 31 +-
.../[partitionId=i32]/messages/+page.svelte | 35 +-
1086 files changed, 75715 insertions(+), 21018 deletions(-)
delete mode 100644 DISCLAIMER
copy bdd/rust/tests/{basic_messaging.rs => stream_crud.rs} (93%)
create mode 100644 bdd/scenarios/stream_crud.feature
create mode 100644 core/binary_protocol/src/batch.rs
delete mode 100644 core/binary_protocol/src/message_layout.rs
delete mode 100644 core/binary_protocol/src/message_view.rs
delete mode 100644 core/binary_protocol/src/requests/consumer_offsets/delete_consumer_offset_2.rs
delete mode 100644 core/binary_protocol/src/requests/consumer_offsets/store_consumer_offset_2.rs
delete mode 100644 core/binary_protocol/src/responses/consumer_offsets/delete_consumer_offset_2.rs
delete mode 100644 core/binary_protocol/src/responses/consumer_offsets/store_consumer_offset_2.rs
delete mode 100644 core/common/src/types/message/message_view_mut.rs
delete mode 100644 core/configs/src/common/cache_indexes.rs
create mode 100644 core/connectors/runtime/src/state/http.rs
copy core/connectors/sinks/{s3_sink => redshift_sink}/Cargo.toml (72%)
create mode 100644 core/connectors/sinks/redshift_sink/README.md
copy core/connectors/sinks/{postgres_sink => redshift_sink}/config.toml (70%)
create mode 100644 core/connectors/sinks/redshift_sink/src/config.rs
create mode 100644 core/connectors/sinks/redshift_sink/src/lib.rs
create mode 100644 core/integration/src/harness/disk.rs
create mode 100644 core/integration/tests/cluster/client_table_adversarial.rs
create mode 100644 core/integration/tests/cluster/crash_durability.rs
create mode 100644 core/integration/tests/cluster/crash_offset_reuse.rs
create mode 100644 core/integration/tests/cluster/crash_recovery_corruption.rs
create mode 100644 core/integration/tests/cluster/failover_client_continuity.rs
create mode 100644 core/integration/tests/cluster/fast_primary_rejoin.rs
create mode 100644 core/integration/tests/cluster/partition_primary_routing.rs
create mode 100644 core/integration/tests/cluster/staggered_bootstrap.rs
create mode 100644 core/integration/tests/connectors/doris/doris_stream_load_format_bench.rs
create mode 100644 core/integration/tests/connectors/fixtures/redshift/container.rs
copy core/integration/tests/connectors/fixtures/{clickhouse => redshift}/mod.rs (80%)
create mode 100644 core/integration/tests/connectors/fixtures/redshift/redshift_mock/ddl.rs
create mode 100644 core/integration/tests/connectors/fixtures/redshift/redshift_mock/dml.rs
create mode 100644 core/integration/tests/connectors/fixtures/redshift/redshift_mock/dql.rs
create mode 100644 core/integration/tests/connectors/fixtures/redshift/redshift_mock/handler.rs
create mode 100644 core/integration/tests/connectors/fixtures/redshift/redshift_mock/load.rs
copy core/{bench/dashboard/frontend/src/components/theme => integration/tests/connectors/fixtures/redshift/redshift_mock}/mod.rs (88%)
create mode 100644 core/integration/tests/connectors/fixtures/redshift/redshift_mock/parser.rs
create mode 100644 core/integration/tests/connectors/fixtures/redshift/redshift_mock/util.rs
create mode 100644 core/integration/tests/connectors/fixtures/redshift/sink.rs
copy core/integration/tests/connectors/{http => redshift}/mod.rs (97%)
create mode 100644 core/integration/tests/connectors/redshift/redshift_sink.rs
copy core/integration/tests/connectors/{delta => redshift}/sink.toml (94%)
create mode 100644 core/integration/tests/connectors/runtime/http_state.rs
copy core/integration/tests/connectors/runtime/{benchmark_json.toml => http_state.toml} (73%)
copy core/integration/tests/connectors/runtime/{benchmark_config => http_state_config}/random_source.toml (89%)
create mode 100644 core/integration/tests/sdk/disconnect_relogin.rs
create mode 100644 core/metadata/src/stm/id_slab.rs
delete mode 100644 core/server_common/src/in_flight.rs
delete mode 100644 core/server_common/src/indexes_mut.rs
delete mode 100644 core/server_common/src/messages_batch_mut.rs
delete mode 100644 core/server_common/src/messages_batch_set.rs
create mode 100644 core/server_common/src/reactor_yield.rs
rename core/server_common/src/{send_messages2.rs => send_messages.rs} (55%)
copy core/{metadata/src/permissioner/permissioner_rules/segments.rs => server_common/src/storage.rs} (70%)
create mode 100644 core/simulator/src/seeds.rs
delete mode 100644 core/simulator/src/workload/ops/delete_consumer_offset_2.rs
delete mode 100644 core/simulator/src/workload/ops/store_consumer_offset_2.rs
create mode 100644 core/simulator/src/workload/state_checker.rs
create mode 100644 foreign/cpp/src/client.cpp
create mode 100644 foreign/csharp/Iggy_SDK.Tests.Integration/HeartbeatTests.cs
create mode 100644 foreign/csharp/Iggy_SDK.Tests.Integration/OptionsTests.cs
delete mode 100644 foreign/csharp/Iggy_SDK/ConnectionStream/IConnectionStream.cs
delete mode 100644 foreign/csharp/Iggy_SDK/ConnectionStream/TcpConnectionStream.cs
rename foreign/csharp/{Iggy_SDK_Tests/Utils/Errors/ErrorModelFactory.cs => Iggy_SDK/Messages/BatchWireFormat.cs} (70%)
copy foreign/csharp/{Iggy_SDK.Tests.Integration/Attributes/SkipHttpAttribute.cs => Iggy_SDK/Utils/ArrayPoolHelper.cs} (53%)
delete mode 100644 foreign/csharp/Iggy_SDK/Utils/BufferSizes.cs
copy foreign/csharp/Iggy_SDK/Vsr/{Command2.cs => Command.cs} (97%)
rename foreign/csharp/Iggy_SDK/Vsr/{Command2.cs => ISessionGenerationProvider.cs} (58%)
create mode 100644 foreign/csharp/Iggy_SDK/Vsr/VsrConnection.cs
create mode 100644 foreign/csharp/Iggy_SDK_Tests/ConsumerTests/ConsumerSessionGenerationTests.cs
create mode 100644 foreign/csharp/Iggy_SDK_Tests/ContractsTests/MessageBatchGoldenVectorTests.cs
delete mode 100644 foreign/csharp/Iggy_SDK_Tests/UtilityTests/SlicedMemoryOwnerTests.cs
create mode 100644 foreign/csharp/Iggy_SDK_Tests/VsrTests/DialCandidatesTests.cs
create mode 100644 foreign/csharp/Iggy_SDK_Tests/VsrTests/EndpointFailoverTests.cs
create mode 100644 foreign/go/client/tcp/tcp_failover_test.go
create mode 100644 foreign/go/client/tcp/tcp_session_credentials_test.go
create mode 100644 foreign/go/internal/batch/batch.go
create mode 100644 foreign/java/java-sdk/src/test/java/org/apache/iggy/client/async/tcp/AsyncIggyTcpClientEndpointFailoverTest.java
create mode 100644 foreign/java/java-sdk/src/test/java/org/apache/iggy/serde/MessagesBatchWireFormatTest.java
create mode 100644 foreign/node/src/client/client.connection-string.test.ts
create mode 100644 foreign/node/src/client/client.connection-string.ts
copy core/bench/dashboard/frontend/src/components/theme/mod.rs => foreign/node/src/constant.ts (89%)
create mode 100644 foreign/node/src/duration.utils.test.ts
create mode 100644 foreign/node/src/duration.utils.ts
create mode 100644 foreign/node/src/e2e/tcp.connection-string.e2e.ts
create mode 100644 foreign/node/src/wire/message/message-batch.test.ts
create mode 100644 gateways/README.md
copy {core/message_bus => gateways/kafka}/Cargo.toml (55%)
create mode 100644 gateways/kafka/README.md
create mode 100644 gateways/kafka/docs/MANUAL_TESTING.md
create mode 100644 gateways/kafka/docs/SCOPE.md
create mode 100644 gateways/kafka/docs/TEST_SUITE.md
create mode 100644 gateways/kafka/docs/kafka_api_keys_reference.md
create mode 100755 gateways/kafka/scripts/ci-wire-fixtures.sh
create mode 100644 gateways/kafka/src/error.rs
copy bdd/rust/tests/steps/mod.rs => gateways/kafka/src/lib.rs (85%)
create mode 100644 gateways/kafka/src/main.rs
create mode 100644 gateways/kafka/src/protocol/api.rs
create mode 100644 gateways/kafka/src/protocol/bounds_guard.rs
create mode 100644 gateways/kafka/src/protocol/header.rs
copy {core/bench/dashboard/frontend/src/components/theme => gateways/kafka/src/protocol}/mod.rs (91%)
create mode 100644 gateways/kafka/src/protocol/responses.rs
create mode 100644 gateways/kafka/src/server.rs
create mode 100644 gateways/kafka/tests/api_handler_tests.rs
create mode 100644 gateways/kafka/tests/broker_advertise_tests.rs
create mode 100644 gateways/kafka/tests/common/codec.rs
create mode 100644 gateways/kafka/tests/common/fixtures.rs
copy core/bench/src/actors/mod.rs => gateways/kafka/tests/common/scope.rs (60%)
create mode 100644 gateways/kafka/tests/common/server.rs
create mode 100644 gateways/kafka/tests/common/tcp.rs
create mode 100644 gateways/kafka/tests/common/wire.rs
copy foreign/csharp/Iggy_SDK_Tests/Utils/DummyObj/DummyObjFactory.cs => gateways/kafka/tests/fixtures_canary_tests.rs (51%)
create mode 100644 gateways/kafka/tests/golden_wire_fixtures_tests.rs
create mode 100644 gateways/kafka/tests/header_tests.rs
create mode 100644 gateways/kafka/tests/listener_robustness_tests.rs
create mode 100644 gateways/kafka/tests/response_negative_tests.rs
create mode 100644 gateways/kafka/tests/server_e2e_tests.rs
create mode 100644 gateways/kafka/tests/server_integration_tests.rs
create mode 100644 gateways/kafka/tests/version_firewall_tests.rs
copy {core/bench/runner => gateways/kafka/tools/kafka-tool}/Cargo.toml (73%)
create mode 100644 gateways/kafka/tools/kafka-tool/README.md
create mode 100644 gateways/kafka/tools/kafka-tool/src/main.rs
create mode 100644 gateways/kafka/tools/kafka-tool/src/response.rs
create mode 100644 gateways/kafka/tools/kafka-tool/tests/generate_cli_tests.rs
create mode 100755 scripts/ci/apt-install.sh
(iggy) 04/11: add tests and stubs
Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
slbotbm pushed a commit to branch feat/add-python-stream-management-functions
in repository https://gitbox.apache.org/repos/asf/iggy.git
commit 7000a3de292c25edab09b1b7bee78502e9935abe
Author: Rimuksh Kansal <ni...@gmail.com>
AuthorDate: Tue Aug 4 17:24:15 2026 +0900
add tests and stubs
---
foreign/python/apache_iggy.pyi | 106 ++++++++++++++++++++++++++++++++----
foreign/python/tests/test_stream.py | 103 +++++++++++++++++++++++++----------
2 files changed, 167 insertions(+), 42 deletions(-)
diff --git a/foreign/python/apache_iggy.pyi b/foreign/python/apache_iggy.pyi
index 864d74e9c..80b4c430e 100644
--- a/foreign/python/apache_iggy.pyi
+++ b/foreign/python/apache_iggy.pyi
@@ -1058,29 +1058,83 @@ class IggyClient:
"""
def get_streams(self) -> collections.abc.Awaitable[list[Stream]]:
r"""
- Gets all streams.
- Returns a list of streams or a PyRuntimeError on failure.
+ Return all streams visible to the authenticated user.
+
+ The result is ordered by ascending numeric stream ID.
+
+ Returns:
+ A list of `Stream` summaries.
+
+ Raises:
+ RuntimeError: If the client is not authenticated, the user lacks global
+ `read_streams` or `manage_streams` permission, or the request fails.
"""
def update_stream(
self, stream_id: builtins.str | builtins.int, name: builtins.str
) -> collections.abc.Awaitable[None]:
r"""
- Updates a stream's name by id.
- Returns Ok(()) on successful update or a PyRuntimeError on failure.
+ Rename a stream selected by name or numeric ID.
+
+ `stream_id` accepts a stream name as `str` or numeric ID as `int`. A
+ decimal-only string is interpreted as a numeric ID. `name` must be unique
+ and contain between 1 and 255 UTF-8 bytes. Renaming a stream to its current
+ name succeeds without changing it.
+
+ Returns:
+ None.
+
+ Raises:
+ TypeError: If `stream_id` is neither `str` nor `int`, or `name` is not
+ `str`.
+ OverflowError: If an integer identifier is outside `0..=2**32 - 1`.
+ ValueError: If a string identifier is empty or exceeds 255 UTF-8 bytes.
+ RuntimeError: If the client is not authenticated, the user lacks global
+ `manage_streams` or per-stream `manage_stream` permission, the
+ stream does not exist, the new name is invalid or already used, or
+ the request fails.
"""
def delete_stream(
self, stream_id: builtins.str | builtins.int
) -> collections.abc.Awaitable[None]:
r"""
- Deletes a stream by id.
- Returns Ok(()) on successful deletion or a PyRuntimeError on failure.
+ Delete a stream selected by name or numeric ID.
+
+ Deletion removes the stream and all of its topics, partitions, and messages.
+ `stream_id` accepts a stream name as `str` or numeric ID as `int`. A
+ decimal-only string is interpreted as a numeric ID.
+
+ Returns:
+ None.
+
+ Raises:
+ TypeError: If `stream_id` is neither `str` nor `int`.
+ OverflowError: If an integer identifier is outside `0..=2**32 - 1`.
+ ValueError: If a string identifier is empty or exceeds 255 UTF-8 bytes.
+ RuntimeError: If the client is not authenticated, the user lacks global
+ `manage_streams` or per-stream `manage_stream` permission, the
+ stream does not exist, or the request fails.
"""
def purge_stream(
self, stream_id: builtins.str | builtins.int
) -> collections.abc.Awaitable[None]:
r"""
- Purges all messages from a stream by id.
- Returns Ok(()) on successful purge or a PyRuntimeError on failure.
+ Delete all messages from every topic in a stream.
+
+ The stream, topics, and partitions remain available. Repeated purges of an
+ existing empty stream succeed. `stream_id` accepts a stream name as `str`
+ or numeric ID as `int`. A decimal-only string is interpreted as a numeric
+ ID.
+
+ Returns:
+ None.
+
+ Raises:
+ TypeError: If `stream_id` is neither `str` nor `int`.
+ OverflowError: If an integer identifier is outside `0..=2**32 - 1`.
+ ValueError: If a string identifier is empty or exceeds 255 UTF-8 bytes.
+ RuntimeError: If the client is not authenticated, the user lacks global
+ `manage_streams` or per-stream `manage_stream` permission, the
+ stream does not exist, or the request fails.
"""
def create_topic(
self,
@@ -1862,14 +1916,42 @@ class SendMessagesResponse:
"""
class Stream:
+ r"""
+ Summary information returned by `IggyClient.get_streams()`.
+
+ `created_at` is Unix time in microseconds. `size_bytes` is the stream's
+ current stored size in bytes.
+ """
@property
- def id(self) -> builtins.int: ...
+ def id(self) -> builtins.int:
+ r"""
+ Numeric stream identifier.
+ """
@property
- def name(self) -> builtins.str: ...
+ def created_at(self) -> builtins.int:
+ r"""
+ Stream creation time as Unix time in microseconds.
+ """
@property
- def messages_count(self) -> builtins.int: ...
+ def name(self) -> builtins.str:
+ r"""
+ Unique stream name.
+ """
@property
- def topics_count(self) -> builtins.int: ...
+ def size_bytes(self) -> builtins.int:
+ r"""
+ Current stored stream size in bytes.
+ """
+ @property
+ def messages_count(self) -> builtins.int:
+ r"""
+ Total messages across all topics in the stream.
+ """
+ @property
+ def topics_count(self) -> builtins.int:
+ r"""
+ Number of topics in the stream.
+ """
@typing.final
class StreamDetails:
diff --git a/foreign/python/tests/test_stream.py b/foreign/python/tests/test_stream.py
index 8f757fab1..2db391951 100644
--- a/foreign/python/tests/test_stream.py
+++ b/foreign/python/tests/test_stream.py
@@ -223,11 +223,13 @@ class TestGetStreams:
await iggy_client.create_stream(name)
streams = await iggy_client.get_streams()
- by_name = {stream.name: stream for stream in streams}
- assert set(created).issubset(by_name)
+ created_names = set(created)
+ mine = [stream for stream in streams if stream.name in created_names]
- mine = [by_name[name] for name in created]
+ assert [stream.name for stream in mine] == created
assert [stream.id for stream in mine] == sorted(stream.id for stream in mine)
+ assert all(stream.created_at > 0 for stream in mine)
+ assert all(stream.size_bytes == 0 for stream in mine)
assert all(stream.messages_count == 0 for stream in mine)
assert all(stream.topics_count == 0 for stream in mine)
@@ -264,23 +266,16 @@ class TestGetStreams:
assert [stream.name for stream in first] == [stream.name for stream in second]
@pytest.mark.asyncio
- async def test_get_streams_before_connect_fails(self):
- """Test get_streams requires an established connection."""
+ async def test_get_streams_requires_connection_and_auth(self):
+ """Test get_streams fails both before connecting and before logging in."""
host, port = get_server_config()
- client = IggyClient(f"{host}:{port}")
+ wait_for_server(host, port)
+ client = IggyClient(f"{host}:{port}")
with pytest.raises(RuntimeError):
await client.get_streams()
- @pytest.mark.asyncio
- async def test_get_streams_before_login_fails(self):
- """Test get_streams requires authentication."""
- host, port = get_server_config()
- wait_for_server(host, port)
-
- client = IggyClient(f"{host}:{port}")
await client.connect()
-
with pytest.raises(RuntimeError):
await client.get_streams()
@@ -297,52 +292,79 @@ class TestUpdateStream:
new_name = unique_name()
await iggy_client.create_stream(stream_name)
+ before = await iggy_client.get_stream(stream_name)
+ assert before is not None
await iggy_client.update_stream(stream_id=stream_name, name=new_name)
renamed = await iggy_client.get_stream(new_name)
assert renamed is not None
assert renamed.name == new_name
+ assert renamed.id == before.id
old = await iggy_client.get_stream(stream_name)
assert old is None
@pytest.mark.asyncio
- async def test_update_stream_preserves_id(
+ async def test_update_stream_by_numeric_id(
self, iggy_client: IggyClient, unique_name
):
- """Test update_stream keeps the same numeric id after a rename."""
+ """Test update_stream accepts a numeric stream id."""
stream_name = unique_name()
new_name = unique_name()
await iggy_client.create_stream(stream_name)
- before = await iggy_client.get_stream(stream_name)
- assert before is not None
+ stream = await iggy_client.get_stream(stream_name)
+ assert stream is not None
- await iggy_client.update_stream(stream_id=stream_name, name=new_name)
+ await iggy_client.update_stream(stream_id=stream.id, name=new_name)
- after = await iggy_client.get_stream(new_name)
- assert after is not None
- assert after.id == before.id
+ renamed = await iggy_client.get_stream(new_name)
+ assert renamed is not None
+ assert renamed.name == new_name
@pytest.mark.asyncio
- async def test_update_stream_by_numeric_id(
- self, iggy_client: IggyClient, unique_name
+ @pytest.mark.parametrize(
+ "new_name",
+ [
+ pytest.param("a", id="one-byte"),
+ pytest.param("a" * 255, id="255-byte-ascii"),
+ pytest.param(("é" * 127) + "a", id="255-byte-utf8"),
+ ],
+ )
+ async def test_update_stream_accepts_name_boundaries(
+ self, iggy_client: IggyClient, unique_name, new_name: str
):
- """Test update_stream accepts a numeric stream id."""
+ """Test update_stream accepts names at the UTF-8 byte boundaries."""
stream_name = unique_name()
- new_name = unique_name()
-
await iggy_client.create_stream(stream_name)
- stream = await iggy_client.get_stream(stream_name)
- assert stream is not None
- await iggy_client.update_stream(stream_id=stream.id, name=new_name)
+ await iggy_client.update_stream(stream_id=stream_name, name=new_name)
renamed = await iggy_client.get_stream(new_name)
assert renamed is not None
assert renamed.name == new_name
+ @pytest.mark.asyncio
+ @pytest.mark.parametrize(
+ "new_name",
+ [
+ pytest.param("", id="empty"),
+ pytest.param("a" * 256, id="256-byte-ascii"),
+ pytest.param("é" * 128, id="256-byte-utf8"),
+ pytest.param(("😀" * 63) + "aaaa", id="256-byte-four-byte-utf8"),
+ ],
+ )
+ async def test_update_stream_rejects_invalid_name_boundaries(
+ self, iggy_client: IggyClient, unique_name, new_name: str
+ ):
+ """Test update_stream rejects empty and 256-byte names."""
+ stream_name = unique_name()
+ await iggy_client.create_stream(stream_name)
+
+ with pytest.raises(RuntimeError):
+ await iggy_client.update_stream(stream_id=stream_name, name=new_name)
+
@pytest.mark.asyncio
async def test_update_stream_applies_repeated_updates(
self, iggy_client: IggyClient, unique_name
@@ -384,10 +406,31 @@ class TestUpdateStream:
await iggy_client.create_stream(first_stream)
await iggy_client.create_stream(second_stream)
+ streams = await iggy_client.get_streams()
+ before = next(stream for stream in streams if stream.name == second_stream)
+ before_metadata = (
+ before.id,
+ before.created_at,
+ before.name,
+ before.size_bytes,
+ before.messages_count,
+ before.topics_count,
+ )
with pytest.raises(RuntimeError):
await iggy_client.update_stream(stream_id=second_stream, name=first_stream)
+ streams = await iggy_client.get_streams()
+ after = next(stream for stream in streams if stream.id == before.id)
+ assert (
+ after.id,
+ after.created_at,
+ after.name,
+ after.size_bytes,
+ after.messages_count,
+ after.topics_count,
+ ) == before_metadata
+
@pytest.mark.asyncio
async def test_update_stream_requires_connection_and_auth(self, unique_name):
"""Test update_stream fails both before connecting and before logging in."""
(iggy) 02/11: add stream getters and docs
Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
slbotbm pushed a commit to branch feat/add-python-stream-management-functions
in repository https://gitbox.apache.org/repos/asf/iggy.git
commit 9a93dc7bdfb0a7ba0069ee9fb100f74c4fec9b33
Author: Rimuksh Kansal <ni...@gmail.com>
AuthorDate: Tue Aug 4 17:09:16 2026 +0900
add stream getters and docs
---
foreign/python/src/stream.rs | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/foreign/python/src/stream.rs b/foreign/python/src/stream.rs
index c4c7f5846..2a7055b2d 100644
--- a/foreign/python/src/stream.rs
+++ b/foreign/python/src/stream.rs
@@ -57,6 +57,10 @@ impl StreamDetails {
}
}
+/// Summary information returned by `IggyClient.get_streams()`.
+///
+/// `created_at` is Unix time in microseconds. `size_bytes` is the stream's
+/// current stored size in bytes.
#[gen_stub_pyclass]
#[pyclass]
pub struct Stream {
@@ -72,21 +76,37 @@ impl From<RustStream> for Stream {
#[gen_stub_pymethods]
#[pymethods]
impl Stream {
+ /// Numeric stream identifier.
#[getter]
pub fn id(&self) -> u32 {
self.inner.id
}
+ /// Stream creation time as Unix time in microseconds.
+ #[getter]
+ pub fn created_at(&self) -> u64 {
+ self.inner.created_at.as_micros()
+ }
+
+ /// Unique stream name.
#[getter]
pub fn name(&self) -> String {
self.inner.name.to_string()
}
+ /// Current stored stream size in bytes.
+ #[getter]
+ pub fn size_bytes(&self) -> u64 {
+ self.inner.size.as_bytes_u64()
+ }
+
+ /// Total messages across all topics in the stream.
#[getter]
pub fn messages_count(&self) -> u64 {
self.inner.messages_count
}
+ /// Number of topics in the stream.
#[getter]
pub fn topics_count(&self) -> u32 {
self.inner.topics_count
(iggy) 01/11: feat(python): add stream listing, update, delete, and purge
Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
slbotbm pushed a commit to branch feat/add-python-stream-management-functions
in repository https://gitbox.apache.org/repos/asf/iggy.git
commit 2567de3714086311b1a0a705ce1e82a1c61b2895
Author: Faisal Ahmed <fa...@gmail.com>
AuthorDate: Sun Jul 19 05:00:52 2026 +0530
feat(python): add stream listing, update, delete, and purge
Signed-off-by: Faisal Ahmed <fa...@gmail.com>
---
foreign/python/apache_iggy.pyi | 37 ++++
foreign/python/src/client.rs | 74 ++++++-
foreign/python/src/lib.rs | 3 +-
foreign/python/src/stream.rs | 38 +++-
foreign/python/tests/test_stream.py | 380 +++++++++++++++++++++++++++++++++++-
5 files changed, 528 insertions(+), 4 deletions(-)
diff --git a/foreign/python/apache_iggy.pyi b/foreign/python/apache_iggy.pyi
index 254b23f41..864d74e9c 100644
--- a/foreign/python/apache_iggy.pyi
+++ b/foreign/python/apache_iggy.pyi
@@ -49,6 +49,7 @@ __all__ = [
"SendMessage",
"SendMessagesConfirmation",
"SendMessagesResponse",
+ "Stream",
"StreamDetails",
"StreamPermissions",
"TcpConfig",
@@ -1055,6 +1056,32 @@ class IggyClient:
ValueError: If the scope name is not one of the three above.
RuntimeError: If the request fails.
"""
+ def get_streams(self) -> collections.abc.Awaitable[list[Stream]]:
+ r"""
+ Gets all streams.
+ Returns a list of streams or a PyRuntimeError on failure.
+ """
+ def update_stream(
+ self, stream_id: builtins.str | builtins.int, name: builtins.str
+ ) -> collections.abc.Awaitable[None]:
+ r"""
+ Updates a stream's name by id.
+ Returns Ok(()) on successful update or a PyRuntimeError on failure.
+ """
+ def delete_stream(
+ self, stream_id: builtins.str | builtins.int
+ ) -> collections.abc.Awaitable[None]:
+ r"""
+ Deletes a stream by id.
+ Returns Ok(()) on successful deletion or a PyRuntimeError on failure.
+ """
+ def purge_stream(
+ self, stream_id: builtins.str | builtins.int
+ ) -> collections.abc.Awaitable[None]:
+ r"""
+ Purges all messages from a stream by id.
+ Returns Ok(()) on successful purge or a PyRuntimeError on failure.
+ """
def create_topic(
self,
stream: builtins.str | builtins.int,
@@ -1834,6 +1861,16 @@ class SendMessagesResponse:
with an offset a client has already recorded.
"""
+class Stream:
+ @property
+ def id(self) -> builtins.int: ...
+ @property
+ def name(self) -> builtins.str: ...
+ @property
+ def messages_count(self) -> builtins.int: ...
+ @property
+ def topics_count(self) -> builtins.int: ...
+
@typing.final
class StreamDetails:
@property
diff --git a/foreign/python/src/client.rs b/foreign/python/src/client.rs
index f669a8748..f2d8567ad 100644
--- a/foreign/python/src/client.rs
+++ b/foreign/python/src/client.rs
@@ -42,7 +42,7 @@ use crate::options::OptionSpec as PyOptionSpec;
use crate::permissions::Permissions as PyPermissions;
use crate::receive_message::{PollingStrategy, ReceiveMessage};
use crate::send_message::{SendMessage, SendMessagesResponse as PySendMessagesResponse};
-use crate::stream::StreamDetails;
+use crate::stream::{Stream, StreamDetails};
use crate::topic::{IggyExpiry, MaxTopicSize, Topic, TopicDetails};
use crate::user::{
UserInfo as PyUserInfo, UserInfoDetails as PyUserInfoDetails, UserStatus as PyUserStatus,
@@ -500,6 +500,78 @@ impl IggyClient {
})
}
+ /// Gets all streams.
+ /// Returns a list of streams or a PyRuntimeError on failure.
+ #[gen_stub(override_return_type(type_repr="collections.abc.Awaitable[list[Stream]]", imports=("collections.abc")))]
+ fn get_streams<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyAny>> {
+ let inner = self.inner.clone();
+ future_into_py(py, async move {
+ let streams = inner
+ .get_streams()
+ .await
+ .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?;
+ Ok(streams.into_iter().map(Stream::from).collect::<Vec<_>>())
+ })
+ }
+
+ /// Updates a stream's name by id.
+ /// Returns Ok(()) on successful update or a PyRuntimeError on failure.
+ #[gen_stub(override_return_type(type_repr="collections.abc.Awaitable[None]", imports=("collections.abc")))]
+ fn update_stream<'a>(
+ &self,
+ py: Python<'a>,
+ stream_id: PyIdentifier,
+ name: String,
+ ) -> PyResult<Bound<'a, PyAny>> {
+ let stream_id = Identifier::try_from(stream_id)?;
+ let inner = self.inner.clone();
+ future_into_py(py, async move {
+ inner
+ .update_stream(&stream_id, &name)
+ .await
+ .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?;
+ Ok(())
+ })
+ }
+
+ /// Deletes a stream by id.
+ /// Returns Ok(()) on successful deletion or a PyRuntimeError on failure.
+ #[gen_stub(override_return_type(type_repr="collections.abc.Awaitable[None]", imports=("collections.abc")))]
+ fn delete_stream<'a>(
+ &self,
+ py: Python<'a>,
+ stream_id: PyIdentifier,
+ ) -> PyResult<Bound<'a, PyAny>> {
+ let stream_id = Identifier::try_from(stream_id)?;
+ let inner = self.inner.clone();
+ future_into_py(py, async move {
+ inner
+ .delete_stream(&stream_id)
+ .await
+ .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?;
+ Ok(())
+ })
+ }
+
+ /// Purges all messages from a stream by id.
+ /// Returns Ok(()) on successful purge or a PyRuntimeError on failure.
+ #[gen_stub(override_return_type(type_repr="collections.abc.Awaitable[None]", imports=("collections.abc")))]
+ fn purge_stream<'a>(
+ &self,
+ py: Python<'a>,
+ stream_id: PyIdentifier,
+ ) -> PyResult<Bound<'a, PyAny>> {
+ let stream_id = Identifier::try_from(stream_id)?;
+ let inner = self.inner.clone();
+ future_into_py(py, async move {
+ inner
+ .purge_stream(&stream_id)
+ .await
+ .map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?;
+ Ok(())
+ })
+ }
+
/// Creates a new topic with the given parameters.
///
/// Args:
diff --git a/foreign/python/src/lib.rs b/foreign/python/src/lib.rs
index 5f2e12826..1dd2af054 100644
--- a/foreign/python/src/lib.rs
+++ b/foreign/python/src/lib.rs
@@ -40,7 +40,7 @@ use permissions::{GlobalPermissions, Permissions, StreamPermissions, TopicPermis
use pyo3::prelude::*;
use receive_message::{PollingStrategy, ReceiveMessage};
use send_message::{SendMessage, SendMessagesConfirmation, SendMessagesResponse};
-use stream::StreamDetails;
+use stream::{Stream, StreamDetails};
use topic::{IggyExpiry, MaxTopicSize, Partition, Topic, TopicDetails};
use user::{UserInfo, UserInfoDetails, UserStatus};
use user_headers::{HeaderKey, HeaderValue, UserHeaders};
@@ -57,6 +57,7 @@ fn apache_iggy(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<TcpConfig>()?;
m.add_class::<TcpReconnectionConfig>()?;
m.add_class::<StreamDetails>()?;
+ m.add_class::<Stream>()?;
m.add_class::<Topic>()?;
m.add_class::<TopicDetails>()?;
m.add_class::<IggyExpiry>()?;
diff --git a/foreign/python/src/stream.rs b/foreign/python/src/stream.rs
index 7343d2c53..c4c7f5846 100644
--- a/foreign/python/src/stream.rs
+++ b/foreign/python/src/stream.rs
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-use iggy::prelude::StreamDetails as RustStreamDetails;
+use iggy::prelude::{Stream as RustStream, StreamDetails as RustStreamDetails};
use pyo3::prelude::*;
use pyo3_stub_gen::derive::{gen_stub_pyclass, gen_stub_pymethods};
@@ -56,3 +56,39 @@ impl StreamDetails {
self.inner.topics_count
}
}
+
+#[gen_stub_pyclass]
+#[pyclass]
+pub struct Stream {
+ pub(crate) inner: RustStream,
+}
+
+impl From<RustStream> for Stream {
+ fn from(stream: RustStream) -> Self {
+ Self { inner: stream }
+ }
+}
+
+#[gen_stub_pymethods]
+#[pymethods]
+impl Stream {
+ #[getter]
+ pub fn id(&self) -> u32 {
+ self.inner.id
+ }
+
+ #[getter]
+ pub fn name(&self) -> String {
+ self.inner.name.to_string()
+ }
+
+ #[getter]
+ pub fn messages_count(&self) -> u64 {
+ self.inner.messages_count
+ }
+
+ #[getter]
+ pub fn topics_count(&self) -> u32 {
+ self.inner.topics_count
+ }
+}
diff --git a/foreign/python/tests/test_stream.py b/foreign/python/tests/test_stream.py
index 5e71a543a..8f757fab1 100644
--- a/foreign/python/tests/test_stream.py
+++ b/foreign/python/tests/test_stream.py
@@ -17,7 +17,7 @@
import pytest
-from apache_iggy import IggyClient
+from apache_iggy import IggyClient, SendMessage
from .utils import get_server_config, wait_for_ping, wait_for_server
@@ -203,3 +203,381 @@ class TestStreamOperations:
with pytest.raises(RuntimeError):
await client.create_stream(unique_name())
+
+
+class TestGetStreams:
+ """Test listing streams via get_streams."""
+
+ @pytest.mark.asyncio
+ async def test_get_streams_returns_created_streams(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test get_streams returns every stream created during the test."""
+ # Reverse-alphabetical names so that id-ascending (creation) order
+ # and name order disagree, proving the list isn't accidentally
+ # name-sorted. The client fixture is session-scoped, so other tests
+ # may have created streams; assert on the ones created here instead
+ # of the full server view.
+ created = [unique_name(f"z{index}") for index in range(3, 0, -1)]
+ for name in created:
+ await iggy_client.create_stream(name)
+
+ streams = await iggy_client.get_streams()
+ by_name = {stream.name: stream for stream in streams}
+ assert set(created).issubset(by_name)
+
+ mine = [by_name[name] for name in created]
+ assert [stream.id for stream in mine] == sorted(stream.id for stream in mine)
+ assert all(stream.messages_count == 0 for stream in mine)
+ assert all(stream.topics_count == 0 for stream in mine)
+
+ @pytest.mark.asyncio
+ async def test_get_streams_reflects_topic_count(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test get_streams reports the topic count for a listed stream."""
+ stream_name = unique_name()
+ topic_name = unique_name()
+
+ await iggy_client.create_stream(stream_name)
+ await iggy_client.create_topic(
+ stream=stream_name, name=topic_name, partitions_count=1
+ )
+
+ streams = await iggy_client.get_streams()
+ listed = next(
+ (stream for stream in streams if stream.name == stream_name), None
+ )
+ assert listed is not None
+ assert listed.topics_count == 1
+
+ @pytest.mark.asyncio
+ async def test_get_streams_returns_same_result_when_called_repeatedly(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test repeated get_streams calls return an identically ordered view."""
+ await iggy_client.create_stream(unique_name())
+
+ first = await iggy_client.get_streams()
+ second = await iggy_client.get_streams()
+ assert [stream.id for stream in first] == [stream.id for stream in second]
+ assert [stream.name for stream in first] == [stream.name for stream in second]
+
+ @pytest.mark.asyncio
+ async def test_get_streams_before_connect_fails(self):
+ """Test get_streams requires an established connection."""
+ host, port = get_server_config()
+ client = IggyClient(f"{host}:{port}")
+
+ with pytest.raises(RuntimeError):
+ await client.get_streams()
+
+ @pytest.mark.asyncio
+ async def test_get_streams_before_login_fails(self):
+ """Test get_streams requires authentication."""
+ host, port = get_server_config()
+ wait_for_server(host, port)
+
+ client = IggyClient(f"{host}:{port}")
+ await client.connect()
+
+ with pytest.raises(RuntimeError):
+ await client.get_streams()
+
+
+class TestUpdateStream:
+ """Test updating streams via update_stream."""
+
+ @pytest.mark.asyncio
+ async def test_update_stream_renames_stream(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test update_stream renames a stream; old name no longer resolves."""
+ stream_name = unique_name()
+ new_name = unique_name()
+
+ await iggy_client.create_stream(stream_name)
+
+ await iggy_client.update_stream(stream_id=stream_name, name=new_name)
+
+ renamed = await iggy_client.get_stream(new_name)
+ assert renamed is not None
+ assert renamed.name == new_name
+
+ old = await iggy_client.get_stream(stream_name)
+ assert old is None
+
+ @pytest.mark.asyncio
+ async def test_update_stream_preserves_id(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test update_stream keeps the same numeric id after a rename."""
+ stream_name = unique_name()
+ new_name = unique_name()
+
+ await iggy_client.create_stream(stream_name)
+ before = await iggy_client.get_stream(stream_name)
+ assert before is not None
+
+ await iggy_client.update_stream(stream_id=stream_name, name=new_name)
+
+ after = await iggy_client.get_stream(new_name)
+ assert after is not None
+ assert after.id == before.id
+
+ @pytest.mark.asyncio
+ async def test_update_stream_by_numeric_id(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test update_stream accepts a numeric stream id."""
+ stream_name = unique_name()
+ new_name = unique_name()
+
+ await iggy_client.create_stream(stream_name)
+ stream = await iggy_client.get_stream(stream_name)
+ assert stream is not None
+
+ await iggy_client.update_stream(stream_id=stream.id, name=new_name)
+
+ renamed = await iggy_client.get_stream(new_name)
+ assert renamed is not None
+ assert renamed.name == new_name
+
+ @pytest.mark.asyncio
+ async def test_update_stream_applies_repeated_updates(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test successive update_stream calls each take effect."""
+ stream_name = unique_name()
+ first_rename = unique_name()
+ second_rename = unique_name()
+
+ await iggy_client.create_stream(stream_name)
+
+ await iggy_client.update_stream(stream_id=stream_name, name=first_rename)
+ after_first = await iggy_client.get_stream(first_rename)
+ assert after_first is not None
+ assert after_first.name == first_rename
+ assert await iggy_client.get_stream(stream_name) is None
+
+ await iggy_client.update_stream(stream_id=first_rename, name=second_rename)
+ after_second = await iggy_client.get_stream(second_rename)
+ assert after_second is not None
+ assert after_second.name == second_rename
+ assert await iggy_client.get_stream(first_rename) is None
+
+ @pytest.mark.asyncio
+ async def test_update_nonexistent_stream_fails(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test update_stream raises for a non-existent stream."""
+ with pytest.raises(RuntimeError):
+ await iggy_client.update_stream(stream_id=unique_name(), name=unique_name())
+
+ @pytest.mark.asyncio
+ async def test_update_stream_to_existing_name_fails(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test update_stream rejects renaming a stream to a name already in use."""
+ first_stream = unique_name()
+ second_stream = unique_name()
+
+ await iggy_client.create_stream(first_stream)
+ await iggy_client.create_stream(second_stream)
+
+ with pytest.raises(RuntimeError):
+ await iggy_client.update_stream(stream_id=second_stream, name=first_stream)
+
+ @pytest.mark.asyncio
+ async def test_update_stream_requires_connection_and_auth(self, unique_name):
+ """Test update_stream fails both before connecting and before logging in."""
+ host, port = get_server_config()
+ wait_for_server(host, port)
+
+ client = IggyClient(f"{host}:{port}")
+ with pytest.raises(RuntimeError):
+ await client.update_stream(stream_id=unique_name(), name=unique_name())
+
+ await client.connect()
+ with pytest.raises(RuntimeError):
+ await client.update_stream(stream_id=unique_name(), name=unique_name())
+
+
+class TestDeleteStream:
+ """Test deleting streams via delete_stream."""
+
+ @pytest.mark.asyncio
+ async def test_delete_stream_removes_stream(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test delete_stream removes the stream so it no longer resolves."""
+ stream_name = unique_name()
+
+ await iggy_client.create_stream(stream_name)
+
+ await iggy_client.delete_stream(stream_name)
+
+ assert await iggy_client.get_stream(stream_name) is None
+
+ @pytest.mark.asyncio
+ async def test_delete_stream_by_numeric_id(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test delete_stream accepts a numeric stream id."""
+ stream_name = unique_name()
+
+ await iggy_client.create_stream(stream_name)
+ stream = await iggy_client.get_stream(stream_name)
+ assert stream is not None
+
+ await iggy_client.delete_stream(stream.id)
+
+ assert await iggy_client.get_stream(stream_name) is None
+
+ @pytest.mark.asyncio
+ async def test_delete_stream_leaves_other_streams(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test delete_stream removes only the targeted stream."""
+ stream_to_delete = unique_name()
+ stream_to_keep = unique_name()
+
+ await iggy_client.create_stream(stream_to_delete)
+ await iggy_client.create_stream(stream_to_keep)
+
+ await iggy_client.delete_stream(stream_to_delete)
+
+ assert await iggy_client.get_stream(stream_to_delete) is None
+ kept = await iggy_client.get_stream(stream_to_keep)
+ assert kept is not None
+ assert kept.name == stream_to_keep
+
+ @pytest.mark.asyncio
+ async def test_delete_nonexistent_stream_fails(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test delete_stream raises for a non-existent stream."""
+ with pytest.raises(RuntimeError):
+ await iggy_client.delete_stream(unique_name())
+
+ @pytest.mark.asyncio
+ async def test_delete_stream_twice_fails_second_time(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test deleting an already-deleted stream raises on the second call."""
+ stream_name = unique_name()
+
+ await iggy_client.create_stream(stream_name)
+
+ await iggy_client.delete_stream(stream_name)
+ with pytest.raises(RuntimeError):
+ await iggy_client.delete_stream(stream_name)
+
+ @pytest.mark.asyncio
+ async def test_delete_stream_requires_connection_and_auth(self, unique_name):
+ """Test delete_stream fails both before connecting and before logging in."""
+ host, port = get_server_config()
+ wait_for_server(host, port)
+
+ client = IggyClient(f"{host}:{port}")
+ with pytest.raises(RuntimeError):
+ await client.delete_stream(unique_name())
+
+ await client.connect()
+ with pytest.raises(RuntimeError):
+ await client.delete_stream(unique_name())
+
+
+class TestPurgeStream:
+ """Test purging stream messages via purge_stream."""
+
+ @pytest.mark.asyncio
+ async def test_purge_stream_clears_messages_but_keeps_stream(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test purge_stream empties the stream while leaving it in place."""
+ stream_name = unique_name()
+ topic_name = unique_name()
+
+ await iggy_client.create_stream(stream_name)
+ await iggy_client.create_topic(
+ stream=stream_name, name=topic_name, partitions_count=1
+ )
+
+ messages = [SendMessage(f"payload-{index}") for index in range(5)]
+ await iggy_client.send_messages(stream_name, topic_name, 0, messages)
+
+ before = await iggy_client.get_stream(stream_name)
+ assert before is not None
+ assert before.messages_count == 5
+
+ await iggy_client.purge_stream(stream_name)
+
+ after = await iggy_client.get_stream(stream_name)
+ # Purging clears messages only; the stream itself survives (purge is
+ # not delete) and keeps its identity and topics.
+ assert after is not None
+ assert after.messages_count == 0
+ assert after.id == before.id
+ assert after.name == before.name
+ assert after.topics_count == before.topics_count
+
+ @pytest.mark.asyncio
+ async def test_purge_empty_stream_succeeds(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test purge_stream is a no-op on a stream with no messages."""
+ stream_name = unique_name()
+
+ await iggy_client.create_stream(stream_name)
+
+ await iggy_client.purge_stream(stream_name)
+
+ stream = await iggy_client.get_stream(stream_name)
+ assert stream is not None
+ assert stream.messages_count == 0
+
+ @pytest.mark.asyncio
+ async def test_purge_stream_is_idempotent_when_called_repeatedly(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test purge_stream succeeds when called repeatedly on the same stream."""
+ stream_name = unique_name()
+ topic_name = unique_name()
+
+ await iggy_client.create_stream(stream_name)
+ await iggy_client.create_topic(
+ stream=stream_name, name=topic_name, partitions_count=1
+ )
+
+ messages = [SendMessage(f"payload-{index}") for index in range(5)]
+ await iggy_client.send_messages(stream_name, topic_name, 0, messages)
+
+ await iggy_client.purge_stream(stream_name)
+ await iggy_client.purge_stream(stream_name)
+
+ stream = await iggy_client.get_stream(stream_name)
+ assert stream is not None
+ assert stream.messages_count == 0
+
+ @pytest.mark.asyncio
+ async def test_purge_nonexistent_stream_fails(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test purge_stream raises for a non-existent stream."""
+ with pytest.raises(RuntimeError):
+ await iggy_client.purge_stream(unique_name())
+
+ @pytest.mark.asyncio
+ async def test_purge_stream_requires_connection_and_auth(self, unique_name):
+ """Test purge_stream fails both before connecting and before logging in."""
+ host, port = get_server_config()
+ wait_for_server(host, port)
+
+ client = IggyClient(f"{host}:{port}")
+ with pytest.raises(RuntimeError):
+ await client.purge_stream(unique_name())
+
+ await client.connect()
+ with pytest.raises(RuntimeError):
+ await client.purge_stream(unique_name())
(iggy) 05/11: add test clean up
Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
slbotbm pushed a commit to branch feat/add-python-stream-management-functions
in repository https://gitbox.apache.org/repos/asf/iggy.git
commit 3781412f70bfec6c9483472f09a853cb8e1e5f64
Author: Rimuksh Kansal <ni...@gmail.com>
AuthorDate: Tue Aug 4 18:23:54 2026 +0900
add test clean up
---
bdd/python/uv.lock | 2 --
examples/python/uv.lock | 2 --
foreign/python/pyproject.toml | 2 --
foreign/python/tests/conftest.py | 37 ++++++++++++++++++++++++++++++-------
foreign/python/tests/test_stream.py | 11 +++++------
foreign/python/uv.lock | 26 --------------------------
6 files changed, 35 insertions(+), 45 deletions(-)
diff --git a/bdd/python/uv.lock b/bdd/python/uv.lock
index b401a9ae2..e653aafbb 100644
--- a/bdd/python/uv.lock
+++ b/bdd/python/uv.lock
@@ -25,8 +25,6 @@ requires-dist = [
{ name = "pytest-cov", marker = "extra == 'testing'", specifier = ">=4.0,<8.0" },
{ name = "pytest-timeout", marker = "extra == 'all'", specifier = ">=2.0,<3.0" },
{ name = "pytest-timeout", marker = "extra == 'testing'", specifier = ">=2.0,<3.0" },
- { name = "pytest-xdist", marker = "extra == 'all'", specifier = ">=3.0,<4.0" },
- { name = "pytest-xdist", marker = "extra == 'testing'", specifier = ">=3.0,<4.0" },
{ name = "ruff", marker = "extra == 'all'", specifier = ">=0.1.0,<1.0" },
{ name = "ruff", marker = "extra == 'dev'", specifier = ">=0.1.0,<1.0" },
{ name = "testcontainers", marker = "extra == 'all'", specifier = ">=4.15.0,<5.0" },
diff --git a/examples/python/uv.lock b/examples/python/uv.lock
index 1f9c5b313..9f7392bde 100644
--- a/examples/python/uv.lock
+++ b/examples/python/uv.lock
@@ -25,8 +25,6 @@ requires-dist = [
{ name = "pytest-cov", marker = "extra == 'testing'", specifier = ">=4.0,<8.0" },
{ name = "pytest-timeout", marker = "extra == 'all'", specifier = ">=2.0,<3.0" },
{ name = "pytest-timeout", marker = "extra == 'testing'", specifier = ">=2.0,<3.0" },
- { name = "pytest-xdist", marker = "extra == 'all'", specifier = ">=3.0,<4.0" },
- { name = "pytest-xdist", marker = "extra == 'testing'", specifier = ">=3.0,<4.0" },
{ name = "ruff", marker = "extra == 'all'", specifier = ">=0.1.0,<1.0" },
{ name = "ruff", marker = "extra == 'dev'", specifier = ">=0.1.0,<1.0" },
{ name = "testcontainers", marker = "extra == 'all'", specifier = ">=4.15.0,<5.0" },
diff --git a/foreign/python/pyproject.toml b/foreign/python/pyproject.toml
index 7a82108b6..91c1192ae 100644
--- a/foreign/python/pyproject.toml
+++ b/foreign/python/pyproject.toml
@@ -102,7 +102,6 @@ testing = [
"pytest>=9.1.1,<10.0",
"pytest-asyncio>=0.24.0,<2.0",
"pytest-cov>=4.0,<8.0",
- "pytest-xdist>=3.0,<4.0",
"pytest-timeout>=2.0,<3.0",
]
@@ -123,7 +122,6 @@ all = [
"pytest>=9.1.1,<10.0",
"pytest-asyncio>=0.24.0,<2.0",
"pytest-cov>=4.0,<8.0",
- "pytest-xdist>=3.0,<4.0",
"pytest-timeout>=2.0,<3.0",
"ruff>=0.1.0,<1.0",
"testcontainers>=4.15.0,<5.0",
diff --git a/foreign/python/tests/conftest.py b/foreign/python/tests/conftest.py
index 3ab97065f..d80c7776d 100644
--- a/foreign/python/tests/conftest.py
+++ b/foreign/python/tests/conftest.py
@@ -22,13 +22,11 @@ This module provides pytest fixtures for setting up test environments
and connecting to Iggy servers in various configurations.
"""
-# TODO(slbotbm): Create text fixture for clean up after
-# delete_stream() has been implemented.
-
import asyncio
import os
import secrets
import string
+from collections.abc import AsyncGenerator
from pathlib import Path
import pytest
@@ -37,9 +35,32 @@ from apache_iggy import IggyClient
from .utils import get_server_config, wait_for_ping, wait_for_server
+_ROOT_USER_ID = 0
+
+
+async def _delete_test_resources(client: IggyClient) -> None:
+ streams = await client.get_streams()
+
+ for stream in streams:
+ topics = await client.get_topics(stream.id)
+ for topic in topics:
+ consumer_groups = await client.get_consumer_groups(stream.id, topic.id)
+ for consumer_group in consumer_groups:
+ await client.delete_consumer_group(
+ stream.id, topic.id, consumer_group.id
+ )
+
+ for stream in streams:
+ await client.delete_stream(stream.id)
-@pytest.fixture(scope="session")
-async def iggy_client() -> IggyClient:
+ users = await client.get_users()
+ for user in users:
+ if user.id != _ROOT_USER_ID:
+ await client.delete_user(user.id)
+
+
+@pytest.fixture(scope="session", autouse=True)
+async def iggy_client() -> AsyncGenerator[IggyClient, None]:
"""
Create and configure an Iggy client for testing.
@@ -50,7 +71,7 @@ async def iggy_client() -> IggyClient:
4. Authenticates with default credentials
5. Verifies connectivity with ping
- Returns:
+ Yields:
IggyClient: Authenticated client ready for testing
"""
host, port = get_server_config()
@@ -68,7 +89,9 @@ async def iggy_client() -> IggyClient:
# Authenticate
await client.login_user("iggy", "iggy")
- return client
+ yield client
+
+ await _delete_test_resources(client)
@pytest.fixture
diff --git a/foreign/python/tests/test_stream.py b/foreign/python/tests/test_stream.py
index 2db391951..24e55e66c 100644
--- a/foreign/python/tests/test_stream.py
+++ b/foreign/python/tests/test_stream.py
@@ -213,11 +213,10 @@ class TestGetStreams:
self, iggy_client: IggyClient, unique_name
):
"""Test get_streams returns every stream created during the test."""
- # Reverse-alphabetical names so that id-ascending (creation) order
- # and name order disagree, proving the list isn't accidentally
- # name-sorted. The client fixture is session-scoped, so other tests
- # may have created streams; assert on the ones created here instead
- # of the full server view.
+ # Stream IDs can be reused after deletion, so creation order does not
+ # imply numeric ID order. The client fixture is session-scoped, so
+ # other tests may have created streams; assert on the ones created
+ # here instead of the full server view.
created = [unique_name(f"z{index}") for index in range(3, 0, -1)]
for name in created:
await iggy_client.create_stream(name)
@@ -226,7 +225,7 @@ class TestGetStreams:
created_names = set(created)
mine = [stream for stream in streams if stream.name in created_names]
- assert [stream.name for stream in mine] == created
+ assert {stream.name for stream in mine} == created_names
assert [stream.id for stream in mine] == sorted(stream.id for stream in mine)
assert all(stream.created_at > 0 for stream in mine)
assert all(stream.size_bytes == 0 for stream in mine)
diff --git a/foreign/python/uv.lock b/foreign/python/uv.lock
index 963b58acf..57766a231 100644
--- a/foreign/python/uv.lock
+++ b/foreign/python/uv.lock
@@ -19,7 +19,6 @@ all = [
{ name = "pytest-asyncio" },
{ name = "pytest-cov" },
{ name = "pytest-timeout" },
- { name = "pytest-xdist" },
{ name = "ruff" },
{ name = "testcontainers" },
]
@@ -33,7 +32,6 @@ testing = [
{ name = "pytest-asyncio" },
{ name = "pytest-cov" },
{ name = "pytest-timeout" },
- { name = "pytest-xdist" },
]
testing-docker = [
{ name = "testcontainers" },
@@ -53,8 +51,6 @@ requires-dist = [
{ name = "pytest-cov", marker = "extra == 'testing'", specifier = ">=4.0,<8.0" },
{ name = "pytest-timeout", marker = "extra == 'all'", specifier = ">=2.0,<3.0" },
{ name = "pytest-timeout", marker = "extra == 'testing'", specifier = ">=2.0,<3.0" },
- { name = "pytest-xdist", marker = "extra == 'all'", specifier = ">=3.0,<4.0" },
- { name = "pytest-xdist", marker = "extra == 'testing'", specifier = ">=3.0,<4.0" },
{ name = "ruff", marker = "extra == 'all'", specifier = ">=0.1.0,<1.0" },
{ name = "ruff", marker = "extra == 'dev'", specifier = ">=0.1.0,<1.0" },
{ name = "testcontainers", marker = "extra == 'all'", specifier = ">=4.15.0,<5.0" },
@@ -411,15 +407,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" },
]
-[[package]]
-name = "execnet"
-version = "2.1.2"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd", size = 166622, upload-time = "2025-11-12T09:56:37.75Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" },
-]
-
[[package]]
name = "idna"
version = "3.18"
@@ -566,19 +553,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2", size = 14382, upload-time = "2025-05-05T19:44:33.502Z" },
]
-[[package]]
-name = "pytest-xdist"
-version = "3.8.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "execnet" },
- { name = "pytest" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" },
-]
-
[[package]]
name = "python-dotenv"
version = "1.2.2"
(iggy) 11/11: fix precommit
Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
slbotbm pushed a commit to branch feat/add-python-stream-management-functions
in repository https://gitbox.apache.org/repos/asf/iggy.git
commit c92f914a2b3b6985c8c656a1617144d1a285059f
Author: Rimuksh Kansal <ni...@gmail.com>
AuthorDate: Mon Aug 31 16:37:09 2026 +0900
fix precommit
---
bdd/python/pylock.toml | 85 ++++++++++++++++++++++++++++++++---------
examples/python/pylock.toml | 33 ++++++++++++++--
foreign/python/pylock.toml | 93 ++++++++++++++++++++++++++++++++++++---------
3 files changed, 171 insertions(+), 40 deletions(-)
diff --git a/bdd/python/pylock.toml b/bdd/python/pylock.toml
index 5a3941503..5b45a7a9f 100644
--- a/bdd/python/pylock.toml
+++ b/bdd/python/pylock.toml
@@ -1,3 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
# This file was autogenerated by uv via the following command:
# uv export -o pylock.toml
lock-version = "1.0"
@@ -14,7 +31,9 @@ version = "1.2.0"
marker = "python_full_version < '3.11'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", upload-time = 2025-07-02T02:27:15Z, size = 69893, hashes = { sha256 = "a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", upload-time = 2025-07-02T02:27:14Z, size = 12313, hashes = { sha256 = "0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", upload-time = 2025-07-02T02:27:14Z, size = 12313, hashes = { sha256 = "0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5" } },
+]
[[packages]]
name = "colorama"
@@ -22,7 +41,9 @@ version = "0.4.6"
marker = "sys_platform == 'win32'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", upload-time = 2022-10-25T02:36:22Z, size = 27697, hashes = { sha256 = "08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } },
+]
[[packages]]
name = "coverage"
@@ -143,28 +164,36 @@ version = "1.3.1"
marker = "python_full_version < '3.11'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", upload-time = 2025-11-21T23:01:54Z, size = 30371, hashes = { sha256 = "8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", upload-time = 2025-11-21T23:01:53Z, size = 16740, hashes = { sha256 = "a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", upload-time = 2025-11-21T23:01:53Z, size = 16740, hashes = { sha256 = "a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598" } },
+]
[[packages]]
name = "gherkin-official"
version = "29.0.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/f3/d8/7a28537efd7638448f7512a0cce011d4e3bf1c7f4794ad4e9c87b3f1e98e/gherkin_official-29.0.0.tar.gz", upload-time = 2024-08-12T09:41:09Z, size = 32303, hashes = { sha256 = "dbea32561158f02280d7579d179b019160d072ce083197625e2f80a6776bb9eb" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/f8/fc/b86c22ad3b18d8324a9d6fe5a3b55403291d2bf7572ba6a16efa5aa88059/gherkin_official-29.0.0-py3-none-any.whl", upload-time = 2024-08-12T09:41:07Z, size = 37085, hashes = { sha256 = "26967b0d537a302119066742669e0e8b663e632769330be675457ae993e1d1bc" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f8/fc/b86c22ad3b18d8324a9d6fe5a3b55403291d2bf7572ba6a16efa5aa88059/gherkin_official-29.0.0-py3-none-any.whl", upload-time = 2024-08-12T09:41:07Z, size = 37085, hashes = { sha256 = "26967b0d537a302119066742669e0e8b663e632769330be675457ae993e1d1bc" } },
+]
[[packages]]
name = "iniconfig"
version = "2.3.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", upload-time = 2025-10-18T21:55:43Z, size = 20503, hashes = { sha256 = "c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", upload-time = 2025-10-18T21:55:41Z, size = 7484, hashes = { sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", upload-time = 2025-10-18T21:55:41Z, size = 7484, hashes = { sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" } },
+]
[[packages]]
name = "mako"
version = "1.3.12"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/00/62/791b31e69ae182791ec67f04850f2f062716bbd205483d63a215f3e062d3/mako-1.3.12.tar.gz", upload-time = 2026-04-28T19:01:08Z, size = 400219, hashes = { sha256 = "9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/bc/b1/a0ec7a5a9db730a08daef1fdfb8090435b82465abbf758a596f0ea88727e/mako-1.3.12-py3-none-any.whl", upload-time = 2026-04-28T19:01:10Z, size = 78521, hashes = { sha256 = "8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/bc/b1/a0ec7a5a9db730a08daef1fdfb8090435b82465abbf758a596f0ea88727e/mako-1.3.12-py3-none-any.whl", upload-time = 2026-04-28T19:01:10Z, size = 78521, hashes = { sha256 = "8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9" } },
+]
[[packages]]
name = "markupsafe"
@@ -256,35 +285,45 @@ name = "packaging"
version = "26.2"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", upload-time = 2026-04-24T20:15:23Z, size = 228134, hashes = { sha256 = "ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", upload-time = 2026-04-24T20:15:22Z, size = 100195, hashes = { sha256 = "5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", upload-time = 2026-04-24T20:15:22Z, size = 100195, hashes = { sha256 = "5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e" } },
+]
[[packages]]
name = "parse"
version = "1.22.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/7b/a2/dd269daedd5ac3a244ca7855b4878d8655393fd4554d5c24a56bc31e302a/parse-1.22.0.tar.gz", upload-time = 2026-05-02T01:36:25Z, size = 36767, hashes = { sha256 = "d4987d68ccf08b6ba3bf80b5004ff7de61c4337cba2d8350ae5c9925794979d9" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/69/3a/0c2cf5922c6133b74c1cebe4b66f6949818e2cf8121aa59e3ebcd64ac6ac/parse-1.22.0-py2.py3-none-any.whl", upload-time = 2026-05-02T01:36:24Z, size = 20839, hashes = { sha256 = "eea8ed34e2614cea65d9c1d4af9cb68cce26aea13d44bdcaf83c1b40884fe945" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/69/3a/0c2cf5922c6133b74c1cebe4b66f6949818e2cf8121aa59e3ebcd64ac6ac/parse-1.22.0-py2.py3-none-any.whl", upload-time = 2026-05-02T01:36:24Z, size = 20839, hashes = { sha256 = "eea8ed34e2614cea65d9c1d4af9cb68cce26aea13d44bdcaf83c1b40884fe945" } },
+]
[[packages]]
name = "parse-type"
version = "0.6.6"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/19/ea/42ba6ce0abba04ab6e0b997dcb9b528a4661b62af1fe1b0d498120d5ea78/parse_type-0.6.6.tar.gz", upload-time = 2025-08-11T22:53:48Z, size = 98012, hashes = { sha256 = "513a3784104839770d690e04339a8b4d33439fcd5dd99f2e4580f9fc1097bfb2" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/85/8d/eef3d8cdccc32abdd91b1286884c99b8c3a6d3b135affcc2a7a0f383bb32/parse_type-0.6.6-py2.py3-none-any.whl", upload-time = 2025-08-11T22:53:46Z, size = 27085, hashes = { sha256 = "3ca79bbe71e170dfccc8ec6c341edfd1c2a0fc1e5cfd18330f93af938de2348c" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/85/8d/eef3d8cdccc32abdd91b1286884c99b8c3a6d3b135affcc2a7a0f383bb32/parse_type-0.6.6-py2.py3-none-any.whl", upload-time = 2025-08-11T22:53:46Z, size = 27085, hashes = { sha256 = "3ca79bbe71e170dfccc8ec6c341edfd1c2a0fc1e5cfd18330f93af938de2348c" } },
+]
[[packages]]
name = "pluggy"
version = "1.6.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", upload-time = 2025-05-15T12:30:07Z, size = 69412, hashes = { sha256 = "7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", upload-time = 2025-05-15T12:30:06Z, size = 20538, hashes = { sha256 = "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", upload-time = 2025-05-15T12:30:06Z, size = 20538, hashes = { sha256 = "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" } },
+]
[[packages]]
name = "pygments"
version = "2.20.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", upload-time = 2026-03-29T13:29:33Z, size = 4955991, hashes = { sha256 = "6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", upload-time = 2026-03-29T13:29:30Z, size = 1231151, hashes = { sha256 = "81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", upload-time = 2026-03-29T13:29:30Z, size = 1231151, hashes = { sha256 = "81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176" } },
+]
[[packages]]
name = "pyrefly"
@@ -310,28 +349,36 @@ name = "pytest"
version = "9.1.1"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", upload-time = 2026-06-19T10:58:32Z, size = 1636369, hashes = { sha256 = "1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", upload-time = 2026-06-19T10:58:31Z, size = 386536, hashes = { sha256 = "37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", upload-time = 2026-06-19T10:58:31Z, size = 386536, hashes = { sha256 = "37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c" } },
+]
[[packages]]
name = "pytest-asyncio"
version = "1.4.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/43/7c/d36d04db312ecf4298932ef77e6e4a9e8ad017906e24e34f0b0c361a2473/pytest_asyncio-1.4.0.tar.gz", upload-time = 2026-05-26T09:56:04Z, size = 58514, hashes = { sha256 = "c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", upload-time = 2026-05-26T09:56:02Z, size = 16930, hashes = { sha256 = "933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", upload-time = 2026-05-26T09:56:02Z, size = 16930, hashes = { sha256 = "933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1" } },
+]
[[packages]]
name = "pytest-bdd"
version = "8.1.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/2d/2f/14c2e55372a5718a93b56aea48cd6ccc15d2d245364e516cd7b19bbd07ad/pytest_bdd-8.1.0.tar.gz", upload-time = 2024-12-05T21:45:58Z, size = 56147, hashes = { sha256 = "ef0896c5cd58816dc49810e8ff1d632f4a12019fb3e49959b2d349ffc1c9bfb5" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/9f/7d/1461076b0cc9a9e6fa8b51b9dea2677182ba8bc248d99d95ca321f2c666f/pytest_bdd-8.1.0-py3-none-any.whl", upload-time = 2024-12-05T21:45:56Z, size = 49149, hashes = { sha256 = "2124051e71a05ad7db15296e39013593f72ebf96796e1b023a40e5453c47e5fb" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/9f/7d/1461076b0cc9a9e6fa8b51b9dea2677182ba8bc248d99d95ca321f2c666f/pytest_bdd-8.1.0-py3-none-any.whl", upload-time = 2024-12-05T21:45:56Z, size = 49149, hashes = { sha256 = "2124051e71a05ad7db15296e39013593f72ebf96796e1b023a40e5453c47e5fb" } },
+]
[[packages]]
name = "pytest-cov"
version = "7.1.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", upload-time = 2026-03-21T20:11:16Z, size = 55592, hashes = { sha256 = "30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", upload-time = 2026-03-21T20:11:14Z, size = 22876, hashes = { sha256 = "a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", upload-time = 2026-03-21T20:11:14Z, size = 22876, hashes = { sha256 = "a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678" } },
+]
[[packages]]
name = "ruff"
@@ -363,7 +410,9 @@ name = "six"
version = "1.17.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", upload-time = 2024-12-04T17:35:28Z, size = 34031, hashes = { sha256 = "ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", upload-time = 2024-12-04T17:35:26Z, size = 11050, hashes = { sha256 = "4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", upload-time = 2024-12-04T17:35:26Z, size = 11050, hashes = { sha256 = "4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274" } },
+]
[[packages]]
name = "tomli"
@@ -425,4 +474,6 @@ name = "typing-extensions"
version = "4.15.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", upload-time = 2025-08-25T13:49:26Z, size = 109391, hashes = { sha256 = "0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", upload-time = 2025-08-25T13:49:24Z, size = 44614, hashes = { sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", upload-time = 2025-08-25T13:49:24Z, size = 44614, hashes = { sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" } },
+]
diff --git a/examples/python/pylock.toml b/examples/python/pylock.toml
index 834be3fd6..4d438f327 100644
--- a/examples/python/pylock.toml
+++ b/examples/python/pylock.toml
@@ -1,3 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
# This file was autogenerated by uv via the following command:
# uv export -o pylock.toml
lock-version = "1.0"
@@ -13,7 +30,9 @@ name = "argparse"
version = "1.4.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/18/dd/e617cfc3f6210ae183374cd9f6a26b20514bbb5a792af97949c5aacddf0f/argparse-1.4.0.tar.gz", upload-time = 2015-09-12T20:22:16Z, size = 70508, hashes = { sha256 = "62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl", upload-time = 2015-09-14T16:03:16Z, size = 23000, hashes = { sha256 = "c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl", upload-time = 2015-09-14T16:03:16Z, size = 23000, hashes = { sha256 = "c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314" } },
+]
[[packages]]
name = "colorama"
@@ -21,14 +40,18 @@ version = "0.4.6"
marker = "sys_platform == 'win32'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", upload-time = 2022-10-25T02:36:22Z, size = 27697, hashes = { sha256 = "08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } },
+]
[[packages]]
name = "loguru"
version = "0.7.3"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", upload-time = 2024-12-06T11:20:56Z, size = 63559, hashes = { sha256 = "19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", upload-time = 2024-12-06T11:20:54Z, size = 61595, hashes = { sha256 = "31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", upload-time = 2024-12-06T11:20:54Z, size = 61595, hashes = { sha256 = "31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c" } },
+]
[[packages]]
name = "pyrefly"
@@ -80,4 +103,6 @@ version = "1.2.0"
marker = "sys_platform == 'win32'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", upload-time = 2024-12-07T15:28:28Z, size = 4867, hashes = { sha256 = "ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", upload-time = 2024-12-07T15:28:26Z, size = 4083, hashes = { sha256 = "95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", upload-time = 2024-12-07T15:28:26Z, size = 4083, hashes = { sha256 = "95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390" } },
+]
diff --git a/foreign/python/pylock.toml b/foreign/python/pylock.toml
index d963b1010..2a7f43e7f 100644
--- a/foreign/python/pylock.toml
+++ b/foreign/python/pylock.toml
@@ -1,3 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
# This file was autogenerated by uv via the following command:
# uv export --format pylock.toml --output-file pylock.toml --all-extras
lock-version = "1.0"
@@ -14,14 +31,18 @@ version = "1.2.0"
marker = "python_full_version < '3.11'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", upload-time = 2025-07-02T02:27:15Z, size = 69893, hashes = { sha256 = "a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", upload-time = 2025-07-02T02:27:14Z, size = 12313, hashes = { sha256 = "0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", upload-time = 2025-07-02T02:27:14Z, size = 12313, hashes = { sha256 = "0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5" } },
+]
[[packages]]
name = "certifi"
version = "2026.4.22"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", upload-time = 2026-04-22T11:26:11Z, size = 137077, hashes = { sha256 = "8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", upload-time = 2026-04-22T11:26:09Z, size = 135707, hashes = { sha256 = "3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", upload-time = 2026-04-22T11:26:09Z, size = 135707, hashes = { sha256 = "3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a" } },
+]
[[packages]]
name = "charset-normalizer"
@@ -134,7 +155,9 @@ version = "0.4.6"
marker = "sys_platform == 'win32'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", upload-time = 2022-10-25T02:36:22Z, size = 27697, hashes = { sha256 = "08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } },
+]
[[packages]]
name = "coverage"
@@ -254,7 +277,9 @@ name = "docker"
version = "7.1.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/91/9b/4a2ea29aeba62471211598dac5d96825bb49348fa07e906ea930394a83ce/docker-7.1.0.tar.gz", upload-time = 2024-05-23T11:13:57Z, size = 117834, hashes = { sha256 = "ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl", upload-time = 2024-05-23T11:13:55Z, size = 147774, hashes = { sha256 = "c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl", upload-time = 2024-05-23T11:13:55Z, size = 147774, hashes = { sha256 = "c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0" } },
+]
[[packages]]
name = "exceptiongroup"
@@ -262,21 +287,27 @@ version = "1.3.1"
marker = "python_full_version < '3.11'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", upload-time = 2025-11-21T23:01:54Z, size = 30371, hashes = { sha256 = "8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", upload-time = 2025-11-21T23:01:53Z, size = 16740, hashes = { sha256 = "a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", upload-time = 2025-11-21T23:01:53Z, size = 16740, hashes = { sha256 = "a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598" } },
+]
[[packages]]
name = "idna"
version = "3.15"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/82/77/7b3966d0b9d1d31a36ddf1746926a11dface89a83409bf1483f0237aa758/idna-3.15.tar.gz", upload-time = 2026-05-12T22:45:57Z, size = 199245, hashes = { sha256 = "ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl", upload-time = 2026-05-12T22:45:55Z, size = 72340, hashes = { sha256 = "048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl", upload-time = 2026-05-12T22:45:55Z, size = 72340, hashes = { sha256 = "048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8" } },
+]
[[packages]]
name = "iniconfig"
version = "2.3.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", upload-time = 2025-10-18T21:55:43Z, size = 20503, hashes = { sha256 = "c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", upload-time = 2025-10-18T21:55:41Z, size = 7484, hashes = { sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", upload-time = 2025-10-18T21:55:41Z, size = 7484, hashes = { sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" } },
+]
[[packages]]
name = "maturin"
@@ -304,21 +335,27 @@ name = "packaging"
version = "26.2"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", upload-time = 2026-04-24T20:15:23Z, size = 228134, hashes = { sha256 = "ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", upload-time = 2026-04-24T20:15:22Z, size = 100195, hashes = { sha256 = "5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", upload-time = 2026-04-24T20:15:22Z, size = 100195, hashes = { sha256 = "5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e" } },
+]
[[packages]]
name = "pluggy"
version = "1.6.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", upload-time = 2025-05-15T12:30:07Z, size = 69412, hashes = { sha256 = "7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", upload-time = 2025-05-15T12:30:06Z, size = 20538, hashes = { sha256 = "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", upload-time = 2025-05-15T12:30:06Z, size = 20538, hashes = { sha256 = "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" } },
+]
[[packages]]
name = "pygments"
version = "2.20.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", upload-time = 2026-03-29T13:29:33Z, size = 4955991, hashes = { sha256 = "6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", upload-time = 2026-03-29T13:29:30Z, size = 1231151, hashes = { sha256 = "81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", upload-time = 2026-03-29T13:29:30Z, size = 1231151, hashes = { sha256 = "81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176" } },
+]
[[packages]]
name = "pyrefly"
@@ -344,35 +381,45 @@ name = "pytest"
version = "9.1.1"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", upload-time = 2026-06-19T10:58:32Z, size = 1636369, hashes = { sha256 = "1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", upload-time = 2026-06-19T10:58:31Z, size = 386536, hashes = { sha256 = "37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", upload-time = 2026-06-19T10:58:31Z, size = 386536, hashes = { sha256 = "37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c" } },
+]
[[packages]]
name = "pytest-asyncio"
version = "1.4.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/43/7c/d36d04db312ecf4298932ef77e6e4a9e8ad017906e24e34f0b0c361a2473/pytest_asyncio-1.4.0.tar.gz", upload-time = 2026-05-26T09:56:04Z, size = 58514, hashes = { sha256 = "c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", upload-time = 2026-05-26T09:56:02Z, size = 16930, hashes = { sha256 = "933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", upload-time = 2026-05-26T09:56:02Z, size = 16930, hashes = { sha256 = "933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1" } },
+]
[[packages]]
name = "pytest-cov"
version = "7.1.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", upload-time = 2026-03-21T20:11:16Z, size = 55592, hashes = { sha256 = "30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", upload-time = 2026-03-21T20:11:14Z, size = 22876, hashes = { sha256 = "a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", upload-time = 2026-03-21T20:11:14Z, size = 22876, hashes = { sha256 = "a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678" } },
+]
[[packages]]
name = "pytest-timeout"
version = "2.4.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/ac/82/4c9ecabab13363e72d880f2fb504c5f750433b2b6f16e99f4ec21ada284c/pytest_timeout-2.4.0.tar.gz", upload-time = 2025-05-05T19:44:34Z, size = 17973, hashes = { sha256 = "7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", upload-time = 2025-05-05T19:44:33Z, size = 14382, hashes = { sha256 = "c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", upload-time = 2025-05-05T19:44:33Z, size = 14382, hashes = { sha256 = "c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2" } },
+]
[[packages]]
name = "python-dotenv"
version = "1.2.2"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", upload-time = 2026-03-01T16:00:26Z, size = 50135, hashes = { sha256 = "2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", upload-time = 2026-03-01T16:00:25Z, size = 22101, hashes = { sha256 = "1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", upload-time = 2026-03-01T16:00:25Z, size = 22101, hashes = { sha256 = "1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a" } },
+]
[[packages]]
name = "pywin32"
@@ -402,7 +449,9 @@ name = "requests"
version = "2.34.2"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", upload-time = 2026-05-14T19:25:27Z, size = 142856, hashes = { sha256 = "f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", upload-time = 2026-05-14T19:25:26Z, size = 73075, hashes = { sha256 = "2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", upload-time = 2026-05-14T19:25:26Z, size = 73075, hashes = { sha256 = "2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0" } },
+]
[[packages]]
name = "ruff"
@@ -434,7 +483,9 @@ name = "testcontainers"
version = "4.15.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/4b/13/2cc466bddf26d0085f30a2b2bd56b7f8708b54a54db833eec97c5c69129b/testcontainers-4.15.0.tar.gz", upload-time = 2026-07-24T23:08:01Z, size = 95340, hashes = { sha256 = "085cde086337632e19002719460b7b80bbab2bdd51bb3ea04f77d0de96504706" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/00/7e/424aac8b355597835deb333e757a0e94b5ccf38ad00f07fe6ed1f4e17c88/testcontainers-4.15.0-py3-none-any.whl", upload-time = 2026-07-24T23:08:00Z, size = 160771, hashes = { sha256 = "8796c14e76604031ad39cf0ed3b8e9806283a1fbf5270965c2b1c594caa31b74" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/00/7e/424aac8b355597835deb333e757a0e94b5ccf38ad00f07fe6ed1f4e17c88/testcontainers-4.15.0-py3-none-any.whl", upload-time = 2026-07-24T23:08:00Z, size = 160771, hashes = { sha256 = "8796c14e76604031ad39cf0ed3b8e9806283a1fbf5270965c2b1c594caa31b74" } },
+]
[[packages]]
name = "tomli"
@@ -496,14 +547,18 @@ name = "typing-extensions"
version = "4.15.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", upload-time = 2025-08-25T13:49:26Z, size = 109391, hashes = { sha256 = "0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", upload-time = 2025-08-25T13:49:24Z, size = 44614, hashes = { sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", upload-time = 2025-08-25T13:49:24Z, size = 44614, hashes = { sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" } },
+]
[[packages]]
name = "urllib3"
version = "2.7.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", upload-time = 2026-05-07T16:13:18Z, size = 433602, hashes = { sha256 = "231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c" } }
-wheels = [{ url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", upload-time = 2026-05-07T16:13:17Z, size = 131087, hashes = { sha256 = "9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897" } }]
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", upload-time = 2026-05-07T16:13:17Z, size = 131087, hashes = { sha256 = "9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897" } },
+]
[[packages]]
name = "wrapt"
(iggy) 06/11: fixes
Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
slbotbm pushed a commit to branch feat/add-python-stream-management-functions
in repository https://gitbox.apache.org/repos/asf/iggy.git
commit 76520fe4a52cfd8e52bbc0c6394be33513557a5c
Author: Rimuksh Kansal <ni...@gmail.com>
AuthorDate: Sun Aug 16 16:59:27 2026 +0900
fixes
---
foreign/python/apache_iggy.pyi | 51 +++++++++++++++++++++---------------------
foreign/python/src/client.rs | 2 +-
foreign/python/src/options.rs | 1 +
3 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/foreign/python/apache_iggy.pyi b/foreign/python/apache_iggy.pyi
index 80b4c430e..c4b193a2d 100644
--- a/foreign/python/apache_iggy.pyi
+++ b/foreign/python/apache_iggy.pyi
@@ -873,6 +873,27 @@ class IggyClient:
Sends a ping request to the server to check connectivity.
Raises `RuntimeError` if the connection fails.
"""
+ def describe_options(
+ self, scope: builtins.str
+ ) -> collections.abc.Awaitable[list[OptionSpec]]:
+ r"""
+ Describe the option catalog for a resource scope.
+
+ This is the discovery surface for the `options` argument on
+ `create_topic`/`update_topic`: a key outside the catalog is refused at
+ create, and the binary transports carry only the error code back.
+
+ Args:
+ scope: One of `"topic"`, `"stream"`, `"user"`.
+
+ Returns:
+ An awaitable that resolves to `list[OptionSpec]`, empty for a scope
+ with no keys yet.
+
+ Raises:
+ ValueError: If the scope name is not one of the three above.
+ RuntimeError: If the request fails.
+ """
def login_user(
self, username: builtins.str, password: builtins.str
) -> collections.abc.Awaitable[None]:
@@ -1035,27 +1056,6 @@ class IggyClient:
Returns the stream details, or `None` if the stream does not exist.
Raises `RuntimeError` on failure.
"""
- def describe_options(
- self, scope: builtins.str
- ) -> collections.abc.Awaitable[builtins.list[OptionSpec]]:
- r"""
- Describe the option catalog for a resource scope.
-
- This is the discovery surface for the `options` argument on
- `create_topic`/`update_topic`: a key outside the catalog is refused at
- create, and the binary transports carry only the error code back.
-
- Args:
- scope: One of `"topic"`, `"stream"`, `"user"`.
-
- Returns:
- An awaitable that resolves to `list[OptionSpec]`, empty for a scope
- with no keys yet.
-
- Raises:
- ValueError: If the scope name is not one of the three above.
- RuntimeError: If the request fails.
- """
def get_streams(self) -> collections.abc.Awaitable[list[Stream]]:
r"""
Return all streams visible to the authenticated user.
@@ -1915,6 +1915,7 @@ class SendMessagesResponse:
with an offset a client has already recorded.
"""
+@typing.final
class Stream:
r"""
Summary information returned by `IggyClient.get_streams()`.
@@ -2222,8 +2223,8 @@ class Topic:
r"""
Options admission resolved for the keys the client did not send.
- Same shape as `options`. These would have resolved differently under
- another server configuration.
+ Same shape as [`Self::options`]. These would have resolved differently
+ under another server configuration.
"""
@typing.final
@@ -2287,8 +2288,8 @@ class TopicDetails:
r"""
Options admission resolved for the keys the client did not send.
- Same shape as `options`. These would have resolved differently under
- another server configuration.
+ Same shape as [`Self::options`]. These would have resolved differently
+ under another server configuration.
"""
@property
def partitions(self) -> builtins.list[Partition]:
diff --git a/foreign/python/src/client.rs b/foreign/python/src/client.rs
index 796c8ac9b..9fab3944c 100644
--- a/foreign/python/src/client.rs
+++ b/foreign/python/src/client.rs
@@ -552,7 +552,7 @@ impl IggyClient {
let inner = self.inner.clone();
future_into_py(py, async move {
inner
- .update_stream(&stream_id, &name)
+ .update_stream(&stream_id, &name, &StreamUpdateOptions::default())
.await
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?;
Ok(())
diff --git a/foreign/python/src/options.rs b/foreign/python/src/options.rs
index c3eee8cdd..fa489c550 100644
--- a/foreign/python/src/options.rs
+++ b/foreign/python/src/options.rs
@@ -62,6 +62,7 @@ impl OptionSpec {
///
/// The same type message user headers use, so the usual accessors read it;
/// options ride that codec.
+ #[gen_stub(override_return_type(type_repr = "HeaderValue | None"))]
#[getter]
pub fn default_value<'a>(&self, py: Python<'a>) -> PyResult<Option<Bound<'a, HeaderValue>>> {
if self.inner.default_value.is_empty() {
(iggy) 07/11: test fixture fixes
Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
slbotbm pushed a commit to branch feat/add-python-stream-management-functions
in repository https://gitbox.apache.org/repos/asf/iggy.git
commit efee3daf0dcadae85b897004d6c081726e767f8a
Author: Rimuksh Kansal <ni...@gmail.com>
AuthorDate: Sun Aug 16 17:18:16 2026 +0900
test fixture fixes
---
foreign/python/tests/conftest.py | 60 ++++++++++++++++++++--------------------
1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/foreign/python/tests/conftest.py b/foreign/python/tests/conftest.py
index d80c7776d..5c8d15a1c 100644
--- a/foreign/python/tests/conftest.py
+++ b/foreign/python/tests/conftest.py
@@ -23,6 +23,7 @@ and connecting to Iggy servers in various configurations.
"""
import asyncio
+import contextlib
import os
import secrets
import string
@@ -35,32 +36,9 @@ from apache_iggy import IggyClient
from .utils import get_server_config, wait_for_ping, wait_for_server
-_ROOT_USER_ID = 0
-
-async def _delete_test_resources(client: IggyClient) -> None:
- streams = await client.get_streams()
-
- for stream in streams:
- topics = await client.get_topics(stream.id)
- for topic in topics:
- consumer_groups = await client.get_consumer_groups(stream.id, topic.id)
- for consumer_group in consumer_groups:
- await client.delete_consumer_group(
- stream.id, topic.id, consumer_group.id
- )
-
- for stream in streams:
- await client.delete_stream(stream.id)
-
- users = await client.get_users()
- for user in users:
- if user.id != _ROOT_USER_ID:
- await client.delete_user(user.id)
-
-
-@pytest.fixture(scope="session", autouse=True)
-async def iggy_client() -> AsyncGenerator[IggyClient, None]:
+@pytest.fixture(scope="session")
+async def iggy_client() -> IggyClient:
"""
Create and configure an Iggy client for testing.
@@ -71,7 +49,7 @@ async def iggy_client() -> AsyncGenerator[IggyClient, None]:
4. Authenticates with default credentials
5. Verifies connectivity with ping
- Yields:
+ Returns:
IggyClient: Authenticated client ready for testing
"""
host, port = get_server_config()
@@ -89,13 +67,17 @@ async def iggy_client() -> AsyncGenerator[IggyClient, None]:
# Authenticate
await client.login_user("iggy", "iggy")
- yield client
+ return client
- await _delete_test_resources(client)
+
+@pytest.fixture
+def issued_names() -> set[str]:
+ """Return names created by unique_name in one test."""
+ return set()
@pytest.fixture
-def unique_name():
+def unique_name(issued_names: set[str]):
"""Return a factory for generating unique test names."""
def make_name(
@@ -126,11 +108,29 @@ def unique_name():
+ min_suffix_bytes
)
suffix = "".join(secrets.choice(alphabet) for _ in range(suffix_bytes))
- return f"{prefix}{suffix}"
+ name = f"{prefix}{suffix}"
+ issued_names.add(name)
+ return name
return make_name
+@pytest.fixture(autouse=True)
+async def cleanup_streams(
+ request: pytest.FixtureRequest, issued_names: set[str]
+) -> AsyncGenerator[None, None]:
+ """Delete streams created by the current test."""
+ yield
+
+ if not issued_names:
+ return
+
+ client = request.getfixturevalue("iggy_client")
+ for name in issued_names:
+ with contextlib.suppress(RuntimeError):
+ await client.delete_stream(name)
+
+
@pytest.fixture(scope="session", autouse=True)
def configure_asyncio():
"""Configure asyncio settings for tests."""
(iggy) 10/11: address comments
Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
slbotbm pushed a commit to branch feat/add-python-stream-management-functions
in repository https://gitbox.apache.org/repos/asf/iggy.git
commit 88ba2b33515f90bda4c98452bcf7f520583d4634
Author: Rimuksh Kansal <ni...@gmail.com>
AuthorDate: Mon Aug 31 15:49:47 2026 +0900
address comments
---
bdd/python/pylock.toml | 155 +++++++++----------------
examples/python/pylock.toml | 95 ++++++----------
foreign/python/apache_iggy.pyi | 38 ++++---
foreign/python/pylock.toml | 219 ++++++++++++------------------------
foreign/python/src/client.rs | 32 ++++--
foreign/python/src/stream.rs | 8 ++
foreign/python/src/topic.rs | 23 +++-
foreign/python/tests/conftest.py | 6 +-
foreign/python/tests/test_stream.py | 34 ++++--
9 files changed, 268 insertions(+), 342 deletions(-)
diff --git a/bdd/python/pylock.toml b/bdd/python/pylock.toml
index 4d2968d09..5a3941503 100644
--- a/bdd/python/pylock.toml
+++ b/bdd/python/pylock.toml
@@ -1,20 +1,3 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
# This file was autogenerated by uv via the following command:
# uv export -o pylock.toml
lock-version = "1.0"
@@ -31,9 +14,7 @@ version = "1.2.0"
marker = "python_full_version < '3.11'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", upload-time = 2025-07-02T02:27:15Z, size = 69893, hashes = { sha256 = "a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", upload-time = 2025-07-02T02:27:14Z, size = 12313, hashes = { sha256 = "0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", upload-time = 2025-07-02T02:27:14Z, size = 12313, hashes = { sha256 = "0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5" } }]
[[packages]]
name = "colorama"
@@ -41,9 +22,7 @@ version = "0.4.6"
marker = "sys_platform == 'win32'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", upload-time = 2022-10-25T02:36:22Z, size = 27697, hashes = { sha256 = "08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } }]
[[packages]]
name = "coverage"
@@ -164,36 +143,28 @@ version = "1.3.1"
marker = "python_full_version < '3.11'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", upload-time = 2025-11-21T23:01:54Z, size = 30371, hashes = { sha256 = "8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", upload-time = 2025-11-21T23:01:53Z, size = 16740, hashes = { sha256 = "a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", upload-time = 2025-11-21T23:01:53Z, size = 16740, hashes = { sha256 = "a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598" } }]
[[packages]]
name = "gherkin-official"
version = "29.0.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/f3/d8/7a28537efd7638448f7512a0cce011d4e3bf1c7f4794ad4e9c87b3f1e98e/gherkin_official-29.0.0.tar.gz", upload-time = 2024-08-12T09:41:09Z, size = 32303, hashes = { sha256 = "dbea32561158f02280d7579d179b019160d072ce083197625e2f80a6776bb9eb" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/f8/fc/b86c22ad3b18d8324a9d6fe5a3b55403291d2bf7572ba6a16efa5aa88059/gherkin_official-29.0.0-py3-none-any.whl", upload-time = 2024-08-12T09:41:07Z, size = 37085, hashes = { sha256 = "26967b0d537a302119066742669e0e8b663e632769330be675457ae993e1d1bc" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/f8/fc/b86c22ad3b18d8324a9d6fe5a3b55403291d2bf7572ba6a16efa5aa88059/gherkin_official-29.0.0-py3-none-any.whl", upload-time = 2024-08-12T09:41:07Z, size = 37085, hashes = { sha256 = "26967b0d537a302119066742669e0e8b663e632769330be675457ae993e1d1bc" } }]
[[packages]]
name = "iniconfig"
version = "2.3.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", upload-time = 2025-10-18T21:55:43Z, size = 20503, hashes = { sha256 = "c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", upload-time = 2025-10-18T21:55:41Z, size = 7484, hashes = { sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", upload-time = 2025-10-18T21:55:41Z, size = 7484, hashes = { sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" } }]
[[packages]]
name = "mako"
version = "1.3.12"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/00/62/791b31e69ae182791ec67f04850f2f062716bbd205483d63a215f3e062d3/mako-1.3.12.tar.gz", upload-time = 2026-04-28T19:01:08Z, size = 400219, hashes = { sha256 = "9f778e93289bd410bb35daadeb4fc66d95a746f0b75777b942088b7fd7af550a" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/bc/b1/a0ec7a5a9db730a08daef1fdfb8090435b82465abbf758a596f0ea88727e/mako-1.3.12-py3-none-any.whl", upload-time = 2026-04-28T19:01:10Z, size = 78521, hashes = { sha256 = "8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/bc/b1/a0ec7a5a9db730a08daef1fdfb8090435b82465abbf758a596f0ea88727e/mako-1.3.12-py3-none-any.whl", upload-time = 2026-04-28T19:01:10Z, size = 78521, hashes = { sha256 = "8f61569480282dbf557145ce441e4ba888be453c30989f879f0d652e39f53ea9" } }]
[[packages]]
name = "markupsafe"
@@ -285,122 +256,106 @@ name = "packaging"
version = "26.2"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", upload-time = 2026-04-24T20:15:23Z, size = 228134, hashes = { sha256 = "ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", upload-time = 2026-04-24T20:15:22Z, size = 100195, hashes = { sha256 = "5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", upload-time = 2026-04-24T20:15:22Z, size = 100195, hashes = { sha256 = "5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e" } }]
[[packages]]
name = "parse"
version = "1.22.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/7b/a2/dd269daedd5ac3a244ca7855b4878d8655393fd4554d5c24a56bc31e302a/parse-1.22.0.tar.gz", upload-time = 2026-05-02T01:36:25Z, size = 36767, hashes = { sha256 = "d4987d68ccf08b6ba3bf80b5004ff7de61c4337cba2d8350ae5c9925794979d9" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/69/3a/0c2cf5922c6133b74c1cebe4b66f6949818e2cf8121aa59e3ebcd64ac6ac/parse-1.22.0-py2.py3-none-any.whl", upload-time = 2026-05-02T01:36:24Z, size = 20839, hashes = { sha256 = "eea8ed34e2614cea65d9c1d4af9cb68cce26aea13d44bdcaf83c1b40884fe945" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/69/3a/0c2cf5922c6133b74c1cebe4b66f6949818e2cf8121aa59e3ebcd64ac6ac/parse-1.22.0-py2.py3-none-any.whl", upload-time = 2026-05-02T01:36:24Z, size = 20839, hashes = { sha256 = "eea8ed34e2614cea65d9c1d4af9cb68cce26aea13d44bdcaf83c1b40884fe945" } }]
[[packages]]
name = "parse-type"
version = "0.6.6"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/19/ea/42ba6ce0abba04ab6e0b997dcb9b528a4661b62af1fe1b0d498120d5ea78/parse_type-0.6.6.tar.gz", upload-time = 2025-08-11T22:53:48Z, size = 98012, hashes = { sha256 = "513a3784104839770d690e04339a8b4d33439fcd5dd99f2e4580f9fc1097bfb2" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/85/8d/eef3d8cdccc32abdd91b1286884c99b8c3a6d3b135affcc2a7a0f383bb32/parse_type-0.6.6-py2.py3-none-any.whl", upload-time = 2025-08-11T22:53:46Z, size = 27085, hashes = { sha256 = "3ca79bbe71e170dfccc8ec6c341edfd1c2a0fc1e5cfd18330f93af938de2348c" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/85/8d/eef3d8cdccc32abdd91b1286884c99b8c3a6d3b135affcc2a7a0f383bb32/parse_type-0.6.6-py2.py3-none-any.whl", upload-time = 2025-08-11T22:53:46Z, size = 27085, hashes = { sha256 = "3ca79bbe71e170dfccc8ec6c341edfd1c2a0fc1e5cfd18330f93af938de2348c" } }]
[[packages]]
name = "pluggy"
version = "1.6.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", upload-time = 2025-05-15T12:30:07Z, size = 69412, hashes = { sha256 = "7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", upload-time = 2025-05-15T12:30:06Z, size = 20538, hashes = { sha256 = "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", upload-time = 2025-05-15T12:30:06Z, size = 20538, hashes = { sha256 = "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" } }]
[[packages]]
name = "pygments"
version = "2.20.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", upload-time = 2026-03-29T13:29:33Z, size = 4955991, hashes = { sha256 = "6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", upload-time = 2026-03-29T13:29:30Z, size = 1231151, hashes = { sha256 = "81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", upload-time = 2026-03-29T13:29:30Z, size = 1231151, hashes = { sha256 = "81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176" } }]
[[packages]]
name = "pyrefly"
-version = "1.0.0"
+version = "1.2.0"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/9f/3a/9045b0097ac58979c7c30a4fa0e673db942d4adbc7b6d439bd54ae58c441/pyrefly-1.0.0.tar.gz", upload-time = 2026-05-12T20:12:46Z, size = 5677995, hashes = { sha256 = "5c2b810ffcebd84be71de5df1223651edee951653a66935c6f091e957c452455" } }
+sdist = { url = "https://files.pythonhosted.org/packages/89/01/a86e9f24722b095c3f88e3616132b75a21b0df53804bdc6a45314dd4d93c/pyrefly-1.2.0.tar.gz", upload-time = 2026-08-01T02:56:27Z, size = 6243654, hashes = { sha256 = "5485f960fc2481617068c918335c39ab1507ef90b6b5bd35bf57726e60e73185" } }
wheels = [
- { url = "https://files.pythonhosted.org/packages/f4/c6/90788819bac9c61dd7bacba53b79f3c12d47ccbe5e51b3d6d89f2387e1d2/pyrefly-1.0.0-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-05-12T20:12:20Z, size = 13122950, hashes = { sha256 = "e355a0908555348ed4b9585ef25c76ff566673e345c866c325f1633f44d890b6" } },
- { url = "https://files.pythonhosted.org/packages/82/91/a3cf2a1e87d336eaa804a1e6fc93266faf6dc2a97eecdbc7eae289628022/pyrefly-1.0.0-py3-none-macosx_11_0_arm64.whl", upload-time = 2026-05-12T20:12:23Z, size = 12599494, hashes = { sha256 = "a7038efc3a40f8294edee339895633cf22db268c0d434cdbcbefc34f78a9ecc3" } },
- { url = "https://files.pythonhosted.org/packages/cd/ab/74d1e11e737e99b1c003ecc5d7d2e846c4ea1f328966bfdbbd0ac63fad0a/pyrefly-1.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2026-05-12T20:12:25Z, size = 12995507, hashes = { sha256 = "da331ca515ed1c08791da2b5f664cf9c1294c48fd802133262e7d5d51e0f4416" } },
- { url = "https://files.pythonhosted.org/packages/7c/ac/2df0899f8464c97e5d995f994c97c5cb5b0f58610432aa90d26d924e1db5/pyrefly-1.0.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2026-05-12T20:12:29Z, size = 13947693, hashes = { sha256 = "c74219d8f3e63cdaa5501a0b21d1c9d37011820f9606728d0ed06f09ae86a878" } },
- { url = "https://files.pythonhosted.org/packages/6b/3e/b247c24321e36f04b7d51f9ccf3df93e5009e4b29939524b36ec2e17dc2a/pyrefly-1.0.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", upload-time = 2026-05-12T20:12:31Z, size = 13925803, hashes = { sha256 = "c0d05543b1bb6ee6d64149eb5d6b2fb15aa72d3962d6a97abca0afaca8b0c131" } },
- { url = "https://files.pythonhosted.org/packages/61/16/cfa2d61a4aa1e1f7bca48bb37acd01c6a09db4864b16a54f9587092765ff/pyrefly-1.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2026-05-12T20:12:35Z, size = 13470398, hashes = { sha256 = "1382d5b1fcdb49a4de9f34d112d2bddf290a78ff93ee8149492ad5f1077ddffc" } },
- { url = "https://files.pythonhosted.org/packages/cb/2b/6372c7dddb326223e24a46b17efd0d4bd7b4fe22c821e523157577eed2d2/pyrefly-1.0.0-py3-none-win32.whl", upload-time = 2026-05-12T20:12:38Z, size = 12222643, hashes = { sha256 = "aa8b5d0e47080e3202a2547b39f7a5a61d2c781c712b3b67884f745ca2c759d2" } },
- { url = "https://files.pythonhosted.org/packages/be/ad/1d23be700b6b2ddaeb362360c7145917a8edbbf7240ae428d40541772fce/pyrefly-1.0.0-py3-none-win_amd64.whl", upload-time = 2026-05-12T20:12:41Z, size = 13146369, hashes = { sha256 = "c8abcb0f2082e83c890375128f9cff4aa4d3f210b85eea7b3046c1ae764e77f5" } },
- { url = "https://files.pythonhosted.org/packages/8c/38/16589134f3012fd097a10dcc85771555f1a5fb76e04b682597180743af30/pyrefly-1.0.0-py3-none-win_arm64.whl", upload-time = 2026-05-12T20:12:43Z, size = 12538326, hashes = { sha256 = "d150fa9e40e8392832be81c3bcfc0497c146674ce4d0f8e04e1ec29e775ffb8c" } },
+ { url = "https://files.pythonhosted.org/packages/7d/9d/3c0ef1d4843987b22f996ed381ec9cf5a3b1273e29804db276252e4c95eb/pyrefly-1.2.0-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-08-01T02:56:02Z, size = 14026305, hashes = { sha256 = "7f46d983ac49ddd2b043694960a01dc6a19a5cfd8eec609d6bd9c42866f91b4e" } },
+ { url = "https://files.pythonhosted.org/packages/0a/06/03bbb78fbea54cdc65b626619f3597d5611aca4fdef11e72a4e8360e7e63/pyrefly-1.2.0-py3-none-macosx_11_0_arm64.whl", upload-time = 2026-08-01T02:56:04Z, size = 13463880, hashes = { sha256 = "756f669b5555090f5c1a4fef30db1785fabe657764f7e4e6dc88994dfb8ca82d" } },
+ { url = "https://files.pythonhosted.org/packages/13/5a/7d8bc00a38e93bbc9c3e7bd14d305f7948717e667c9bcddeab9dd42fd255/pyrefly-1.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2026-08-01T02:56:07Z, size = 13907329, hashes = { sha256 = "e3465812ce5ef4781fb592edbf2724547296f0a3124be115d73c7e8b2401862d" } },
+ { url = "https://files.pythonhosted.org/packages/be/94/9e08b4bf799d0b8f36b55a2783c7ba5f51730cf0632a85a67b5b5ed876cd/pyrefly-1.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2026-08-01T02:56:09Z, size = 15039020, hashes = { sha256 = "5de7b2ad2bba5c8055181681a84b74143eac2234a48ba5d1b7ed7e7a722b02bd" } },
+ { url = "https://files.pythonhosted.org/packages/5b/bd/bca5fd0c80f4daf8ee6903a29df9f3de1feb05ff0946b8f35ec8c5096b13/pyrefly-1.2.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", upload-time = 2026-08-01T02:56:11Z, size = 14986199, hashes = { sha256 = "25822ea9505f589ea8a725e4268b475132fb89e038fbf092e446510443ac142a" } },
+ { url = "https://files.pythonhosted.org/packages/97/f7/f07087f3d185ad2eced0c56cef89ca5474dfb4ff25f146cd50a861c97553/pyrefly-1.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2026-08-01T02:56:14Z, size = 14393715, hashes = { sha256 = "90efe75e17491ef5d636e10469e9278d7d0256b3b4c5e1f4750069bf3ae0f5d1" } },
+ { url = "https://files.pythonhosted.org/packages/d3/70/0d142c320e284b9e3ce35e9b1e58b8ce2ee1f578f2a7234bc30e5022b94f/pyrefly-1.2.0-py3-none-musllinux_1_2_aarch64.whl", upload-time = 2026-08-01T02:56:16Z, size = 13933008, hashes = { sha256 = "368aaf7eee4f511ddc0f8e564cf14e01ab2f10b0db9105c6d5b153bf498d07bf" } },
+ { url = "https://files.pythonhosted.org/packages/5d/e8/e84f11b6e1f63fd453ad3654213b9a0f6f4de8cef6b58038eef2d0d5955d/pyrefly-1.2.0-py3-none-musllinux_1_2_x86_64.whl", upload-time = 2026-08-01T02:56:18Z, size = 14431827, hashes = { sha256 = "d52d5da7bc65fb7675fbaa80eda879d4f8787c494f04cac21603330d3abbdbbe" } },
+ { url = "https://files.pythonhosted.org/packages/0f/06/810d31380f66c75e1c0779a408d3b16117b1b368b57894f6aa66bef21686/pyrefly-1.2.0-py3-none-win32.whl", upload-time = 2026-08-01T02:56:20Z, size = 13229447, hashes = { sha256 = "8c90751de8506d938e8f802659c74cf35bd7a0036510ee6c634a38eebb280bfa" } },
+ { url = "https://files.pythonhosted.org/packages/ed/98/4dafa3c7a1caed2dc8cc708dde09ba27963c7736508f55b626fff3024113/pyrefly-1.2.0-py3-none-win_amd64.whl", upload-time = 2026-08-01T02:56:23Z, size = 14087387, hashes = { sha256 = "8a8964c224ccc4882730130955815de21ff443c1ac3f0b90685b19bf63848170" } },
+ { url = "https://files.pythonhosted.org/packages/1b/1c/df3cb0a2e5591660ded7a1836cd2f29dc48c91adb1c0a3a700a96f6d09e1/pyrefly-1.2.0-py3-none-win_arm64.whl", upload-time = 2026-08-01T02:56:25Z, size = 13430873, hashes = { sha256 = "3a90bb8df39dfbac74b1f3b2e9d7c526b8f80568884c3944d955023a73ebf61e" } },
]
[[packages]]
name = "pytest"
-version = "9.0.3"
+version = "9.1.1"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", upload-time = 2026-04-07T17:16:18Z, size = 1572165, hashes = { sha256 = "b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", upload-time = 2026-04-07T17:16:16Z, size = 375249, hashes = { sha256 = "2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9" } },
-]
+sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", upload-time = 2026-06-19T10:58:32Z, size = 1636369, hashes = { sha256 = "1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313" } }
+wheels = [{ url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", upload-time = 2026-06-19T10:58:31Z, size = 386536, hashes = { sha256 = "37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c" } }]
[[packages]]
name = "pytest-asyncio"
-version = "1.3.0"
+version = "1.4.0"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", upload-time = 2025-11-10T16:07:47Z, size = 50087, hashes = { sha256 = "d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", upload-time = 2025-11-10T16:07:45Z, size = 15075, hashes = { sha256 = "611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5" } },
-]
+sdist = { url = "https://files.pythonhosted.org/packages/43/7c/d36d04db312ecf4298932ef77e6e4a9e8ad017906e24e34f0b0c361a2473/pytest_asyncio-1.4.0.tar.gz", upload-time = 2026-05-26T09:56:04Z, size = 58514, hashes = { sha256 = "c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42" } }
+wheels = [{ url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", upload-time = 2026-05-26T09:56:02Z, size = 16930, hashes = { sha256 = "933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1" } }]
[[packages]]
name = "pytest-bdd"
version = "8.1.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/2d/2f/14c2e55372a5718a93b56aea48cd6ccc15d2d245364e516cd7b19bbd07ad/pytest_bdd-8.1.0.tar.gz", upload-time = 2024-12-05T21:45:58Z, size = 56147, hashes = { sha256 = "ef0896c5cd58816dc49810e8ff1d632f4a12019fb3e49959b2d349ffc1c9bfb5" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/9f/7d/1461076b0cc9a9e6fa8b51b9dea2677182ba8bc248d99d95ca321f2c666f/pytest_bdd-8.1.0-py3-none-any.whl", upload-time = 2024-12-05T21:45:56Z, size = 49149, hashes = { sha256 = "2124051e71a05ad7db15296e39013593f72ebf96796e1b023a40e5453c47e5fb" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/9f/7d/1461076b0cc9a9e6fa8b51b9dea2677182ba8bc248d99d95ca321f2c666f/pytest_bdd-8.1.0-py3-none-any.whl", upload-time = 2024-12-05T21:45:56Z, size = 49149, hashes = { sha256 = "2124051e71a05ad7db15296e39013593f72ebf96796e1b023a40e5453c47e5fb" } }]
[[packages]]
name = "pytest-cov"
version = "7.1.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", upload-time = 2026-03-21T20:11:16Z, size = 55592, hashes = { sha256 = "30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", upload-time = 2026-03-21T20:11:14Z, size = 22876, hashes = { sha256 = "a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", upload-time = 2026-03-21T20:11:14Z, size = 22876, hashes = { sha256 = "a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678" } }]
[[packages]]
name = "ruff"
-version = "0.15.13"
+version = "0.16.1"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/24/21/a7d5c126d5b557715ef81098f3db2fe20f622a039ff2e626af28d674ab80/ruff-0.15.13.tar.gz", upload-time = 2026-05-14T13:44:37Z, size = 4678180, hashes = { sha256 = "f9d89f17f7ba7fb2ed42921f0df75da797a9a5d71bc39049e2c687cf2baf44b7" } }
+sdist = { url = "https://files.pythonhosted.org/packages/70/25/7113f6d5498888c5fb7db34081cba7d5971c4cb1bfb26819966eee68f003/ruff-0.16.1.tar.gz", upload-time = 2026-07-30T19:37:01Z, size = 4877500, hashes = { sha256 = "fedad7c801dabd3fb9741d76aca39246e6ddd9ca446a015875207bf19f1e6bc7" } }
wheels = [
- { url = "https://files.pythonhosted.org/packages/c6/61/11d458dc6ac22504fd8e237b29dfd40504c7fbbcc8930402cfe51a8e63ed/ruff-0.15.13-py3-none-linux_armv6l.whl", upload-time = 2026-05-14T13:44:18Z, size = 10738279, hashes = { sha256 = "444b580fc72fd6887e650acd3e575e18cdc79dbcf42fb4030b491057921f61f8" } },
- { url = "https://files.pythonhosted.org/packages/86/ca/caa871ee7be718c45256fada4e16a218ee3e33f0c4a46b729a60a24912e6/ruff-0.15.13-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-05-14T13:44:06Z, size = 11124798, hashes = { sha256 = "6590d009e7cb7ebf36f83dbdd44a3fa48a0994ff6f1cdc1b08006abe58f98dc7" } },
- { url = "https://files.pythonhosted.org/packages/d3/19/43f5f2e568dddde567fc41f8471f9432c09563e19d3e617a48cfa52f8f0a/ruff-0.15.13-py3-none-macosx_11_0_arm64.whl", upload-time = 2026-05-14T13:44:04Z, size = 10460761, hashes = { sha256 = "1c26d2f66163deeb6e08d8b39fbbe983ce3c71cea06a6d7591cfd1421793c629" } },
- { url = "https://files.pythonhosted.org/packages/99/df/cf938cd6de3003178f03ad7c1ea2a6c099468c03a35037985070b37e76be/ruff-0.15.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2026-05-14T13:44:25Z, size = 10804451, hashes = { sha256 = "9dbd6f94b434f896308e4d57fb7bfde0d02b99f7a64b3bdab0fdfa6a864203a5" } },
- { url = "https://files.pythonhosted.org/packages/c7/7d/5d0973129b154ded2225729169d7068f26b467760b146493fde138415f23/ruff-0.15.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", upload-time = 2026-05-14T13:44:08Z, size = 10534285, hashes = { sha256 = "bf3259f3be4d181bda591da5db2571aed6853c6a048157756448020bc6c5cd22" } },
- { url = "https://files.pythonhosted.org/packages/1f/e3/6b999bbc66cd51e5f073842bc2a3995e99c5e0e72e16b15e7261f7abf57a/ruff-0.15.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2026-05-14T13:44:11Z, size = 11312063, hashes = { sha256 = "ae9c17e5eb4430c154e76abc25d79a318190f5a997f38fb6b114416c5319ffc9" } },
- { url = "https://files.pythonhosted.org/packages/af/5a/642639e9f5db04f1e97fbd6e091c6fd20725bdf072fb114d00eefb9e6eb8/ruff-0.15.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", upload-time = 2026-05-14T13:44:01Z, size = 12183079, hashes = { sha256 = "2e2e39bff6c341f4b577a21b801326fab0b11847f48fcaa83f00a113c9b3cb55" } },
- { url = "https://files.pythonhosted.org/packages/19/4c/7585735f6b53b0f12de13618b2f7d250a844f018822efc899df2e7b8295f/ruff-0.15.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", upload-time = 2026-05-14T13:43:59Z, size = 11440833, hashes = { sha256 = "e8d9a8e08013542e94d3220bc5b62cc3e5ef87c5f74bff367d3fac14fab013e6" } },
- { url = "https://files.pythonhosted.org/packages/e8/31/bf1a0803d077e679cfeee5f2f67290a0fa79c7385b5d9a8c17b9db2c48f0/ruff-0.15.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2026-05-14T13:44:27Z, size = 11434486, hashes = { sha256 = "cc411dfebe5eebe55ce041c6ae080eb7668955e866daa2fbb16692a784f1c4ca" } },
- { url = "https://files.pythonhosted.org/packages/e1/4e/62c9b999875d4f14db80f277c030578f5e249c9852d65b7ac7ad0b43c041/ruff-0.15.13-py3-none-manylinux_2_31_riscv64.whl", upload-time = 2026-05-14T13:44:13Z, size = 11385189, hashes = { sha256 = "768494eb08b9cee54e2fd27969966f74db5a57f6eaa7a90fcb3306af34dfc4bd" } },
- { url = "https://files.pythonhosted.org/packages/fc/89/7e959047a104df3eb12863447c110140191fc5b6c4f379ea2e803fcdb0e4/ruff-0.15.13-py3-none-musllinux_1_2_aarch64.whl", upload-time = 2026-05-14T13:43:56Z, size = 10781380, hashes = { sha256 = "fb75f9a3a7e42ffe117d734494e6c5e5cb3565d66e12612cb63d0e572a41a5b6" } },
- { url = "https://files.pythonhosted.org/packages/ff/52/5fd18f3b88cab63e88aa11516b3b4e1e5f720e5c330f8dbe5c26210f41f8/ruff-0.15.13-py3-none-musllinux_1_2_armv7l.whl", upload-time = 2026-05-14T13:44:20Z, size = 10540605, hashes = { sha256 = "8cb74dd33bb2f6613faf7fc03b660053b5ac4f80e706d5788c6335e2a8048d51" } },
- { url = "https://files.pythonhosted.org/packages/e8/e0/9e35f338990d3e41a82875ff7053ffe97541dae81c9d02143177f381d572/ruff-0.15.13-py3-none-musllinux_1_2_i686.whl", upload-time = 2026-05-14T13:44:16Z, size = 11036554, hashes = { sha256 = "7ef823f817fcd191dc934e984be9cf4094f808effa16f2542ad8e821ba02bbf2" } },
- { url = "https://files.pythonhosted.org/packages/c2/13/070fb048c24080fba188f66371e2a92785be257ad02242066dc7255ac6e9/ruff-0.15.13-py3-none-musllinux_1_2_x86_64.whl", upload-time = 2026-05-14T13:44:22Z, size = 11528133, hashes = { sha256 = "f345a13937bd7f09f6f5d19fa0721b0c103e00e7f62bc67089a8e5e037719e0b" } },
- { url = "https://files.pythonhosted.org/packages/6b/8c/b1e1666aef7fc6555094d73ae6cd981701781ae85b97ceefc0eebd0b4668/ruff-0.15.13-py3-none-win32.whl", upload-time = 2026-05-14T13:44:35Z, size = 10721455, hashes = { sha256 = "4044f94208b3b05ba0fc4a4abd0558cf4d6459bd18325eead7fd8cc66f909b41" } },
- { url = "https://files.pythonhosted.org/packages/ab/a6/870a3e8a50590bb92be184ad928c2922f088b00d9dc5c5ec7b924ee08c22/ruff-0.15.13-py3-none-win_amd64.whl", upload-time = 2026-05-14T13:44:30Z, size = 11900409, hashes = { sha256 = "7064884d442b7d477b4e7473d12da7f08851d2b1982763c5d3f388a19468a1a4" } },
- { url = "https://files.pythonhosted.org/packages/9b/36/9c015cd052fca743dae8cb2aeb16b551444787467db42ceab0fc968865af/ruff-0.15.13-py3-none-win_arm64.whl", upload-time = 2026-05-14T13:44:33Z, size = 11179336, hashes = { sha256 = "2471da9bd1068c8c064b5fd9c0c4b6dddffd6369cb1cd68b29993b1709ff1b21" } },
+ { url = "https://files.pythonhosted.org/packages/1b/bd/694da69368e0973de65df2ddc73ab18d43c469d5963d9b150911de6bc513/ruff-0.16.1-py3-none-linux_armv6l.whl", upload-time = 2026-07-30T19:36:13Z, size = 10839126, hashes = { sha256 = "58edb313b88f0c5460a26adf5f39a37a3be789494a15e3e411e35fa78b89f9a0" } },
+ { url = "https://files.pythonhosted.org/packages/3f/f0/b626e5d5bd0dd9576263658ef12885e2288afd1029a48e26ffed65ec1ac1/ruff-0.16.1-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-07-30T19:36:17Z, size = 11070253, hashes = { sha256 = "fde5a99e2f97479af66edd6622c6d5a2a7592c77cf4153d9e4428f5eeb55b60c" } },
+ { url = "https://files.pythonhosted.org/packages/83/63/f40acfb6b35b88623e71684942b552c3edd96035f5d98f313815f7b277de/ruff-0.16.1-py3-none-macosx_11_0_arm64.whl", upload-time = 2026-07-30T19:36:20Z, size = 10561425, hashes = { sha256 = "e0d4c20532fca4f7fa609369161d968dd28f65d83dabbd61d8e9c7edbf7001f6" } },
+ { url = "https://files.pythonhosted.org/packages/aa/dd/14ec0e9c2b4d315547dd38765004b4863e354e1b52cb308272215d9f6f6d/ruff-0.16.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2026-07-30T19:36:22Z, size = 10948879, hashes = { sha256 = "30affbcedf59ad5703d9c91f82266e02b47739f797e1a7b6e158e5526a6dae38" } },
+ { url = "https://files.pythonhosted.org/packages/33/e9/9d870cbae575030fdef595f04b4b97573c525b5497cce4f4498cf2f85446/ruff-0.16.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", upload-time = 2026-07-30T19:36:24Z, size = 10643691, hashes = { sha256 = "24e9c631573cbca9d20f1283f8f479b2afa4a8503504822bd71a293889f16743" } },
+ { url = "https://files.pythonhosted.org/packages/c4/09/12743d544e2173f53ecd27217c65f90d2bc0f8424a66a60339e56bbc0457/ruff-0.16.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2026-07-30T19:36:28Z, size = 11435354, hashes = { sha256 = "b41bdd48fb420987a9b5212e4957c26ad4abce401fa9ea9d4d85843727945f4f" } },
+ { url = "https://files.pythonhosted.org/packages/7f/89/a1652b2daee52083c9554a6333b678a8b01d0400f976827bb87857f9449a/ruff-0.16.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", upload-time = 2026-07-30T19:36:31Z, size = 12259033, hashes = { sha256 = "b0d1e1393b7648079e13669de1c1f4fde06d4583e84d8fd5c1551e0a77a2aa75" } },
+ { url = "https://files.pythonhosted.org/packages/16/96/ecdcb8c54ee7b123b487f807eb014e6e019155a0b81dfb669acd52f28ce3/ruff-0.16.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", upload-time = 2026-07-30T19:36:34Z, size = 11667981, hashes = { sha256 = "07bf434b1c95f4e093be4532068ef4fcf00924eb2ade8796075980902d6fd54a" } },
+ { url = "https://files.pythonhosted.org/packages/cd/90/c52e12e0d862e9572f2a33aa227409143520abe53111e9a6babbac7b4af8/ruff-0.16.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2026-07-30T19:36:37Z, size = 11468183, hashes = { sha256 = "39897739f112253ee4fdd2e8aa9a4f9ded99fb2be367d5f31dfa4ded6025584c" } },
+ { url = "https://files.pythonhosted.org/packages/2c/6b/4ffb7ad1d83eb16cf8cbb3c8815d3f11c88460fd162d4b372a2059be1c2a/ruff-0.16.1-py3-none-manylinux_2_31_riscv64.whl", upload-time = 2026-07-30T19:36:39Z, size = 11470071, hashes = { sha256 = "82ae3c0c0d74daf17b968a10b7b3bb3ef297ab7de0c1f749646b25e690ccb150" } },
+ { url = "https://files.pythonhosted.org/packages/9c/72/32ae7db4c0b5e32ab611787caa19d1546800676d79f7483b7100a3561bf4/ruff-0.16.1-py3-none-musllinux_1_2_aarch64.whl", upload-time = 2026-07-30T19:36:42Z, size = 10919503, hashes = { sha256 = "4d5f2ed10f8242d83fc08d521301089364e3375375705356f20c0e31606ef3ef" } },
+ { url = "https://files.pythonhosted.org/packages/f7/ca/3d901ba6ad6fc38da39c3448fc6c59ac945679293a17c3ceb6d6c1cba13e/ruff-0.16.1-py3-none-musllinux_1_2_armv7l.whl", upload-time = 2026-07-30T19:36:45Z, size = 10649861, hashes = { sha256 = "a4665b309891f83f3e3c25447935f1213e9abbd4b5640af7a1f2def9f8d413c1" } },
+ { url = "https://files.pythonhosted.org/packages/92/79/894ef1ced26552d5f8c9cf6d85b0687840e1128c55aeab7b9c2d54a0d880/ruff-0.16.1-py3-none-musllinux_1_2_i686.whl", upload-time = 2026-07-30T19:36:47Z, size = 11148137, hashes = { sha256 = "26e9ca5c9bc3971f20d3cf18a957f52ffd6a5f6564ff15c4912a144dcac22494" } },
+ { url = "https://files.pythonhosted.org/packages/2d/69/3609a09fa1cb46cc28b762363e440a354204e5dff01bd0c8d7437874d6b9/ruff-0.16.1-py3-none-musllinux_1_2_x86_64.whl", upload-time = 2026-07-30T19:36:50Z, size = 11559211, hashes = { sha256 = "67e1e1e3fa4f0c82f0e36d4cd61e661f6e7a6196cb1aa92fe0828fa7b8f257cd" } },
+ { url = "https://files.pythonhosted.org/packages/fc/8a/fb22af2fd78a736e241fabf67e30ce1799a64244026377a49e133af90762/ruff-0.16.1-py3-none-win32.whl", upload-time = 2026-07-30T19:36:53Z, size = 10838258, hashes = { sha256 = "d31765e131295b8445caf301e3e8a85b34d1b9b211b4109b7ba457888b051806" } },
+ { url = "https://files.pythonhosted.org/packages/d4/35/e57fd9fb5d423961df087a00b12d42c0a830288dc2f3b45ecca299158b4f/ruff-0.16.1-py3-none-win_amd64.whl", upload-time = 2026-07-30T19:36:56Z, size = 11961111, hashes = { sha256 = "09b05e8b90c2cb06ad63464350e7a45e8e44a2dfe52072ebfba6666ca8d3f596" } },
+ { url = "https://files.pythonhosted.org/packages/cb/46/240ea004bf6dc4feb40e9832f2205a476a47dd5b8a3f8211a5fc5f95e20e/ruff-0.16.1-py3-none-win_arm64.whl", upload-time = 2026-07-30T19:36:58Z, size = 11309414, hashes = { sha256 = "dbaadaac38c70239f056d306b7476f246b0bf000fa6b3876402acbf5b227eaf8" } },
]
[[packages]]
@@ -408,9 +363,7 @@ name = "six"
version = "1.17.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", upload-time = 2024-12-04T17:35:28Z, size = 34031, hashes = { sha256 = "ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", upload-time = 2024-12-04T17:35:26Z, size = 11050, hashes = { sha256 = "4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", upload-time = 2024-12-04T17:35:26Z, size = 11050, hashes = { sha256 = "4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274" } }]
[[packages]]
name = "tomli"
@@ -472,6 +425,4 @@ name = "typing-extensions"
version = "4.15.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", upload-time = 2025-08-25T13:49:26Z, size = 109391, hashes = { sha256 = "0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", upload-time = 2025-08-25T13:49:24Z, size = 44614, hashes = { sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", upload-time = 2025-08-25T13:49:24Z, size = 44614, hashes = { sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" } }]
diff --git a/examples/python/pylock.toml b/examples/python/pylock.toml
index 082a913f9..834be3fd6 100644
--- a/examples/python/pylock.toml
+++ b/examples/python/pylock.toml
@@ -1,20 +1,3 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
# This file was autogenerated by uv via the following command:
# uv export -o pylock.toml
lock-version = "1.0"
@@ -30,9 +13,7 @@ name = "argparse"
version = "1.4.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/18/dd/e617cfc3f6210ae183374cd9f6a26b20514bbb5a792af97949c5aacddf0f/argparse-1.4.0.tar.gz", upload-time = 2015-09-12T20:22:16Z, size = 70508, hashes = { sha256 = "62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl", upload-time = 2015-09-14T16:03:16Z, size = 23000, hashes = { sha256 = "c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl", upload-time = 2015-09-14T16:03:16Z, size = 23000, hashes = { sha256 = "c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314" } }]
[[packages]]
name = "colorama"
@@ -40,59 +21,57 @@ version = "0.4.6"
marker = "sys_platform == 'win32'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", upload-time = 2022-10-25T02:36:22Z, size = 27697, hashes = { sha256 = "08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } }]
[[packages]]
name = "loguru"
version = "0.7.3"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", upload-time = 2024-12-06T11:20:56Z, size = 63559, hashes = { sha256 = "19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", upload-time = 2024-12-06T11:20:54Z, size = 61595, hashes = { sha256 = "31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", upload-time = 2024-12-06T11:20:54Z, size = 61595, hashes = { sha256 = "31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c" } }]
[[packages]]
name = "pyrefly"
-version = "1.0.0"
+version = "1.2.0"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/9f/3a/9045b0097ac58979c7c30a4fa0e673db942d4adbc7b6d439bd54ae58c441/pyrefly-1.0.0.tar.gz", upload-time = 2026-05-12T20:12:46Z, size = 5677995, hashes = { sha256 = "5c2b810ffcebd84be71de5df1223651edee951653a66935c6f091e957c452455" } }
+sdist = { url = "https://files.pythonhosted.org/packages/89/01/a86e9f24722b095c3f88e3616132b75a21b0df53804bdc6a45314dd4d93c/pyrefly-1.2.0.tar.gz", upload-time = 2026-08-01T02:56:27Z, size = 6243654, hashes = { sha256 = "5485f960fc2481617068c918335c39ab1507ef90b6b5bd35bf57726e60e73185" } }
wheels = [
- { url = "https://files.pythonhosted.org/packages/f4/c6/90788819bac9c61dd7bacba53b79f3c12d47ccbe5e51b3d6d89f2387e1d2/pyrefly-1.0.0-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-05-12T20:12:20Z, size = 13122950, hashes = { sha256 = "e355a0908555348ed4b9585ef25c76ff566673e345c866c325f1633f44d890b6" } },
- { url = "https://files.pythonhosted.org/packages/82/91/a3cf2a1e87d336eaa804a1e6fc93266faf6dc2a97eecdbc7eae289628022/pyrefly-1.0.0-py3-none-macosx_11_0_arm64.whl", upload-time = 2026-05-12T20:12:23Z, size = 12599494, hashes = { sha256 = "a7038efc3a40f8294edee339895633cf22db268c0d434cdbcbefc34f78a9ecc3" } },
- { url = "https://files.pythonhosted.org/packages/cd/ab/74d1e11e737e99b1c003ecc5d7d2e846c4ea1f328966bfdbbd0ac63fad0a/pyrefly-1.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2026-05-12T20:12:25Z, size = 12995507, hashes = { sha256 = "da331ca515ed1c08791da2b5f664cf9c1294c48fd802133262e7d5d51e0f4416" } },
- { url = "https://files.pythonhosted.org/packages/7c/ac/2df0899f8464c97e5d995f994c97c5cb5b0f58610432aa90d26d924e1db5/pyrefly-1.0.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2026-05-12T20:12:29Z, size = 13947693, hashes = { sha256 = "c74219d8f3e63cdaa5501a0b21d1c9d37011820f9606728d0ed06f09ae86a878" } },
- { url = "https://files.pythonhosted.org/packages/6b/3e/b247c24321e36f04b7d51f9ccf3df93e5009e4b29939524b36ec2e17dc2a/pyrefly-1.0.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", upload-time = 2026-05-12T20:12:31Z, size = 13925803, hashes = { sha256 = "c0d05543b1bb6ee6d64149eb5d6b2fb15aa72d3962d6a97abca0afaca8b0c131" } },
- { url = "https://files.pythonhosted.org/packages/61/16/cfa2d61a4aa1e1f7bca48bb37acd01c6a09db4864b16a54f9587092765ff/pyrefly-1.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2026-05-12T20:12:35Z, size = 13470398, hashes = { sha256 = "1382d5b1fcdb49a4de9f34d112d2bddf290a78ff93ee8149492ad5f1077ddffc" } },
- { url = "https://files.pythonhosted.org/packages/cb/2b/6372c7dddb326223e24a46b17efd0d4bd7b4fe22c821e523157577eed2d2/pyrefly-1.0.0-py3-none-win32.whl", upload-time = 2026-05-12T20:12:38Z, size = 12222643, hashes = { sha256 = "aa8b5d0e47080e3202a2547b39f7a5a61d2c781c712b3b67884f745ca2c759d2" } },
- { url = "https://files.pythonhosted.org/packages/be/ad/1d23be700b6b2ddaeb362360c7145917a8edbbf7240ae428d40541772fce/pyrefly-1.0.0-py3-none-win_amd64.whl", upload-time = 2026-05-12T20:12:41Z, size = 13146369, hashes = { sha256 = "c8abcb0f2082e83c890375128f9cff4aa4d3f210b85eea7b3046c1ae764e77f5" } },
- { url = "https://files.pythonhosted.org/packages/8c/38/16589134f3012fd097a10dcc85771555f1a5fb76e04b682597180743af30/pyrefly-1.0.0-py3-none-win_arm64.whl", upload-time = 2026-05-12T20:12:43Z, size = 12538326, hashes = { sha256 = "d150fa9e40e8392832be81c3bcfc0497c146674ce4d0f8e04e1ec29e775ffb8c" } },
+ { url = "https://files.pythonhosted.org/packages/7d/9d/3c0ef1d4843987b22f996ed381ec9cf5a3b1273e29804db276252e4c95eb/pyrefly-1.2.0-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-08-01T02:56:02Z, size = 14026305, hashes = { sha256 = "7f46d983ac49ddd2b043694960a01dc6a19a5cfd8eec609d6bd9c42866f91b4e" } },
+ { url = "https://files.pythonhosted.org/packages/0a/06/03bbb78fbea54cdc65b626619f3597d5611aca4fdef11e72a4e8360e7e63/pyrefly-1.2.0-py3-none-macosx_11_0_arm64.whl", upload-time = 2026-08-01T02:56:04Z, size = 13463880, hashes = { sha256 = "756f669b5555090f5c1a4fef30db1785fabe657764f7e4e6dc88994dfb8ca82d" } },
+ { url = "https://files.pythonhosted.org/packages/13/5a/7d8bc00a38e93bbc9c3e7bd14d305f7948717e667c9bcddeab9dd42fd255/pyrefly-1.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2026-08-01T02:56:07Z, size = 13907329, hashes = { sha256 = "e3465812ce5ef4781fb592edbf2724547296f0a3124be115d73c7e8b2401862d" } },
+ { url = "https://files.pythonhosted.org/packages/be/94/9e08b4bf799d0b8f36b55a2783c7ba5f51730cf0632a85a67b5b5ed876cd/pyrefly-1.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2026-08-01T02:56:09Z, size = 15039020, hashes = { sha256 = "5de7b2ad2bba5c8055181681a84b74143eac2234a48ba5d1b7ed7e7a722b02bd" } },
+ { url = "https://files.pythonhosted.org/packages/5b/bd/bca5fd0c80f4daf8ee6903a29df9f3de1feb05ff0946b8f35ec8c5096b13/pyrefly-1.2.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", upload-time = 2026-08-01T02:56:11Z, size = 14986199, hashes = { sha256 = "25822ea9505f589ea8a725e4268b475132fb89e038fbf092e446510443ac142a" } },
+ { url = "https://files.pythonhosted.org/packages/97/f7/f07087f3d185ad2eced0c56cef89ca5474dfb4ff25f146cd50a861c97553/pyrefly-1.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2026-08-01T02:56:14Z, size = 14393715, hashes = { sha256 = "90efe75e17491ef5d636e10469e9278d7d0256b3b4c5e1f4750069bf3ae0f5d1" } },
+ { url = "https://files.pythonhosted.org/packages/d3/70/0d142c320e284b9e3ce35e9b1e58b8ce2ee1f578f2a7234bc30e5022b94f/pyrefly-1.2.0-py3-none-musllinux_1_2_aarch64.whl", upload-time = 2026-08-01T02:56:16Z, size = 13933008, hashes = { sha256 = "368aaf7eee4f511ddc0f8e564cf14e01ab2f10b0db9105c6d5b153bf498d07bf" } },
+ { url = "https://files.pythonhosted.org/packages/5d/e8/e84f11b6e1f63fd453ad3654213b9a0f6f4de8cef6b58038eef2d0d5955d/pyrefly-1.2.0-py3-none-musllinux_1_2_x86_64.whl", upload-time = 2026-08-01T02:56:18Z, size = 14431827, hashes = { sha256 = "d52d5da7bc65fb7675fbaa80eda879d4f8787c494f04cac21603330d3abbdbbe" } },
+ { url = "https://files.pythonhosted.org/packages/0f/06/810d31380f66c75e1c0779a408d3b16117b1b368b57894f6aa66bef21686/pyrefly-1.2.0-py3-none-win32.whl", upload-time = 2026-08-01T02:56:20Z, size = 13229447, hashes = { sha256 = "8c90751de8506d938e8f802659c74cf35bd7a0036510ee6c634a38eebb280bfa" } },
+ { url = "https://files.pythonhosted.org/packages/ed/98/4dafa3c7a1caed2dc8cc708dde09ba27963c7736508f55b626fff3024113/pyrefly-1.2.0-py3-none-win_amd64.whl", upload-time = 2026-08-01T02:56:23Z, size = 14087387, hashes = { sha256 = "8a8964c224ccc4882730130955815de21ff443c1ac3f0b90685b19bf63848170" } },
+ { url = "https://files.pythonhosted.org/packages/1b/1c/df3cb0a2e5591660ded7a1836cd2f29dc48c91adb1c0a3a700a96f6d09e1/pyrefly-1.2.0-py3-none-win_arm64.whl", upload-time = 2026-08-01T02:56:25Z, size = 13430873, hashes = { sha256 = "3a90bb8df39dfbac74b1f3b2e9d7c526b8f80568884c3944d955023a73ebf61e" } },
]
[[packages]]
name = "ruff"
-version = "0.15.13"
+version = "0.16.1"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/24/21/a7d5c126d5b557715ef81098f3db2fe20f622a039ff2e626af28d674ab80/ruff-0.15.13.tar.gz", upload-time = 2026-05-14T13:44:37Z, size = 4678180, hashes = { sha256 = "f9d89f17f7ba7fb2ed42921f0df75da797a9a5d71bc39049e2c687cf2baf44b7" } }
+sdist = { url = "https://files.pythonhosted.org/packages/70/25/7113f6d5498888c5fb7db34081cba7d5971c4cb1bfb26819966eee68f003/ruff-0.16.1.tar.gz", upload-time = 2026-07-30T19:37:01Z, size = 4877500, hashes = { sha256 = "fedad7c801dabd3fb9741d76aca39246e6ddd9ca446a015875207bf19f1e6bc7" } }
wheels = [
- { url = "https://files.pythonhosted.org/packages/c6/61/11d458dc6ac22504fd8e237b29dfd40504c7fbbcc8930402cfe51a8e63ed/ruff-0.15.13-py3-none-linux_armv6l.whl", upload-time = 2026-05-14T13:44:18Z, size = 10738279, hashes = { sha256 = "444b580fc72fd6887e650acd3e575e18cdc79dbcf42fb4030b491057921f61f8" } },
- { url = "https://files.pythonhosted.org/packages/86/ca/caa871ee7be718c45256fada4e16a218ee3e33f0c4a46b729a60a24912e6/ruff-0.15.13-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-05-14T13:44:06Z, size = 11124798, hashes = { sha256 = "6590d009e7cb7ebf36f83dbdd44a3fa48a0994ff6f1cdc1b08006abe58f98dc7" } },
- { url = "https://files.pythonhosted.org/packages/d3/19/43f5f2e568dddde567fc41f8471f9432c09563e19d3e617a48cfa52f8f0a/ruff-0.15.13-py3-none-macosx_11_0_arm64.whl", upload-time = 2026-05-14T13:44:04Z, size = 10460761, hashes = { sha256 = "1c26d2f66163deeb6e08d8b39fbbe983ce3c71cea06a6d7591cfd1421793c629" } },
- { url = "https://files.pythonhosted.org/packages/99/df/cf938cd6de3003178f03ad7c1ea2a6c099468c03a35037985070b37e76be/ruff-0.15.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2026-05-14T13:44:25Z, size = 10804451, hashes = { sha256 = "9dbd6f94b434f896308e4d57fb7bfde0d02b99f7a64b3bdab0fdfa6a864203a5" } },
- { url = "https://files.pythonhosted.org/packages/c7/7d/5d0973129b154ded2225729169d7068f26b467760b146493fde138415f23/ruff-0.15.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", upload-time = 2026-05-14T13:44:08Z, size = 10534285, hashes = { sha256 = "bf3259f3be4d181bda591da5db2571aed6853c6a048157756448020bc6c5cd22" } },
- { url = "https://files.pythonhosted.org/packages/1f/e3/6b999bbc66cd51e5f073842bc2a3995e99c5e0e72e16b15e7261f7abf57a/ruff-0.15.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2026-05-14T13:44:11Z, size = 11312063, hashes = { sha256 = "ae9c17e5eb4430c154e76abc25d79a318190f5a997f38fb6b114416c5319ffc9" } },
- { url = "https://files.pythonhosted.org/packages/af/5a/642639e9f5db04f1e97fbd6e091c6fd20725bdf072fb114d00eefb9e6eb8/ruff-0.15.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", upload-time = 2026-05-14T13:44:01Z, size = 12183079, hashes = { sha256 = "2e2e39bff6c341f4b577a21b801326fab0b11847f48fcaa83f00a113c9b3cb55" } },
- { url = "https://files.pythonhosted.org/packages/19/4c/7585735f6b53b0f12de13618b2f7d250a844f018822efc899df2e7b8295f/ruff-0.15.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", upload-time = 2026-05-14T13:43:59Z, size = 11440833, hashes = { sha256 = "e8d9a8e08013542e94d3220bc5b62cc3e5ef87c5f74bff367d3fac14fab013e6" } },
- { url = "https://files.pythonhosted.org/packages/e8/31/bf1a0803d077e679cfeee5f2f67290a0fa79c7385b5d9a8c17b9db2c48f0/ruff-0.15.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2026-05-14T13:44:27Z, size = 11434486, hashes = { sha256 = "cc411dfebe5eebe55ce041c6ae080eb7668955e866daa2fbb16692a784f1c4ca" } },
- { url = "https://files.pythonhosted.org/packages/e1/4e/62c9b999875d4f14db80f277c030578f5e249c9852d65b7ac7ad0b43c041/ruff-0.15.13-py3-none-manylinux_2_31_riscv64.whl", upload-time = 2026-05-14T13:44:13Z, size = 11385189, hashes = { sha256 = "768494eb08b9cee54e2fd27969966f74db5a57f6eaa7a90fcb3306af34dfc4bd" } },
- { url = "https://files.pythonhosted.org/packages/fc/89/7e959047a104df3eb12863447c110140191fc5b6c4f379ea2e803fcdb0e4/ruff-0.15.13-py3-none-musllinux_1_2_aarch64.whl", upload-time = 2026-05-14T13:43:56Z, size = 10781380, hashes = { sha256 = "fb75f9a3a7e42ffe117d734494e6c5e5cb3565d66e12612cb63d0e572a41a5b6" } },
- { url = "https://files.pythonhosted.org/packages/ff/52/5fd18f3b88cab63e88aa11516b3b4e1e5f720e5c330f8dbe5c26210f41f8/ruff-0.15.13-py3-none-musllinux_1_2_armv7l.whl", upload-time = 2026-05-14T13:44:20Z, size = 10540605, hashes = { sha256 = "8cb74dd33bb2f6613faf7fc03b660053b5ac4f80e706d5788c6335e2a8048d51" } },
- { url = "https://files.pythonhosted.org/packages/e8/e0/9e35f338990d3e41a82875ff7053ffe97541dae81c9d02143177f381d572/ruff-0.15.13-py3-none-musllinux_1_2_i686.whl", upload-time = 2026-05-14T13:44:16Z, size = 11036554, hashes = { sha256 = "7ef823f817fcd191dc934e984be9cf4094f808effa16f2542ad8e821ba02bbf2" } },
- { url = "https://files.pythonhosted.org/packages/c2/13/070fb048c24080fba188f66371e2a92785be257ad02242066dc7255ac6e9/ruff-0.15.13-py3-none-musllinux_1_2_x86_64.whl", upload-time = 2026-05-14T13:44:22Z, size = 11528133, hashes = { sha256 = "f345a13937bd7f09f6f5d19fa0721b0c103e00e7f62bc67089a8e5e037719e0b" } },
- { url = "https://files.pythonhosted.org/packages/6b/8c/b1e1666aef7fc6555094d73ae6cd981701781ae85b97ceefc0eebd0b4668/ruff-0.15.13-py3-none-win32.whl", upload-time = 2026-05-14T13:44:35Z, size = 10721455, hashes = { sha256 = "4044f94208b3b05ba0fc4a4abd0558cf4d6459bd18325eead7fd8cc66f909b41" } },
- { url = "https://files.pythonhosted.org/packages/ab/a6/870a3e8a50590bb92be184ad928c2922f088b00d9dc5c5ec7b924ee08c22/ruff-0.15.13-py3-none-win_amd64.whl", upload-time = 2026-05-14T13:44:30Z, size = 11900409, hashes = { sha256 = "7064884d442b7d477b4e7473d12da7f08851d2b1982763c5d3f388a19468a1a4" } },
- { url = "https://files.pythonhosted.org/packages/9b/36/9c015cd052fca743dae8cb2aeb16b551444787467db42ceab0fc968865af/ruff-0.15.13-py3-none-win_arm64.whl", upload-time = 2026-05-14T13:44:33Z, size = 11179336, hashes = { sha256 = "2471da9bd1068c8c064b5fd9c0c4b6dddffd6369cb1cd68b29993b1709ff1b21" } },
+ { url = "https://files.pythonhosted.org/packages/1b/bd/694da69368e0973de65df2ddc73ab18d43c469d5963d9b150911de6bc513/ruff-0.16.1-py3-none-linux_armv6l.whl", upload-time = 2026-07-30T19:36:13Z, size = 10839126, hashes = { sha256 = "58edb313b88f0c5460a26adf5f39a37a3be789494a15e3e411e35fa78b89f9a0" } },
+ { url = "https://files.pythonhosted.org/packages/3f/f0/b626e5d5bd0dd9576263658ef12885e2288afd1029a48e26ffed65ec1ac1/ruff-0.16.1-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-07-30T19:36:17Z, size = 11070253, hashes = { sha256 = "fde5a99e2f97479af66edd6622c6d5a2a7592c77cf4153d9e4428f5eeb55b60c" } },
+ { url = "https://files.pythonhosted.org/packages/83/63/f40acfb6b35b88623e71684942b552c3edd96035f5d98f313815f7b277de/ruff-0.16.1-py3-none-macosx_11_0_arm64.whl", upload-time = 2026-07-30T19:36:20Z, size = 10561425, hashes = { sha256 = "e0d4c20532fca4f7fa609369161d968dd28f65d83dabbd61d8e9c7edbf7001f6" } },
+ { url = "https://files.pythonhosted.org/packages/aa/dd/14ec0e9c2b4d315547dd38765004b4863e354e1b52cb308272215d9f6f6d/ruff-0.16.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2026-07-30T19:36:22Z, size = 10948879, hashes = { sha256 = "30affbcedf59ad5703d9c91f82266e02b47739f797e1a7b6e158e5526a6dae38" } },
+ { url = "https://files.pythonhosted.org/packages/33/e9/9d870cbae575030fdef595f04b4b97573c525b5497cce4f4498cf2f85446/ruff-0.16.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", upload-time = 2026-07-30T19:36:24Z, size = 10643691, hashes = { sha256 = "24e9c631573cbca9d20f1283f8f479b2afa4a8503504822bd71a293889f16743" } },
+ { url = "https://files.pythonhosted.org/packages/c4/09/12743d544e2173f53ecd27217c65f90d2bc0f8424a66a60339e56bbc0457/ruff-0.16.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2026-07-30T19:36:28Z, size = 11435354, hashes = { sha256 = "b41bdd48fb420987a9b5212e4957c26ad4abce401fa9ea9d4d85843727945f4f" } },
+ { url = "https://files.pythonhosted.org/packages/7f/89/a1652b2daee52083c9554a6333b678a8b01d0400f976827bb87857f9449a/ruff-0.16.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", upload-time = 2026-07-30T19:36:31Z, size = 12259033, hashes = { sha256 = "b0d1e1393b7648079e13669de1c1f4fde06d4583e84d8fd5c1551e0a77a2aa75" } },
+ { url = "https://files.pythonhosted.org/packages/16/96/ecdcb8c54ee7b123b487f807eb014e6e019155a0b81dfb669acd52f28ce3/ruff-0.16.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", upload-time = 2026-07-30T19:36:34Z, size = 11667981, hashes = { sha256 = "07bf434b1c95f4e093be4532068ef4fcf00924eb2ade8796075980902d6fd54a" } },
+ { url = "https://files.pythonhosted.org/packages/cd/90/c52e12e0d862e9572f2a33aa227409143520abe53111e9a6babbac7b4af8/ruff-0.16.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2026-07-30T19:36:37Z, size = 11468183, hashes = { sha256 = "39897739f112253ee4fdd2e8aa9a4f9ded99fb2be367d5f31dfa4ded6025584c" } },
+ { url = "https://files.pythonhosted.org/packages/2c/6b/4ffb7ad1d83eb16cf8cbb3c8815d3f11c88460fd162d4b372a2059be1c2a/ruff-0.16.1-py3-none-manylinux_2_31_riscv64.whl", upload-time = 2026-07-30T19:36:39Z, size = 11470071, hashes = { sha256 = "82ae3c0c0d74daf17b968a10b7b3bb3ef297ab7de0c1f749646b25e690ccb150" } },
+ { url = "https://files.pythonhosted.org/packages/9c/72/32ae7db4c0b5e32ab611787caa19d1546800676d79f7483b7100a3561bf4/ruff-0.16.1-py3-none-musllinux_1_2_aarch64.whl", upload-time = 2026-07-30T19:36:42Z, size = 10919503, hashes = { sha256 = "4d5f2ed10f8242d83fc08d521301089364e3375375705356f20c0e31606ef3ef" } },
+ { url = "https://files.pythonhosted.org/packages/f7/ca/3d901ba6ad6fc38da39c3448fc6c59ac945679293a17c3ceb6d6c1cba13e/ruff-0.16.1-py3-none-musllinux_1_2_armv7l.whl", upload-time = 2026-07-30T19:36:45Z, size = 10649861, hashes = { sha256 = "a4665b309891f83f3e3c25447935f1213e9abbd4b5640af7a1f2def9f8d413c1" } },
+ { url = "https://files.pythonhosted.org/packages/92/79/894ef1ced26552d5f8c9cf6d85b0687840e1128c55aeab7b9c2d54a0d880/ruff-0.16.1-py3-none-musllinux_1_2_i686.whl", upload-time = 2026-07-30T19:36:47Z, size = 11148137, hashes = { sha256 = "26e9ca5c9bc3971f20d3cf18a957f52ffd6a5f6564ff15c4912a144dcac22494" } },
+ { url = "https://files.pythonhosted.org/packages/2d/69/3609a09fa1cb46cc28b762363e440a354204e5dff01bd0c8d7437874d6b9/ruff-0.16.1-py3-none-musllinux_1_2_x86_64.whl", upload-time = 2026-07-30T19:36:50Z, size = 11559211, hashes = { sha256 = "67e1e1e3fa4f0c82f0e36d4cd61e661f6e7a6196cb1aa92fe0828fa7b8f257cd" } },
+ { url = "https://files.pythonhosted.org/packages/fc/8a/fb22af2fd78a736e241fabf67e30ce1799a64244026377a49e133af90762/ruff-0.16.1-py3-none-win32.whl", upload-time = 2026-07-30T19:36:53Z, size = 10838258, hashes = { sha256 = "d31765e131295b8445caf301e3e8a85b34d1b9b211b4109b7ba457888b051806" } },
+ { url = "https://files.pythonhosted.org/packages/d4/35/e57fd9fb5d423961df087a00b12d42c0a830288dc2f3b45ecca299158b4f/ruff-0.16.1-py3-none-win_amd64.whl", upload-time = 2026-07-30T19:36:56Z, size = 11961111, hashes = { sha256 = "09b05e8b90c2cb06ad63464350e7a45e8e44a2dfe52072ebfba6666ca8d3f596" } },
+ { url = "https://files.pythonhosted.org/packages/cb/46/240ea004bf6dc4feb40e9832f2205a476a47dd5b8a3f8211a5fc5f95e20e/ruff-0.16.1-py3-none-win_arm64.whl", upload-time = 2026-07-30T19:36:58Z, size = 11309414, hashes = { sha256 = "dbaadaac38c70239f056d306b7476f246b0bf000fa6b3876402acbf5b227eaf8" } },
]
[[packages]]
@@ -101,6 +80,4 @@ version = "1.2.0"
marker = "sys_platform == 'win32'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", upload-time = 2024-12-07T15:28:28Z, size = 4867, hashes = { sha256 = "ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", upload-time = 2024-12-07T15:28:26Z, size = 4083, hashes = { sha256 = "95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", upload-time = 2024-12-07T15:28:26Z, size = 4083, hashes = { sha256 = "95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390" } }]
diff --git a/foreign/python/apache_iggy.pyi b/foreign/python/apache_iggy.pyi
index 95d4debf1..96391d65f 100644
--- a/foreign/python/apache_iggy.pyi
+++ b/foreign/python/apache_iggy.pyi
@@ -1058,9 +1058,7 @@ class IggyClient:
"""
def get_streams(self) -> collections.abc.Awaitable[list[Stream]]:
r"""
- Return all streams visible to the authenticated user.
-
- The result is ordered by ascending numeric stream ID.
+ Return all streams.
Returns:
A list of `Stream` summaries.
@@ -1070,7 +1068,10 @@ class IggyClient:
`read_streams` or `manage_streams` permission, or the request fails.
"""
def update_stream(
- self, stream_id: builtins.str | builtins.int, name: builtins.str
+ self,
+ stream_id: builtins.str | builtins.int,
+ name: builtins.str,
+ options: builtins.dict[builtins.str, builtins.str] | None = None,
) -> collections.abc.Awaitable[None]:
r"""
Rename a stream selected by name or numeric ID.
@@ -1080,13 +1081,19 @@ class IggyClient:
and contain between 1 and 255 UTF-8 bytes. Renaming a stream to its current
name succeeds without changing it.
+ Args:
+ stream_id: Stream identifier as `str | int`.
+ name: New stream name as `str`.
+ options: Additional option keys as `dict[str, str] | None`, forwarded
+ to the server. Current server versions reject all stream update
+ option keys.
+
Returns:
None.
Raises:
- TypeError: If `stream_id` is neither `str` nor `int`, or `name` is not
- `str`.
- OverflowError: If an integer identifier is outside `0..=2**32 - 1`.
+ TypeError: If `stream_id` is not `str` or an integer in
+ `0..=2**32 - 1`, or `name` is not `str`.
ValueError: If a string identifier is empty or exceeds 255 UTF-8 bytes.
RuntimeError: If the client is not authenticated, the user lacks global
`manage_streams` or per-stream `manage_stream` permission, the
@@ -1107,8 +1114,8 @@ class IggyClient:
None.
Raises:
- TypeError: If `stream_id` is neither `str` nor `int`.
- OverflowError: If an integer identifier is outside `0..=2**32 - 1`.
+ TypeError: If `stream_id` is not `str` or an integer in
+ `0..=2**32 - 1`.
ValueError: If a string identifier is empty or exceeds 255 UTF-8 bytes.
RuntimeError: If the client is not authenticated, the user lacks global
`manage_streams` or per-stream `manage_stream` permission, the
@@ -1129,8 +1136,8 @@ class IggyClient:
None.
Raises:
- TypeError: If `stream_id` is neither `str` nor `int`.
- OverflowError: If an integer identifier is outside `0..=2**32 - 1`.
+ TypeError: If `stream_id` is not `str` or an integer in
+ `0..=2**32 - 1`.
ValueError: If a string identifier is empty or exceeds 255 UTF-8 bytes.
RuntimeError: If the client is not authenticated, the user lacks global
`manage_streams` or per-stream `manage_stream` permission, the
@@ -1974,6 +1981,11 @@ class StreamDetails:
def messages_count(self) -> builtins.int: ...
@property
def topics_count(self) -> builtins.int: ...
+ @property
+ def topics(self) -> builtins.list[Topic]:
+ r"""
+ Returns the topics in the stream.
+ """
@typing.final
class StreamPermissions:
@@ -2233,7 +2245,7 @@ class Topic:
r"""
Options admission resolved for the keys the client did not send.
- Same shape as [`Self::options`]. These would have resolved differently
+ Same shape as options. These would have resolved differently
under another server configuration.
"""
@@ -2298,7 +2310,7 @@ class TopicDetails:
r"""
Options admission resolved for the keys the client did not send.
- Same shape as [`Self::options`]. These would have resolved differently
+ Same shape as options. These would have resolved differently
under another server configuration.
"""
@property
diff --git a/foreign/python/pylock.toml b/foreign/python/pylock.toml
index 4c01b652b..d963b1010 100644
--- a/foreign/python/pylock.toml
+++ b/foreign/python/pylock.toml
@@ -1,20 +1,3 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
# This file was autogenerated by uv via the following command:
# uv export --format pylock.toml --output-file pylock.toml --all-extras
lock-version = "1.0"
@@ -31,18 +14,14 @@ version = "1.2.0"
marker = "python_full_version < '3.11'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", upload-time = 2025-07-02T02:27:15Z, size = 69893, hashes = { sha256 = "a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", upload-time = 2025-07-02T02:27:14Z, size = 12313, hashes = { sha256 = "0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", upload-time = 2025-07-02T02:27:14Z, size = 12313, hashes = { sha256 = "0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5" } }]
[[packages]]
name = "certifi"
version = "2026.4.22"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", upload-time = 2026-04-22T11:26:11Z, size = 137077, hashes = { sha256 = "8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", upload-time = 2026-04-22T11:26:09Z, size = 135707, hashes = { sha256 = "3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", upload-time = 2026-04-22T11:26:09Z, size = 135707, hashes = { sha256 = "3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a" } }]
[[packages]]
name = "charset-normalizer"
@@ -155,9 +134,7 @@ version = "0.4.6"
marker = "sys_platform == 'win32'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", upload-time = 2022-10-25T02:36:22Z, size = 27697, hashes = { sha256 = "08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } }]
[[packages]]
name = "coverage"
@@ -277,9 +254,7 @@ name = "docker"
version = "7.1.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/91/9b/4a2ea29aeba62471211598dac5d96825bb49348fa07e906ea930394a83ce/docker-7.1.0.tar.gz", upload-time = 2024-05-23T11:13:57Z, size = 117834, hashes = { sha256 = "ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl", upload-time = 2024-05-23T11:13:55Z, size = 147774, hashes = { sha256 = "c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/e3/26/57c6fb270950d476074c087527a558ccb6f4436657314bfb6cdf484114c4/docker-7.1.0-py3-none-any.whl", upload-time = 2024-05-23T11:13:55Z, size = 147774, hashes = { sha256 = "c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0" } }]
[[packages]]
name = "exceptiongroup"
@@ -287,56 +262,41 @@ version = "1.3.1"
marker = "python_full_version < '3.11'"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", upload-time = 2025-11-21T23:01:54Z, size = 30371, hashes = { sha256 = "8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", upload-time = 2025-11-21T23:01:53Z, size = 16740, hashes = { sha256 = "a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598" } },
-]
-
-[[packages]]
-name = "execnet"
-version = "2.1.2"
-index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", upload-time = 2025-11-12T09:56:37Z, size = 166622, hashes = { sha256 = "63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", upload-time = 2025-11-12T09:56:36Z, size = 40708, hashes = { sha256 = "67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", upload-time = 2025-11-21T23:01:53Z, size = 16740, hashes = { sha256 = "a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598" } }]
[[packages]]
name = "idna"
version = "3.15"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/82/77/7b3966d0b9d1d31a36ddf1746926a11dface89a83409bf1483f0237aa758/idna-3.15.tar.gz", upload-time = 2026-05-12T22:45:57Z, size = 199245, hashes = { sha256 = "ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl", upload-time = 2026-05-12T22:45:55Z, size = 72340, hashes = { sha256 = "048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl", upload-time = 2026-05-12T22:45:55Z, size = 72340, hashes = { sha256 = "048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8" } }]
[[packages]]
name = "iniconfig"
version = "2.3.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", upload-time = 2025-10-18T21:55:43Z, size = 20503, hashes = { sha256 = "c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", upload-time = 2025-10-18T21:55:41Z, size = 7484, hashes = { sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", upload-time = 2025-10-18T21:55:41Z, size = 7484, hashes = { sha256 = "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" } }]
[[packages]]
name = "maturin"
-version = "1.13.3"
+version = "1.14.1"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/9c/1c/612d23d33ec21b9ae7ece7b3f0dd5f9dfd57b4009e9d2938165869ebd6ae/maturin-1.13.3.tar.gz", upload-time = 2026-05-11T07:43:39Z, size = 357934, hashes = { sha256 = "771e1e9e71a278e56db01552e0d1acfd1464259f9575b6e72842f893cd299079" } }
+sdist = { url = "https://files.pythonhosted.org/packages/e7/b3/addd877f871fb1860d46d3a4f206ecb10b946c85846805e6367631926fd3/maturin-1.14.1.tar.gz", upload-time = 2026-06-19T05:19:49Z, size = 369637, hashes = { sha256 = "9d6577a62cd08e0ceba7a0db06fb098e0c9b1b3429bad747a4f3a18215a1b3df" } }
wheels = [
- { url = "https://files.pythonhosted.org/packages/71/66/18c2aaac0b2a5dea9f1db5984ce83b905ad205cfc7c02d0091e707c0c2e7/maturin-1.13.3-py3-none-linux_armv6l.whl", upload-time = 2026-05-11T07:43:10Z, size = 10190971, hashes = { sha256 = "3cc13929ca82aefa4adbf0f2c35419369796213c6fb0eb24e914945f50ef5d8c" } },
- { url = "https://files.pythonhosted.org/packages/bc/71/26a988d092e4fd6a9523d46d44400a46cad7cdf3fd206ce702240c748aee/maturin-1.13.3-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", upload-time = 2026-05-11T07:43:36Z, size = 19716714, hashes = { sha256 = "53b08bd075649ce96513ad9abf241a43cb685ed6e9e7790f8dbc2d66e95d8323" } },
- { url = "https://files.pythonhosted.org/packages/82/5c/f3fd0e184255d9fc7e272c62af3dfa84c617b2577ef83af9ce615f5279cc/maturin-1.13.3-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-05-11T07:43:07Z, size = 10194726, hashes = { sha256 = "4cd478e6e4c56251e48ed079b8efd55b30bc5c09cf695a1bdafaeb582ee735a0" } },
- { url = "https://files.pythonhosted.org/packages/a9/e1/f4edb69fb647b77c4769a9bfd4d6fb62961e653d164bc277ecdffac3ab61/maturin-1.13.3-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", upload-time = 2026-05-11T07:43:40Z, size = 10172781, hashes = { sha256 = "a2675e25f313034ae6f57388cf14818f87d8961c4a96795287f3e155f59beb11" } },
- { url = "https://files.pythonhosted.org/packages/c7/7d/a1be934690cdcc3c6609769ceaad322ab7501c2ee5bafcac1b14d609e403/maturin-1.13.3-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", upload-time = 2026-05-11T07:43:13Z, size = 10682670, hashes = { sha256 = "4667ef609ab446c1b5e0bfe4f9fb99699ab6d8548433f8d1a684256e0b67217f" } },
- { url = "https://files.pythonhosted.org/packages/18/f5/372ae19b72ce8f6e37e5864ae4dc5b252ee9fce0619ccc3aa366aa3a7f97/maturin-1.13.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", upload-time = 2026-05-11T07:43:21Z, size = 10060363, hashes = { sha256 = "3db93337ed97e60ffc878aa8b493cd7ae44d3a5e1a37256db3a4491f57565018" } },
- { url = "https://files.pythonhosted.org/packages/cb/5b/c68340cca09368af0df80965dfabed4234205a492a93da00793c7b9aae20/maturin-1.13.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", upload-time = 2026-05-11T07:43:33Z, size = 10017551, hashes = { sha256 = "1cc0a110b224ca90406b668a3e3c1f5a515062e59e26292f6dbaf5fd4909c6f3" } },
- { url = "https://files.pythonhosted.org/packages/28/1e/f90fb2b000bad9e6d850cd5afb88b2f1e2a279cfb4de02ea40078484690e/maturin-1.13.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", upload-time = 2026-05-11T07:43:26Z, size = 13301712, hashes = { sha256 = "c00ea6428dea17bf616fe93770837634454b28c2de1a876e42ef8036c616079a" } },
- { url = "https://files.pythonhosted.org/packages/be/58/1670f68a8f04ccd7b90df11047bd9a046585310e84e1967cc9849cd1c5a3/maturin-1.13.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", upload-time = 2026-05-11T07:43:16Z, size = 10946765, hashes = { sha256 = "49fd6ab08da28098ccf37afca24cdba72376ba9c1eedf9dd25ff82ed771961ff" } },
- { url = "https://files.pythonhosted.org/packages/4b/ac/00c955c2ef134817b1a7bdaa76b0309e9c5291eb17d9ff88069eecd08bc2/maturin-1.13.3-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", upload-time = 2026-05-11T07:43:18Z, size = 10388661, hashes = { sha256 = "b6741d7bf4af97da937528fd1e523c6ab54f53d9a21870fa735d6e67fd88e273" } },
- { url = "https://files.pythonhosted.org/packages/97/c6/cbf8a51dde19c19aeba0d9b075095a2effb9b31fd312b1aae3ac79f8aea2/maturin-1.13.3-py3-none-win32.whl", upload-time = 2026-05-11T07:43:23Z, size = 8901838, hashes = { sha256 = "0ef257e692cc756c87af5bea95ddfe7d3ac49d3376a7a87f728d63f06e7b6f8b" } },
- { url = "https://files.pythonhosted.org/packages/a1/ff/c6a50a59dc8313097d43ac5f4d74df6a500c8cb62b0dc9e054f53e203a48/maturin-1.13.3-py3-none-win_amd64.whl", upload-time = 2026-05-11T07:43:29Z, size = 10340801, hashes = { sha256 = "def4a435ea9d2ee93b18ba579dc8c9cf898889a66f312cd379b5e374ec3e3ad6" } },
- { url = "https://files.pythonhosted.org/packages/6c/93/e32e79333f0902ba292b996f504f5f06be59587f7d02ab8d5ed1e3066445/maturin-1.13.3-py3-none-win_arm64.whl", upload-time = 2026-05-11T07:43:31Z, size = 9706562, hashes = { sha256 = "2389fe92d017cea9d94e521fa0175314a4c52f79a1057b901fbc9f8686ef7d0b" } },
+ { url = "https://files.pythonhosted.org/packages/f4/f0/97c5a5bd9c71653a066c0976a484eaaae50b9369557838a4176b7b0bdaa5/maturin-1.14.1-py3-none-linux_armv6l.whl", upload-time = 2026-06-19T05:19:09Z, size = 10207496, hashes = { sha256 = "522292398945442cdafa9daeb2271b2340fbde57027b818f923f88eab04174f8" } },
+ { url = "https://files.pythonhosted.org/packages/fe/83/294bca639b0e052f1e2f65199b3db258780c7d4e31408b934c9c974a1379/maturin-1.14.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", upload-time = 2026-06-19T05:19:13Z, size = 19680113, hashes = { sha256 = "ffe5ad71f21d1e6603c4dd75f7fee34adf5ed5ebcebb692886549888ebb329ed" } },
+ { url = "https://files.pythonhosted.org/packages/43/b6/79c881410a3b1c187f7eb3d407aecae646c6a4433d630d72200359015e83/maturin-1.14.1-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-06-19T05:19:16Z, size = 10169205, hashes = { sha256 = "f3306078070c1508fd715b9116070cbcaff5959024272a9f1e6f5cb29768b86c" } },
+ { url = "https://files.pythonhosted.org/packages/93/9d/44b6f26dcb7f7a04c5501ac2dbb6ca1490150682baa525ca5860504f9eab/maturin-1.14.1-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", upload-time = 2026-06-19T05:19:19Z, size = 10188098, hashes = { sha256 = "cd457cd88961156e26379e1155bd287cc0ec1c8b2f1582b0660fb31b87c8842d" } },
+ { url = "https://files.pythonhosted.org/packages/1a/bd/9c0d5d6983905ce2c9edaa073a7e89355a9cf7f396988e05d32f1c37785d/maturin-1.14.1-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", upload-time = 2026-06-19T05:19:22Z, size = 10627576, hashes = { sha256 = "dfc54ae32e6fcb18302193ab9a30b0b25eefffba994ae13238974805533ef75e" } },
+ { url = "https://files.pythonhosted.org/packages/e5/33/b096412bd6a7cb399652b260666f901adf88a687181a6dbd6a3f89f0a94e/maturin-1.14.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", upload-time = 2026-06-19T05:19:25Z, size = 10085181, hashes = { sha256 = "a131d912b5267e640bc96d70f4914e10590aed64082ec9abacba7cea52004224" } },
+ { url = "https://files.pythonhosted.org/packages/56/8d/08c3bf469c38a23c9e6c877e338193001eb604d010fedc08341974e38528/maturin-1.14.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", upload-time = 2026-06-19T05:19:28Z, size = 10026363, hashes = { sha256 = "be18fc568fb76884c0205456336892a75105ec398e6b667cd777c6268bd06d69" } },
+ { url = "https://files.pythonhosted.org/packages/3a/a4/c4d1a92839f8745ab4aab988a7db884a79d6d710bd3b286fcf9316dece1a/maturin-1.14.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", upload-time = 2026-06-19T05:19:32Z, size = 13321347, hashes = { sha256 = "994a0c8ba3ad8a92b3a9ee1b02645d200d610216b15cff5102b0fe65e8e08666" } },
+ { url = "https://files.pythonhosted.org/packages/b3/fa/170f04624d03fd07d2a8b1b67de83a127af93aef9eaa425839553347297b/maturin-1.14.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", upload-time = 2026-06-19T05:19:35Z, size = 10877609, hashes = { sha256 = "be80866363e605d137991b491a741a84cde9ae350183c4c85f49690ca9aaaa65" } },
+ { url = "https://files.pythonhosted.org/packages/61/ad/1ae2e1d0ded282bf2c55ac13f0811d87deb425e200ae64a15785675dede9/maturin-1.14.1-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", upload-time = 2026-06-19T05:19:38Z, size = 10417316, hashes = { sha256 = "5282dffd4b539d2be245f4e5b1a5ab6bc1033b58f4a4872f5833f9d43c954aa4" } },
+ { url = "https://files.pythonhosted.org/packages/fb/27/bf677183920718da49cd7982d6a3ffc440aad8919329f571d189f81b7bdf/maturin-1.14.1-py3-none-win32.whl", upload-time = 2026-06-19T05:19:41Z, size = 8931293, hashes = { sha256 = "1a04de0a20188f95c721b5702eed18140bdcccb28c386797093eca3f62f4d4e0" } },
+ { url = "https://files.pythonhosted.org/packages/63/4b/585adeb9167b08d3cdff0032a938b0e72655c92003df4f52c3f696a1bcc2/maturin-1.14.1-py3-none-win_amd64.whl", upload-time = 2026-06-19T05:19:44Z, size = 10314067, hashes = { sha256 = "3c9f94640ecc4895e94abaf834a0684430032c865b2748a36c12461fd9252fdd" } },
+ { url = "https://files.pythonhosted.org/packages/51/d4/dac8c0720ae246be1700afb6fbdbbea20fe35b13f6570b2f70faa005df77/maturin-1.14.1-py3-none-win_arm64.whl", upload-time = 2026-06-19T05:19:47Z, size = 9718943, hashes = { sha256 = "15cea8fcb3ba47dd636f50092bb34baea8b04ac777392f23e6bf8a9a61efb894" } },
]
[[packages]]
@@ -344,98 +304,75 @@ name = "packaging"
version = "26.2"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", upload-time = 2026-04-24T20:15:23Z, size = 228134, hashes = { sha256 = "ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", upload-time = 2026-04-24T20:15:22Z, size = 100195, hashes = { sha256 = "5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", upload-time = 2026-04-24T20:15:22Z, size = 100195, hashes = { sha256 = "5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e" } }]
[[packages]]
name = "pluggy"
version = "1.6.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", upload-time = 2025-05-15T12:30:07Z, size = 69412, hashes = { sha256 = "7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", upload-time = 2025-05-15T12:30:06Z, size = 20538, hashes = { sha256 = "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", upload-time = 2025-05-15T12:30:06Z, size = 20538, hashes = { sha256 = "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" } }]
[[packages]]
name = "pygments"
version = "2.20.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", upload-time = 2026-03-29T13:29:33Z, size = 4955991, hashes = { sha256 = "6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", upload-time = 2026-03-29T13:29:30Z, size = 1231151, hashes = { sha256 = "81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", upload-time = 2026-03-29T13:29:30Z, size = 1231151, hashes = { sha256 = "81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176" } }]
[[packages]]
name = "pyrefly"
-version = "1.0.0"
+version = "1.2.0"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/9f/3a/9045b0097ac58979c7c30a4fa0e673db942d4adbc7b6d439bd54ae58c441/pyrefly-1.0.0.tar.gz", upload-time = 2026-05-12T20:12:46Z, size = 5677995, hashes = { sha256 = "5c2b810ffcebd84be71de5df1223651edee951653a66935c6f091e957c452455" } }
+sdist = { url = "https://files.pythonhosted.org/packages/89/01/a86e9f24722b095c3f88e3616132b75a21b0df53804bdc6a45314dd4d93c/pyrefly-1.2.0.tar.gz", upload-time = 2026-08-01T02:56:27Z, size = 6243654, hashes = { sha256 = "5485f960fc2481617068c918335c39ab1507ef90b6b5bd35bf57726e60e73185" } }
wheels = [
- { url = "https://files.pythonhosted.org/packages/f4/c6/90788819bac9c61dd7bacba53b79f3c12d47ccbe5e51b3d6d89f2387e1d2/pyrefly-1.0.0-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-05-12T20:12:20Z, size = 13122950, hashes = { sha256 = "e355a0908555348ed4b9585ef25c76ff566673e345c866c325f1633f44d890b6" } },
- { url = "https://files.pythonhosted.org/packages/82/91/a3cf2a1e87d336eaa804a1e6fc93266faf6dc2a97eecdbc7eae289628022/pyrefly-1.0.0-py3-none-macosx_11_0_arm64.whl", upload-time = 2026-05-12T20:12:23Z, size = 12599494, hashes = { sha256 = "a7038efc3a40f8294edee339895633cf22db268c0d434cdbcbefc34f78a9ecc3" } },
- { url = "https://files.pythonhosted.org/packages/cd/ab/74d1e11e737e99b1c003ecc5d7d2e846c4ea1f328966bfdbbd0ac63fad0a/pyrefly-1.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2026-05-12T20:12:25Z, size = 12995507, hashes = { sha256 = "da331ca515ed1c08791da2b5f664cf9c1294c48fd802133262e7d5d51e0f4416" } },
- { url = "https://files.pythonhosted.org/packages/7c/ac/2df0899f8464c97e5d995f994c97c5cb5b0f58610432aa90d26d924e1db5/pyrefly-1.0.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2026-05-12T20:12:29Z, size = 13947693, hashes = { sha256 = "c74219d8f3e63cdaa5501a0b21d1c9d37011820f9606728d0ed06f09ae86a878" } },
- { url = "https://files.pythonhosted.org/packages/6b/3e/b247c24321e36f04b7d51f9ccf3df93e5009e4b29939524b36ec2e17dc2a/pyrefly-1.0.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", upload-time = 2026-05-12T20:12:31Z, size = 13925803, hashes = { sha256 = "c0d05543b1bb6ee6d64149eb5d6b2fb15aa72d3962d6a97abca0afaca8b0c131" } },
- { url = "https://files.pythonhosted.org/packages/61/16/cfa2d61a4aa1e1f7bca48bb37acd01c6a09db4864b16a54f9587092765ff/pyrefly-1.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2026-05-12T20:12:35Z, size = 13470398, hashes = { sha256 = "1382d5b1fcdb49a4de9f34d112d2bddf290a78ff93ee8149492ad5f1077ddffc" } },
- { url = "https://files.pythonhosted.org/packages/cb/2b/6372c7dddb326223e24a46b17efd0d4bd7b4fe22c821e523157577eed2d2/pyrefly-1.0.0-py3-none-win32.whl", upload-time = 2026-05-12T20:12:38Z, size = 12222643, hashes = { sha256 = "aa8b5d0e47080e3202a2547b39f7a5a61d2c781c712b3b67884f745ca2c759d2" } },
- { url = "https://files.pythonhosted.org/packages/be/ad/1d23be700b6b2ddaeb362360c7145917a8edbbf7240ae428d40541772fce/pyrefly-1.0.0-py3-none-win_amd64.whl", upload-time = 2026-05-12T20:12:41Z, size = 13146369, hashes = { sha256 = "c8abcb0f2082e83c890375128f9cff4aa4d3f210b85eea7b3046c1ae764e77f5" } },
- { url = "https://files.pythonhosted.org/packages/8c/38/16589134f3012fd097a10dcc85771555f1a5fb76e04b682597180743af30/pyrefly-1.0.0-py3-none-win_arm64.whl", upload-time = 2026-05-12T20:12:43Z, size = 12538326, hashes = { sha256 = "d150fa9e40e8392832be81c3bcfc0497c146674ce4d0f8e04e1ec29e775ffb8c" } },
+ { url = "https://files.pythonhosted.org/packages/7d/9d/3c0ef1d4843987b22f996ed381ec9cf5a3b1273e29804db276252e4c95eb/pyrefly-1.2.0-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-08-01T02:56:02Z, size = 14026305, hashes = { sha256 = "7f46d983ac49ddd2b043694960a01dc6a19a5cfd8eec609d6bd9c42866f91b4e" } },
+ { url = "https://files.pythonhosted.org/packages/0a/06/03bbb78fbea54cdc65b626619f3597d5611aca4fdef11e72a4e8360e7e63/pyrefly-1.2.0-py3-none-macosx_11_0_arm64.whl", upload-time = 2026-08-01T02:56:04Z, size = 13463880, hashes = { sha256 = "756f669b5555090f5c1a4fef30db1785fabe657764f7e4e6dc88994dfb8ca82d" } },
+ { url = "https://files.pythonhosted.org/packages/13/5a/7d8bc00a38e93bbc9c3e7bd14d305f7948717e667c9bcddeab9dd42fd255/pyrefly-1.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2026-08-01T02:56:07Z, size = 13907329, hashes = { sha256 = "e3465812ce5ef4781fb592edbf2724547296f0a3124be115d73c7e8b2401862d" } },
+ { url = "https://files.pythonhosted.org/packages/be/94/9e08b4bf799d0b8f36b55a2783c7ba5f51730cf0632a85a67b5b5ed876cd/pyrefly-1.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2026-08-01T02:56:09Z, size = 15039020, hashes = { sha256 = "5de7b2ad2bba5c8055181681a84b74143eac2234a48ba5d1b7ed7e7a722b02bd" } },
+ { url = "https://files.pythonhosted.org/packages/5b/bd/bca5fd0c80f4daf8ee6903a29df9f3de1feb05ff0946b8f35ec8c5096b13/pyrefly-1.2.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", upload-time = 2026-08-01T02:56:11Z, size = 14986199, hashes = { sha256 = "25822ea9505f589ea8a725e4268b475132fb89e038fbf092e446510443ac142a" } },
+ { url = "https://files.pythonhosted.org/packages/97/f7/f07087f3d185ad2eced0c56cef89ca5474dfb4ff25f146cd50a861c97553/pyrefly-1.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2026-08-01T02:56:14Z, size = 14393715, hashes = { sha256 = "90efe75e17491ef5d636e10469e9278d7d0256b3b4c5e1f4750069bf3ae0f5d1" } },
+ { url = "https://files.pythonhosted.org/packages/d3/70/0d142c320e284b9e3ce35e9b1e58b8ce2ee1f578f2a7234bc30e5022b94f/pyrefly-1.2.0-py3-none-musllinux_1_2_aarch64.whl", upload-time = 2026-08-01T02:56:16Z, size = 13933008, hashes = { sha256 = "368aaf7eee4f511ddc0f8e564cf14e01ab2f10b0db9105c6d5b153bf498d07bf" } },
+ { url = "https://files.pythonhosted.org/packages/5d/e8/e84f11b6e1f63fd453ad3654213b9a0f6f4de8cef6b58038eef2d0d5955d/pyrefly-1.2.0-py3-none-musllinux_1_2_x86_64.whl", upload-time = 2026-08-01T02:56:18Z, size = 14431827, hashes = { sha256 = "d52d5da7bc65fb7675fbaa80eda879d4f8787c494f04cac21603330d3abbdbbe" } },
+ { url = "https://files.pythonhosted.org/packages/0f/06/810d31380f66c75e1c0779a408d3b16117b1b368b57894f6aa66bef21686/pyrefly-1.2.0-py3-none-win32.whl", upload-time = 2026-08-01T02:56:20Z, size = 13229447, hashes = { sha256 = "8c90751de8506d938e8f802659c74cf35bd7a0036510ee6c634a38eebb280bfa" } },
+ { url = "https://files.pythonhosted.org/packages/ed/98/4dafa3c7a1caed2dc8cc708dde09ba27963c7736508f55b626fff3024113/pyrefly-1.2.0-py3-none-win_amd64.whl", upload-time = 2026-08-01T02:56:23Z, size = 14087387, hashes = { sha256 = "8a8964c224ccc4882730130955815de21ff443c1ac3f0b90685b19bf63848170" } },
+ { url = "https://files.pythonhosted.org/packages/1b/1c/df3cb0a2e5591660ded7a1836cd2f29dc48c91adb1c0a3a700a96f6d09e1/pyrefly-1.2.0-py3-none-win_arm64.whl", upload-time = 2026-08-01T02:56:25Z, size = 13430873, hashes = { sha256 = "3a90bb8df39dfbac74b1f3b2e9d7c526b8f80568884c3944d955023a73ebf61e" } },
]
[[packages]]
name = "pytest"
-version = "9.0.3"
+version = "9.1.1"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", upload-time = 2026-04-07T17:16:18Z, size = 1572165, hashes = { sha256 = "b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", upload-time = 2026-04-07T17:16:16Z, size = 375249, hashes = { sha256 = "2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9" } },
-]
+sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", upload-time = 2026-06-19T10:58:32Z, size = 1636369, hashes = { sha256 = "1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313" } }
+wheels = [{ url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", upload-time = 2026-06-19T10:58:31Z, size = 386536, hashes = { sha256 = "37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c" } }]
[[packages]]
name = "pytest-asyncio"
-version = "1.3.0"
+version = "1.4.0"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", upload-time = 2025-11-10T16:07:47Z, size = 50087, hashes = { sha256 = "d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", upload-time = 2025-11-10T16:07:45Z, size = 15075, hashes = { sha256 = "611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5" } },
-]
+sdist = { url = "https://files.pythonhosted.org/packages/43/7c/d36d04db312ecf4298932ef77e6e4a9e8ad017906e24e34f0b0c361a2473/pytest_asyncio-1.4.0.tar.gz", upload-time = 2026-05-26T09:56:04Z, size = 58514, hashes = { sha256 = "c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42" } }
+wheels = [{ url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", upload-time = 2026-05-26T09:56:02Z, size = 16930, hashes = { sha256 = "933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1" } }]
[[packages]]
name = "pytest-cov"
-version = "6.3.0"
+version = "7.1.0"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/30/4c/f883ab8f0daad69f47efdf95f55a66b51a8b939c430dadce0611508d9e99/pytest_cov-6.3.0.tar.gz", upload-time = 2025-09-06T15:40:14Z, size = 70398, hashes = { sha256 = "35c580e7800f87ce892e687461166e1ac2bcb8fb9e13aea79032518d6e503ff2" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl", upload-time = 2025-09-06T15:40:12Z, size = 25115, hashes = { sha256 = "440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749" } },
-]
+sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", upload-time = 2026-03-21T20:11:16Z, size = 55592, hashes = { sha256 = "30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2" } }
+wheels = [{ url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", upload-time = 2026-03-21T20:11:14Z, size = 22876, hashes = { sha256 = "a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678" } }]
[[packages]]
name = "pytest-timeout"
version = "2.4.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/ac/82/4c9ecabab13363e72d880f2fb504c5f750433b2b6f16e99f4ec21ada284c/pytest_timeout-2.4.0.tar.gz", upload-time = 2025-05-05T19:44:34Z, size = 17973, hashes = { sha256 = "7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", upload-time = 2025-05-05T19:44:33Z, size = 14382, hashes = { sha256 = "c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2" } },
-]
-
-[[packages]]
-name = "pytest-xdist"
-version = "3.8.0"
-index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", upload-time = 2025-07-01T13:30:59Z, size = 88069, hashes = { sha256 = "7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", upload-time = 2025-07-01T13:30:56Z, size = 46396, hashes = { sha256 = "202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", upload-time = 2025-05-05T19:44:33Z, size = 14382, hashes = { sha256 = "c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2" } }]
[[packages]]
name = "python-dotenv"
version = "1.2.2"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", upload-time = 2026-03-01T16:00:26Z, size = 50135, hashes = { sha256 = "2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", upload-time = 2026-03-01T16:00:25Z, size = 22101, hashes = { sha256 = "1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", upload-time = 2026-03-01T16:00:25Z, size = 22101, hashes = { sha256 = "1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a" } }]
[[packages]]
name = "pywin32"
@@ -465,43 +402,39 @@ name = "requests"
version = "2.34.2"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", upload-time = 2026-05-14T19:25:27Z, size = 142856, hashes = { sha256 = "f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", upload-time = 2026-05-14T19:25:26Z, size = 73075, hashes = { sha256 = "2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", upload-time = 2026-05-14T19:25:26Z, size = 73075, hashes = { sha256 = "2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0" } }]
[[packages]]
name = "ruff"
-version = "0.15.13"
+version = "0.16.1"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/24/21/a7d5c126d5b557715ef81098f3db2fe20f622a039ff2e626af28d674ab80/ruff-0.15.13.tar.gz", upload-time = 2026-05-14T13:44:37Z, size = 4678180, hashes = { sha256 = "f9d89f17f7ba7fb2ed42921f0df75da797a9a5d71bc39049e2c687cf2baf44b7" } }
+sdist = { url = "https://files.pythonhosted.org/packages/70/25/7113f6d5498888c5fb7db34081cba7d5971c4cb1bfb26819966eee68f003/ruff-0.16.1.tar.gz", upload-time = 2026-07-30T19:37:01Z, size = 4877500, hashes = { sha256 = "fedad7c801dabd3fb9741d76aca39246e6ddd9ca446a015875207bf19f1e6bc7" } }
wheels = [
- { url = "https://files.pythonhosted.org/packages/c6/61/11d458dc6ac22504fd8e237b29dfd40504c7fbbcc8930402cfe51a8e63ed/ruff-0.15.13-py3-none-linux_armv6l.whl", upload-time = 2026-05-14T13:44:18Z, size = 10738279, hashes = { sha256 = "444b580fc72fd6887e650acd3e575e18cdc79dbcf42fb4030b491057921f61f8" } },
- { url = "https://files.pythonhosted.org/packages/86/ca/caa871ee7be718c45256fada4e16a218ee3e33f0c4a46b729a60a24912e6/ruff-0.15.13-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-05-14T13:44:06Z, size = 11124798, hashes = { sha256 = "6590d009e7cb7ebf36f83dbdd44a3fa48a0994ff6f1cdc1b08006abe58f98dc7" } },
- { url = "https://files.pythonhosted.org/packages/d3/19/43f5f2e568dddde567fc41f8471f9432c09563e19d3e617a48cfa52f8f0a/ruff-0.15.13-py3-none-macosx_11_0_arm64.whl", upload-time = 2026-05-14T13:44:04Z, size = 10460761, hashes = { sha256 = "1c26d2f66163deeb6e08d8b39fbbe983ce3c71cea06a6d7591cfd1421793c629" } },
- { url = "https://files.pythonhosted.org/packages/99/df/cf938cd6de3003178f03ad7c1ea2a6c099468c03a35037985070b37e76be/ruff-0.15.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2026-05-14T13:44:25Z, size = 10804451, hashes = { sha256 = "9dbd6f94b434f896308e4d57fb7bfde0d02b99f7a64b3bdab0fdfa6a864203a5" } },
- { url = "https://files.pythonhosted.org/packages/c7/7d/5d0973129b154ded2225729169d7068f26b467760b146493fde138415f23/ruff-0.15.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", upload-time = 2026-05-14T13:44:08Z, size = 10534285, hashes = { sha256 = "bf3259f3be4d181bda591da5db2571aed6853c6a048157756448020bc6c5cd22" } },
- { url = "https://files.pythonhosted.org/packages/1f/e3/6b999bbc66cd51e5f073842bc2a3995e99c5e0e72e16b15e7261f7abf57a/ruff-0.15.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2026-05-14T13:44:11Z, size = 11312063, hashes = { sha256 = "ae9c17e5eb4430c154e76abc25d79a318190f5a997f38fb6b114416c5319ffc9" } },
- { url = "https://files.pythonhosted.org/packages/af/5a/642639e9f5db04f1e97fbd6e091c6fd20725bdf072fb114d00eefb9e6eb8/ruff-0.15.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", upload-time = 2026-05-14T13:44:01Z, size = 12183079, hashes = { sha256 = "2e2e39bff6c341f4b577a21b801326fab0b11847f48fcaa83f00a113c9b3cb55" } },
- { url = "https://files.pythonhosted.org/packages/19/4c/7585735f6b53b0f12de13618b2f7d250a844f018822efc899df2e7b8295f/ruff-0.15.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", upload-time = 2026-05-14T13:43:59Z, size = 11440833, hashes = { sha256 = "e8d9a8e08013542e94d3220bc5b62cc3e5ef87c5f74bff367d3fac14fab013e6" } },
- { url = "https://files.pythonhosted.org/packages/e8/31/bf1a0803d077e679cfeee5f2f67290a0fa79c7385b5d9a8c17b9db2c48f0/ruff-0.15.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2026-05-14T13:44:27Z, size = 11434486, hashes = { sha256 = "cc411dfebe5eebe55ce041c6ae080eb7668955e866daa2fbb16692a784f1c4ca" } },
- { url = "https://files.pythonhosted.org/packages/e1/4e/62c9b999875d4f14db80f277c030578f5e249c9852d65b7ac7ad0b43c041/ruff-0.15.13-py3-none-manylinux_2_31_riscv64.whl", upload-time = 2026-05-14T13:44:13Z, size = 11385189, hashes = { sha256 = "768494eb08b9cee54e2fd27969966f74db5a57f6eaa7a90fcb3306af34dfc4bd" } },
- { url = "https://files.pythonhosted.org/packages/fc/89/7e959047a104df3eb12863447c110140191fc5b6c4f379ea2e803fcdb0e4/ruff-0.15.13-py3-none-musllinux_1_2_aarch64.whl", upload-time = 2026-05-14T13:43:56Z, size = 10781380, hashes = { sha256 = "fb75f9a3a7e42ffe117d734494e6c5e5cb3565d66e12612cb63d0e572a41a5b6" } },
- { url = "https://files.pythonhosted.org/packages/ff/52/5fd18f3b88cab63e88aa11516b3b4e1e5f720e5c330f8dbe5c26210f41f8/ruff-0.15.13-py3-none-musllinux_1_2_armv7l.whl", upload-time = 2026-05-14T13:44:20Z, size = 10540605, hashes = { sha256 = "8cb74dd33bb2f6613faf7fc03b660053b5ac4f80e706d5788c6335e2a8048d51" } },
- { url = "https://files.pythonhosted.org/packages/e8/e0/9e35f338990d3e41a82875ff7053ffe97541dae81c9d02143177f381d572/ruff-0.15.13-py3-none-musllinux_1_2_i686.whl", upload-time = 2026-05-14T13:44:16Z, size = 11036554, hashes = { sha256 = "7ef823f817fcd191dc934e984be9cf4094f808effa16f2542ad8e821ba02bbf2" } },
- { url = "https://files.pythonhosted.org/packages/c2/13/070fb048c24080fba188f66371e2a92785be257ad02242066dc7255ac6e9/ruff-0.15.13-py3-none-musllinux_1_2_x86_64.whl", upload-time = 2026-05-14T13:44:22Z, size = 11528133, hashes = { sha256 = "f345a13937bd7f09f6f5d19fa0721b0c103e00e7f62bc67089a8e5e037719e0b" } },
- { url = "https://files.pythonhosted.org/packages/6b/8c/b1e1666aef7fc6555094d73ae6cd981701781ae85b97ceefc0eebd0b4668/ruff-0.15.13-py3-none-win32.whl", upload-time = 2026-05-14T13:44:35Z, size = 10721455, hashes = { sha256 = "4044f94208b3b05ba0fc4a4abd0558cf4d6459bd18325eead7fd8cc66f909b41" } },
- { url = "https://files.pythonhosted.org/packages/ab/a6/870a3e8a50590bb92be184ad928c2922f088b00d9dc5c5ec7b924ee08c22/ruff-0.15.13-py3-none-win_amd64.whl", upload-time = 2026-05-14T13:44:30Z, size = 11900409, hashes = { sha256 = "7064884d442b7d477b4e7473d12da7f08851d2b1982763c5d3f388a19468a1a4" } },
- { url = "https://files.pythonhosted.org/packages/9b/36/9c015cd052fca743dae8cb2aeb16b551444787467db42ceab0fc968865af/ruff-0.15.13-py3-none-win_arm64.whl", upload-time = 2026-05-14T13:44:33Z, size = 11179336, hashes = { sha256 = "2471da9bd1068c8c064b5fd9c0c4b6dddffd6369cb1cd68b29993b1709ff1b21" } },
+ { url = "https://files.pythonhosted.org/packages/1b/bd/694da69368e0973de65df2ddc73ab18d43c469d5963d9b150911de6bc513/ruff-0.16.1-py3-none-linux_armv6l.whl", upload-time = 2026-07-30T19:36:13Z, size = 10839126, hashes = { sha256 = "58edb313b88f0c5460a26adf5f39a37a3be789494a15e3e411e35fa78b89f9a0" } },
+ { url = "https://files.pythonhosted.org/packages/3f/f0/b626e5d5bd0dd9576263658ef12885e2288afd1029a48e26ffed65ec1ac1/ruff-0.16.1-py3-none-macosx_10_12_x86_64.whl", upload-time = 2026-07-30T19:36:17Z, size = 11070253, hashes = { sha256 = "fde5a99e2f97479af66edd6622c6d5a2a7592c77cf4153d9e4428f5eeb55b60c" } },
+ { url = "https://files.pythonhosted.org/packages/83/63/f40acfb6b35b88623e71684942b552c3edd96035f5d98f313815f7b277de/ruff-0.16.1-py3-none-macosx_11_0_arm64.whl", upload-time = 2026-07-30T19:36:20Z, size = 10561425, hashes = { sha256 = "e0d4c20532fca4f7fa609369161d968dd28f65d83dabbd61d8e9c7edbf7001f6" } },
+ { url = "https://files.pythonhosted.org/packages/aa/dd/14ec0e9c2b4d315547dd38765004b4863e354e1b52cb308272215d9f6f6d/ruff-0.16.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", upload-time = 2026-07-30T19:36:22Z, size = 10948879, hashes = { sha256 = "30affbcedf59ad5703d9c91f82266e02b47739f797e1a7b6e158e5526a6dae38" } },
+ { url = "https://files.pythonhosted.org/packages/33/e9/9d870cbae575030fdef595f04b4b97573c525b5497cce4f4498cf2f85446/ruff-0.16.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", upload-time = 2026-07-30T19:36:24Z, size = 10643691, hashes = { sha256 = "24e9c631573cbca9d20f1283f8f479b2afa4a8503504822bd71a293889f16743" } },
+ { url = "https://files.pythonhosted.org/packages/c4/09/12743d544e2173f53ecd27217c65f90d2bc0f8424a66a60339e56bbc0457/ruff-0.16.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", upload-time = 2026-07-30T19:36:28Z, size = 11435354, hashes = { sha256 = "b41bdd48fb420987a9b5212e4957c26ad4abce401fa9ea9d4d85843727945f4f" } },
+ { url = "https://files.pythonhosted.org/packages/7f/89/a1652b2daee52083c9554a6333b678a8b01d0400f976827bb87857f9449a/ruff-0.16.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", upload-time = 2026-07-30T19:36:31Z, size = 12259033, hashes = { sha256 = "b0d1e1393b7648079e13669de1c1f4fde06d4583e84d8fd5c1551e0a77a2aa75" } },
+ { url = "https://files.pythonhosted.org/packages/16/96/ecdcb8c54ee7b123b487f807eb014e6e019155a0b81dfb669acd52f28ce3/ruff-0.16.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", upload-time = 2026-07-30T19:36:34Z, size = 11667981, hashes = { sha256 = "07bf434b1c95f4e093be4532068ef4fcf00924eb2ade8796075980902d6fd54a" } },
+ { url = "https://files.pythonhosted.org/packages/cd/90/c52e12e0d862e9572f2a33aa227409143520abe53111e9a6babbac7b4af8/ruff-0.16.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2026-07-30T19:36:37Z, size = 11468183, hashes = { sha256 = "39897739f112253ee4fdd2e8aa9a4f9ded99fb2be367d5f31dfa4ded6025584c" } },
+ { url = "https://files.pythonhosted.org/packages/2c/6b/4ffb7ad1d83eb16cf8cbb3c8815d3f11c88460fd162d4b372a2059be1c2a/ruff-0.16.1-py3-none-manylinux_2_31_riscv64.whl", upload-time = 2026-07-30T19:36:39Z, size = 11470071, hashes = { sha256 = "82ae3c0c0d74daf17b968a10b7b3bb3ef297ab7de0c1f749646b25e690ccb150" } },
+ { url = "https://files.pythonhosted.org/packages/9c/72/32ae7db4c0b5e32ab611787caa19d1546800676d79f7483b7100a3561bf4/ruff-0.16.1-py3-none-musllinux_1_2_aarch64.whl", upload-time = 2026-07-30T19:36:42Z, size = 10919503, hashes = { sha256 = "4d5f2ed10f8242d83fc08d521301089364e3375375705356f20c0e31606ef3ef" } },
+ { url = "https://files.pythonhosted.org/packages/f7/ca/3d901ba6ad6fc38da39c3448fc6c59ac945679293a17c3ceb6d6c1cba13e/ruff-0.16.1-py3-none-musllinux_1_2_armv7l.whl", upload-time = 2026-07-30T19:36:45Z, size = 10649861, hashes = { sha256 = "a4665b309891f83f3e3c25447935f1213e9abbd4b5640af7a1f2def9f8d413c1" } },
+ { url = "https://files.pythonhosted.org/packages/92/79/894ef1ced26552d5f8c9cf6d85b0687840e1128c55aeab7b9c2d54a0d880/ruff-0.16.1-py3-none-musllinux_1_2_i686.whl", upload-time = 2026-07-30T19:36:47Z, size = 11148137, hashes = { sha256 = "26e9ca5c9bc3971f20d3cf18a957f52ffd6a5f6564ff15c4912a144dcac22494" } },
+ { url = "https://files.pythonhosted.org/packages/2d/69/3609a09fa1cb46cc28b762363e440a354204e5dff01bd0c8d7437874d6b9/ruff-0.16.1-py3-none-musllinux_1_2_x86_64.whl", upload-time = 2026-07-30T19:36:50Z, size = 11559211, hashes = { sha256 = "67e1e1e3fa4f0c82f0e36d4cd61e661f6e7a6196cb1aa92fe0828fa7b8f257cd" } },
+ { url = "https://files.pythonhosted.org/packages/fc/8a/fb22af2fd78a736e241fabf67e30ce1799a64244026377a49e133af90762/ruff-0.16.1-py3-none-win32.whl", upload-time = 2026-07-30T19:36:53Z, size = 10838258, hashes = { sha256 = "d31765e131295b8445caf301e3e8a85b34d1b9b211b4109b7ba457888b051806" } },
+ { url = "https://files.pythonhosted.org/packages/d4/35/e57fd9fb5d423961df087a00b12d42c0a830288dc2f3b45ecca299158b4f/ruff-0.16.1-py3-none-win_amd64.whl", upload-time = 2026-07-30T19:36:56Z, size = 11961111, hashes = { sha256 = "09b05e8b90c2cb06ad63464350e7a45e8e44a2dfe52072ebfba6666ca8d3f596" } },
+ { url = "https://files.pythonhosted.org/packages/cb/46/240ea004bf6dc4feb40e9832f2205a476a47dd5b8a3f8211a5fc5f95e20e/ruff-0.16.1-py3-none-win_arm64.whl", upload-time = 2026-07-30T19:36:58Z, size = 11309414, hashes = { sha256 = "dbaadaac38c70239f056d306b7476f246b0bf000fa6b3876402acbf5b227eaf8" } },
]
[[packages]]
name = "testcontainers"
-version = "4.14.2"
+version = "4.15.0"
index = "https://pypi.org/simple"
-sdist = { url = "https://files.pythonhosted.org/packages/ca/ac/a597c3a0e02b26cbed6dd07df68be1e57684766fd1c381dee9b170a99690/testcontainers-4.14.2.tar.gz", upload-time = 2026-03-18T05:19:16Z, size = 166841, hashes = { sha256 = "1340ccf16fe3acd9389a6c9e1d9ab21d9fe99a8afdf8165f89c3e69c1967d239" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/13/2d/26b8b30067d94339afee62c3edc9b803a6eb9332f521ba77d8aaab5de873/testcontainers-4.14.2-py3-none-any.whl", upload-time = 2026-03-18T05:19:15Z, size = 125712, hashes = { sha256 = "0d0522c3cd8f8d9627cda41f7a6b51b639fa57bdc492923c045117933c668d68" } },
-]
+sdist = { url = "https://files.pythonhosted.org/packages/4b/13/2cc466bddf26d0085f30a2b2bd56b7f8708b54a54db833eec97c5c69129b/testcontainers-4.15.0.tar.gz", upload-time = 2026-07-24T23:08:01Z, size = 95340, hashes = { sha256 = "085cde086337632e19002719460b7b80bbab2bdd51bb3ea04f77d0de96504706" } }
+wheels = [{ url = "https://files.pythonhosted.org/packages/00/7e/424aac8b355597835deb333e757a0e94b5ccf38ad00f07fe6ed1f4e17c88/testcontainers-4.15.0-py3-none-any.whl", upload-time = 2026-07-24T23:08:00Z, size = 160771, hashes = { sha256 = "8796c14e76604031ad39cf0ed3b8e9806283a1fbf5270965c2b1c594caa31b74" } }]
[[packages]]
name = "tomli"
@@ -563,18 +496,14 @@ name = "typing-extensions"
version = "4.15.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", upload-time = 2025-08-25T13:49:26Z, size = 109391, hashes = { sha256 = "0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", upload-time = 2025-08-25T13:49:24Z, size = 44614, hashes = { sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", upload-time = 2025-08-25T13:49:24Z, size = 44614, hashes = { sha256 = "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" } }]
[[packages]]
name = "urllib3"
version = "2.7.0"
index = "https://pypi.org/simple"
sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", upload-time = 2026-05-07T16:13:18Z, size = 433602, hashes = { sha256 = "231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c" } }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", upload-time = 2026-05-07T16:13:17Z, size = 131087, hashes = { sha256 = "9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897" } },
-]
+wheels = [{ url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", upload-time = 2026-05-07T16:13:17Z, size = 131087, hashes = { sha256 = "9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897" } }]
[[packages]]
name = "wrapt"
diff --git a/foreign/python/src/client.rs b/foreign/python/src/client.rs
index 9fab3944c..fc17adbd9 100644
--- a/foreign/python/src/client.rs
+++ b/foreign/python/src/client.rs
@@ -500,9 +500,7 @@ impl IggyClient {
})
}
- /// Return all streams visible to the authenticated user.
- ///
- /// The result is ordered by ascending numeric stream ID.
+ /// Return all streams.
///
/// Returns:
/// A list of `Stream` summaries.
@@ -529,30 +527,42 @@ impl IggyClient {
/// and contain between 1 and 255 UTF-8 bytes. Renaming a stream to its current
/// name succeeds without changing it.
///
+ /// Args:
+ /// stream_id: Stream identifier as `str | int`.
+ /// name: New stream name as `str`.
+ /// options: Additional option keys as `dict[str, str] | None`, forwarded
+ /// to the server. Current server versions reject all stream update
+ /// option keys.
+ ///
/// Returns:
/// None.
///
/// Raises:
- /// TypeError: If `stream_id` is neither `str` nor `int`, or `name` is not
- /// `str`.
- /// OverflowError: If an integer identifier is outside `0..=2**32 - 1`.
+ /// TypeError: If `stream_id` is not `str` or an integer in
+ /// `0..=2**32 - 1`, or `name` is not `str`.
/// ValueError: If a string identifier is empty or exceeds 255 UTF-8 bytes.
/// RuntimeError: If the client is not authenticated, the user lacks global
/// `manage_streams` or per-stream `manage_stream` permission, the
/// stream does not exist, the new name is invalid or already used, or
/// the request fails.
+ #[pyo3(signature = (stream_id, name, options = None))]
#[gen_stub(override_return_type(type_repr="collections.abc.Awaitable[None]", imports=("collections.abc")))]
fn update_stream<'a>(
&self,
py: Python<'a>,
stream_id: PyIdentifier,
name: String,
+ #[gen_stub(override_type(type_repr = "builtins.dict[builtins.str, builtins.str] | None"))]
+ options: Option<BTreeMap<String, String>>,
) -> PyResult<Bound<'a, PyAny>> {
let stream_id = Identifier::try_from(stream_id)?;
+ let update_options = StreamUpdateOptions {
+ raw: options.unwrap_or_default(),
+ };
let inner = self.inner.clone();
future_into_py(py, async move {
inner
- .update_stream(&stream_id, &name, &StreamUpdateOptions::default())
+ .update_stream(&stream_id, &name, &update_options)
.await
.map_err(|e| PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(e.to_string()))?;
Ok(())
@@ -569,8 +579,8 @@ impl IggyClient {
/// None.
///
/// Raises:
- /// TypeError: If `stream_id` is neither `str` nor `int`.
- /// OverflowError: If an integer identifier is outside `0..=2**32 - 1`.
+ /// TypeError: If `stream_id` is not `str` or an integer in
+ /// `0..=2**32 - 1`.
/// ValueError: If a string identifier is empty or exceeds 255 UTF-8 bytes.
/// RuntimeError: If the client is not authenticated, the user lacks global
/// `manage_streams` or per-stream `manage_stream` permission, the
@@ -603,8 +613,8 @@ impl IggyClient {
/// None.
///
/// Raises:
- /// TypeError: If `stream_id` is neither `str` nor `int`.
- /// OverflowError: If an integer identifier is outside `0..=2**32 - 1`.
+ /// TypeError: If `stream_id` is not `str` or an integer in
+ /// `0..=2**32 - 1`.
/// ValueError: If a string identifier is empty or exceeds 255 UTF-8 bytes.
/// RuntimeError: If the client is not authenticated, the user lacks global
/// `manage_streams` or per-stream `manage_stream` permission, the
diff --git a/foreign/python/src/stream.rs b/foreign/python/src/stream.rs
index 9b6126ad9..d5f6a8e44 100644
--- a/foreign/python/src/stream.rs
+++ b/foreign/python/src/stream.rs
@@ -19,6 +19,8 @@ use iggy::prelude::{Stream as RustStream, StreamDetails as RustStreamDetails};
use pyo3::prelude::*;
use pyo3_stub_gen::derive::{gen_stub_pyclass, gen_stub_pymethods};
+use crate::topic::Topic;
+
#[pyclass]
#[gen_stub_pyclass]
pub struct StreamDetails {
@@ -67,6 +69,12 @@ impl StreamDetails {
pub fn topics_count(&self) -> u32 {
self.inner.topics_count
}
+
+ /// Returns the topics in the stream.
+ #[getter]
+ pub fn topics(&self) -> Vec<Topic> {
+ self.inner.topics.iter().map(Topic::from).collect()
+ }
}
/// Summary information returned by `IggyClient.get_streams()`.
diff --git a/foreign/python/src/topic.rs b/foreign/python/src/topic.rs
index e5f86facd..6b33c9e0f 100644
--- a/foreign/python/src/topic.rs
+++ b/foreign/python/src/topic.rs
@@ -185,6 +185,25 @@ impl From<RustTopic> for Topic {
}
}
+impl From<&RustTopic> for Topic {
+ fn from(topic: &RustTopic) -> Self {
+ Self {
+ inner: RustTopic {
+ id: topic.id,
+ created_at: topic.created_at,
+ name: topic.name.clone(),
+ size: topic.size,
+ message_expiry: topic.message_expiry,
+ compression_algorithm: topic.compression_algorithm,
+ max_topic_size: topic.max_topic_size,
+ messages_count: topic.messages_count,
+ partitions_count: topic.partitions_count,
+ options: topic.options.clone(),
+ },
+ }
+ }
+}
+
#[gen_stub_pymethods]
#[pymethods]
impl Topic {
@@ -254,7 +273,7 @@ impl Topic {
/// Options admission resolved for the keys the client did not send.
///
- /// Same shape as [`Self::options`]. These would have resolved differently
+ /// Same shape as options. These would have resolved differently
/// under another server configuration.
#[getter]
pub fn derived_options<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, UserHeaders>> {
@@ -345,7 +364,7 @@ impl TopicDetails {
/// Options admission resolved for the keys the client did not send.
///
- /// Same shape as [`Self::options`]. These would have resolved differently
+ /// Same shape as options. These would have resolved differently
/// under another server configuration.
#[getter]
pub fn derived_options<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, UserHeaders>> {
diff --git a/foreign/python/tests/conftest.py b/foreign/python/tests/conftest.py
index 734054069..ac9acdec4 100644
--- a/foreign/python/tests/conftest.py
+++ b/foreign/python/tests/conftest.py
@@ -117,12 +117,14 @@ async def cleanup_streams(
return
client: IggyClient = request.getfixturevalue("iggy_client")
- existing_stream_ids = {stream.id for stream in await client.get_streams()}
+ existing_streams = {
+ (stream.id, stream.created_at) for stream in await client.get_streams()
+ }
yield
for stream in await client.get_streams():
- if stream.id not in existing_stream_ids:
+ if (stream.id, stream.created_at) not in existing_streams:
with contextlib.suppress(RuntimeError):
await client.delete_stream(stream.id)
diff --git a/foreign/python/tests/test_stream.py b/foreign/python/tests/test_stream.py
index 6252c4fca..c6e6bdc75 100644
--- a/foreign/python/tests/test_stream.py
+++ b/foreign/python/tests/test_stream.py
@@ -254,6 +254,10 @@ class TestGetStreams:
assert listed is not None
assert listed.topics_count == 1
+ stream = await iggy_client.get_stream(stream_name)
+ assert stream is not None
+ assert [topic.name for topic in stream.topics] == [topic_name]
+
@pytest.mark.asyncio
async def test_get_streams_returns_same_result_when_called_repeatedly(
self, iggy_client: IggyClient, unique_name
@@ -324,6 +328,21 @@ class TestUpdateStream:
assert renamed is not None
assert renamed.name == new_name
+ @pytest.mark.asyncio
+ async def test_update_stream_forwards_options(
+ self, iggy_client: IggyClient, unique_name
+ ):
+ """Test update_stream forwards option keys to the server."""
+ stream_name = unique_name()
+ await iggy_client.create_stream(stream_name)
+
+ with pytest.raises(RuntimeError):
+ await iggy_client.update_stream(
+ stream_id=stream_name,
+ name=stream_name,
+ options={"unknown": "value"},
+ )
+
@pytest.mark.asyncio
@pytest.mark.parametrize(
"new_name",
@@ -341,12 +360,9 @@ class TestUpdateStream:
await iggy_client.create_stream(stream_name)
await iggy_client.update_stream(stream_id=stream_name, name=new_name)
- try:
- renamed = await iggy_client.get_stream(new_name)
- assert renamed is not None
- assert renamed.name == new_name
- finally:
- await iggy_client.delete_stream(new_name)
+ renamed = await iggy_client.get_stream(new_name)
+ assert renamed is not None
+ assert renamed.name == new_name
@pytest.mark.asyncio
@pytest.mark.parametrize(
@@ -400,10 +416,10 @@ class TestUpdateStream:
await iggy_client.update_stream(stream_id=unique_name(), name=unique_name())
@pytest.mark.asyncio
- async def test_update_stream_to_existing_name_fails(
+ async def test_update_stream_to_existing_name_fails_and_current_name_is_a_noop(
self, iggy_client: IggyClient, unique_name
):
- """Test update_stream rejects renaming a stream to a name already in use."""
+ """Test update_stream rejects conflicts and preserves a self-rename."""
first_stream = unique_name()
second_stream = unique_name()
@@ -423,6 +439,8 @@ class TestUpdateStream:
with pytest.raises(RuntimeError):
await iggy_client.update_stream(stream_id=second_stream, name=first_stream)
+ await iggy_client.update_stream(stream_id=second_stream, name=second_stream)
+
streams = await iggy_client.get_streams()
after = next(stream for stream in streams if stream.id == before.id)
assert (
(iggy) 09/11: address comments
Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
slbotbm pushed a commit to branch feat/add-python-stream-management-functions
in repository https://gitbox.apache.org/repos/asf/iggy.git
commit e47f23347484ceb126cde4df836793b3aa6d4ea7
Author: Rimuksh Kansal <ni...@gmail.com>
AuthorDate: Mon Aug 31 15:20:38 2026 +0900
address comments
---
foreign/python/apache_iggy.pyi | 16 +++++++++++++---
foreign/python/src/stream.rs | 18 +++++++++++++++---
foreign/python/tests/test_stream.py | 8 +++++---
3 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/foreign/python/apache_iggy.pyi b/foreign/python/apache_iggy.pyi
index c4b193a2d..95d4debf1 100644
--- a/foreign/python/apache_iggy.pyi
+++ b/foreign/python/apache_iggy.pyi
@@ -1920,8 +1920,8 @@ class Stream:
r"""
Summary information returned by `IggyClient.get_streams()`.
- `created_at` is Unix time in microseconds. `size_bytes` is the stream's
- current stored size in bytes.
+ `created_at` is Unix time in microseconds. `size` is the stream's current
+ stored size in bytes.
"""
@property
def id(self) -> builtins.int:
@@ -1939,7 +1939,7 @@ class Stream:
Unique stream name.
"""
@property
- def size_bytes(self) -> builtins.int:
+ def size(self) -> builtins.int:
r"""
Current stored stream size in bytes.
"""
@@ -1957,10 +1957,20 @@ class Stream:
@typing.final
class StreamDetails:
@property
+ def created_at(self) -> builtins.int:
+ r"""
+ Stream creation time as Unix time in microseconds.
+ """
+ @property
def id(self) -> builtins.int: ...
@property
def name(self) -> builtins.str: ...
@property
+ def size(self) -> builtins.int:
+ r"""
+ Current stored stream size in bytes.
+ """
+ @property
def messages_count(self) -> builtins.int: ...
@property
def topics_count(self) -> builtins.int: ...
diff --git a/foreign/python/src/stream.rs b/foreign/python/src/stream.rs
index 2a7055b2d..9b6126ad9 100644
--- a/foreign/python/src/stream.rs
+++ b/foreign/python/src/stream.rs
@@ -36,6 +36,12 @@ impl From<RustStreamDetails> for StreamDetails {
#[gen_stub_pymethods]
#[pymethods]
impl StreamDetails {
+ /// Stream creation time as Unix time in microseconds.
+ #[getter]
+ pub fn created_at(&self) -> u64 {
+ self.inner.created_at.as_micros()
+ }
+
#[getter]
pub fn id(&self) -> u32 {
self.inner.id
@@ -46,6 +52,12 @@ impl StreamDetails {
self.inner.name.to_string()
}
+ /// Current stored stream size in bytes.
+ #[getter]
+ pub fn size(&self) -> u64 {
+ self.inner.size.as_bytes_u64()
+ }
+
#[getter]
pub fn messages_count(&self) -> u64 {
self.inner.messages_count
@@ -59,8 +71,8 @@ impl StreamDetails {
/// Summary information returned by `IggyClient.get_streams()`.
///
-/// `created_at` is Unix time in microseconds. `size_bytes` is the stream's
-/// current stored size in bytes.
+/// `created_at` is Unix time in microseconds. `size` is the stream's current
+/// stored size in bytes.
#[gen_stub_pyclass]
#[pyclass]
pub struct Stream {
@@ -96,7 +108,7 @@ impl Stream {
/// Current stored stream size in bytes.
#[getter]
- pub fn size_bytes(&self) -> u64 {
+ pub fn size(&self) -> u64 {
self.inner.size.as_bytes_u64()
}
diff --git a/foreign/python/tests/test_stream.py b/foreign/python/tests/test_stream.py
index a44dec183..6252c4fca 100644
--- a/foreign/python/tests/test_stream.py
+++ b/foreign/python/tests/test_stream.py
@@ -62,7 +62,9 @@ class TestStreamOperations:
stream = await iggy_client.get_stream(stream_name)
assert stream is not None
+ assert stream.created_at > 0
assert stream.name == stream_name
+ assert stream.size == 0
assert stream.topics_count == 0
@pytest.mark.asyncio
@@ -228,7 +230,7 @@ class TestGetStreams:
assert {stream.name for stream in mine} == created_names
assert [stream.id for stream in mine] == sorted(stream.id for stream in mine)
assert all(stream.created_at > 0 for stream in mine)
- assert all(stream.size_bytes == 0 for stream in mine)
+ assert all(stream.size == 0 for stream in mine)
assert all(stream.messages_count == 0 for stream in mine)
assert all(stream.topics_count == 0 for stream in mine)
@@ -413,7 +415,7 @@ class TestUpdateStream:
before.id,
before.created_at,
before.name,
- before.size_bytes,
+ before.size,
before.messages_count,
before.topics_count,
)
@@ -427,7 +429,7 @@ class TestUpdateStream:
after.id,
after.created_at,
after.name,
- after.size_bytes,
+ after.size,
after.messages_count,
after.topics_count,
) == before_metadata
(iggy) 03/11: add proper docs
Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
slbotbm pushed a commit to branch feat/add-python-stream-management-functions
in repository https://gitbox.apache.org/repos/asf/iggy.git
commit 21e5177a5ed5ef3361d1f864ebe42ad30d2bc190
Author: Rimuksh Kansal <ni...@gmail.com>
AuthorDate: Tue Aug 4 17:14:17 2026 +0900
add proper docs
---
foreign/python/src/client.rs | 70 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 62 insertions(+), 8 deletions(-)
diff --git a/foreign/python/src/client.rs b/foreign/python/src/client.rs
index f2d8567ad..796c8ac9b 100644
--- a/foreign/python/src/client.rs
+++ b/foreign/python/src/client.rs
@@ -500,8 +500,16 @@ impl IggyClient {
})
}
- /// Gets all streams.
- /// Returns a list of streams or a PyRuntimeError on failure.
+ /// Return all streams visible to the authenticated user.
+ ///
+ /// The result is ordered by ascending numeric stream ID.
+ ///
+ /// Returns:
+ /// A list of `Stream` summaries.
+ ///
+ /// Raises:
+ /// RuntimeError: If the client is not authenticated, the user lacks global
+ /// `read_streams` or `manage_streams` permission, or the request fails.
#[gen_stub(override_return_type(type_repr="collections.abc.Awaitable[list[Stream]]", imports=("collections.abc")))]
fn get_streams<'a>(&self, py: Python<'a>) -> PyResult<Bound<'a, PyAny>> {
let inner = self.inner.clone();
@@ -514,8 +522,25 @@ impl IggyClient {
})
}
- /// Updates a stream's name by id.
- /// Returns Ok(()) on successful update or a PyRuntimeError on failure.
+ /// Rename a stream selected by name or numeric ID.
+ ///
+ /// `stream_id` accepts a stream name as `str` or numeric ID as `int`. A
+ /// decimal-only string is interpreted as a numeric ID. `name` must be unique
+ /// and contain between 1 and 255 UTF-8 bytes. Renaming a stream to its current
+ /// name succeeds without changing it.
+ ///
+ /// Returns:
+ /// None.
+ ///
+ /// Raises:
+ /// TypeError: If `stream_id` is neither `str` nor `int`, or `name` is not
+ /// `str`.
+ /// OverflowError: If an integer identifier is outside `0..=2**32 - 1`.
+ /// ValueError: If a string identifier is empty or exceeds 255 UTF-8 bytes.
+ /// RuntimeError: If the client is not authenticated, the user lacks global
+ /// `manage_streams` or per-stream `manage_stream` permission, the
+ /// stream does not exist, the new name is invalid or already used, or
+ /// the request fails.
#[gen_stub(override_return_type(type_repr="collections.abc.Awaitable[None]", imports=("collections.abc")))]
fn update_stream<'a>(
&self,
@@ -534,8 +559,22 @@ impl IggyClient {
})
}
- /// Deletes a stream by id.
- /// Returns Ok(()) on successful deletion or a PyRuntimeError on failure.
+ /// Delete a stream selected by name or numeric ID.
+ ///
+ /// Deletion removes the stream and all of its topics, partitions, and messages.
+ /// `stream_id` accepts a stream name as `str` or numeric ID as `int`. A
+ /// decimal-only string is interpreted as a numeric ID.
+ ///
+ /// Returns:
+ /// None.
+ ///
+ /// Raises:
+ /// TypeError: If `stream_id` is neither `str` nor `int`.
+ /// OverflowError: If an integer identifier is outside `0..=2**32 - 1`.
+ /// ValueError: If a string identifier is empty or exceeds 255 UTF-8 bytes.
+ /// RuntimeError: If the client is not authenticated, the user lacks global
+ /// `manage_streams` or per-stream `manage_stream` permission, the
+ /// stream does not exist, or the request fails.
#[gen_stub(override_return_type(type_repr="collections.abc.Awaitable[None]", imports=("collections.abc")))]
fn delete_stream<'a>(
&self,
@@ -553,8 +592,23 @@ impl IggyClient {
})
}
- /// Purges all messages from a stream by id.
- /// Returns Ok(()) on successful purge or a PyRuntimeError on failure.
+ /// Delete all messages from every topic in a stream.
+ ///
+ /// The stream, topics, and partitions remain available. Repeated purges of an
+ /// existing empty stream succeed. `stream_id` accepts a stream name as `str`
+ /// or numeric ID as `int`. A decimal-only string is interpreted as a numeric
+ /// ID.
+ ///
+ /// Returns:
+ /// None.
+ ///
+ /// Raises:
+ /// TypeError: If `stream_id` is neither `str` nor `int`.
+ /// OverflowError: If an integer identifier is outside `0..=2**32 - 1`.
+ /// ValueError: If a string identifier is empty or exceeds 255 UTF-8 bytes.
+ /// RuntimeError: If the client is not authenticated, the user lacks global
+ /// `manage_streams` or per-stream `manage_stream` permission, the
+ /// stream does not exist, or the request fails.
#[gen_stub(override_return_type(type_repr="collections.abc.Awaitable[None]", imports=("collections.abc")))]
fn purge_stream<'a>(
&self,
(iggy) 08/11: fix test
Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
slbotbm pushed a commit to branch feat/add-python-stream-management-functions
in repository https://gitbox.apache.org/repos/asf/iggy.git
commit af3e0aabd52fe9325d8d0b5940fc1629de02eafc
Author: Rimuksh Kansal <ni...@gmail.com>
AuthorDate: Sun Aug 16 18:08:45 2026 +0900
fix test
---
foreign/python/tests/conftest.py | 34 +++++++++++++++-------------------
foreign/python/tests/test_stream.py | 10 ++++++----
2 files changed, 21 insertions(+), 23 deletions(-)
diff --git a/foreign/python/tests/conftest.py b/foreign/python/tests/conftest.py
index 5c8d15a1c..734054069 100644
--- a/foreign/python/tests/conftest.py
+++ b/foreign/python/tests/conftest.py
@@ -71,13 +71,7 @@ async def iggy_client() -> IggyClient:
@pytest.fixture
-def issued_names() -> set[str]:
- """Return names created by unique_name in one test."""
- return set()
-
-
-@pytest.fixture
-def unique_name(issued_names: set[str]):
+def unique_name():
"""Return a factory for generating unique test names."""
def make_name(
@@ -108,27 +102,29 @@ def unique_name(issued_names: set[str]):
+ min_suffix_bytes
)
suffix = "".join(secrets.choice(alphabet) for _ in range(suffix_bytes))
- name = f"{prefix}{suffix}"
- issued_names.add(name)
- return name
+ return f"{prefix}{suffix}"
return make_name
-@pytest.fixture(autouse=True)
+@pytest.fixture(scope="function", autouse=True)
async def cleanup_streams(
- request: pytest.FixtureRequest, issued_names: set[str]
+ request: pytest.FixtureRequest,
) -> AsyncGenerator[None, None]:
"""Delete streams created by the current test."""
- yield
-
- if not issued_names:
+ if "iggy_client" not in request.fixturenames:
+ yield
return
- client = request.getfixturevalue("iggy_client")
- for name in issued_names:
- with contextlib.suppress(RuntimeError):
- await client.delete_stream(name)
+ client: IggyClient = request.getfixturevalue("iggy_client")
+ existing_stream_ids = {stream.id for stream in await client.get_streams()}
+
+ yield
+
+ for stream in await client.get_streams():
+ if stream.id not in existing_stream_ids:
+ with contextlib.suppress(RuntimeError):
+ await client.delete_stream(stream.id)
@pytest.fixture(scope="session", autouse=True)
diff --git a/foreign/python/tests/test_stream.py b/foreign/python/tests/test_stream.py
index 24e55e66c..a44dec183 100644
--- a/foreign/python/tests/test_stream.py
+++ b/foreign/python/tests/test_stream.py
@@ -339,10 +339,12 @@ class TestUpdateStream:
await iggy_client.create_stream(stream_name)
await iggy_client.update_stream(stream_id=stream_name, name=new_name)
-
- renamed = await iggy_client.get_stream(new_name)
- assert renamed is not None
- assert renamed.name == new_name
+ try:
+ renamed = await iggy_client.get_stream(new_name)
+ assert renamed is not None
+ assert renamed.name == new_name
+ finally:
+ await iggy_client.delete_stream(new_name)
@pytest.mark.asyncio
@pytest.mark.parametrize(