sharedbox 0.6.0__tar.gz → 0.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/ci.yaml +5 -5
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/ops.yaml +21 -3
- {sharedbox-0.6.0 → sharedbox-0.8.0}/CHANGELOG.md +186 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/CLAUDE.md +31 -16
- {sharedbox-0.6.0 → sharedbox-0.8.0}/CMakeLists.txt +5 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/PKG-INFO +3 -1
- sharedbox-0.8.0/benchmarks/test_bench_box.py +440 -0
- sharedbox-0.8.0/docs/examples/attach_metadata.py +78 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/send_items_through_a_stream.py +59 -1
- sharedbox-0.8.0/docs/examples/store_a_large_list.py +81 -0
- sharedbox-0.8.0/docs/examples/store_a_large_set_or_dict.py +107 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/store_arrays.py +38 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/store_collections.py +1 -1
- sharedbox-0.8.0/docs/examples/store_numpy_numbers.py +82 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/store_text_and_bytes.py +2 -2
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/field-types.md +24 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/glossary.md +30 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/how-a-box-is-stored.md +1 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/accept-a-box-in-c.md +5 -3
- sharedbox-0.8.0/docs/how-to/attach-metadata.md +192 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/commits-and-prs.md +13 -3
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/index.md +7 -0
- sharedbox-0.8.0/docs/how-to/migrate-from-0.7.md +83 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/send-items-through-a-stream.md +80 -7
- sharedbox-0.8.0/docs/how-to/store-a-large-list.md +152 -0
- sharedbox-0.8.0/docs/how-to/store-a-large-set-or-dict.md +235 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/store-arrays.md +33 -3
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/store-collections.md +9 -1
- sharedbox-0.8.0/docs/how-to/store-numpy-numbers.md +107 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/store-text-and-bytes.md +7 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/arrays.md +5 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/box.md +18 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/errors.md +15 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/events.md +1 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/segment-layout.md +466 -66
- {sharedbox-0.6.0 → sharedbox-0.8.0}/include/sharedbox/box.hpp +192 -20
- {sharedbox-0.6.0 → sharedbox-0.8.0}/include/sharedbox/core.hpp +598 -27
- {sharedbox-0.6.0 → sharedbox-0.8.0}/include/sharedbox/sharedbox_c.cpp +71 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/include/sharedbox/sharedbox_c.h +20 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/include/sharedbox/stream.hpp +267 -55
- {sharedbox-0.6.0 → sharedbox-0.8.0}/includes/abbreviations.md +1 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/pyproject.toml +6 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/__init__.py +13 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_arrays.py +77 -23
- sharedbox-0.8.0/src/sharedbox/_bounded.py +354 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_box.py +232 -49
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_events.py +35 -7
- sharedbox-0.8.0/src/sharedbox/_exit.py +193 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_layout.py +64 -20
- sharedbox-0.8.0/src/sharedbox/_metadata.py +134 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/codec.cpp +35 -18
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/codec.hpp +56 -0
- sharedbox-0.8.0/src/sharedbox/_native/collection.cpp +662 -0
- sharedbox-0.8.0/src/sharedbox/_native/collection.hpp +226 -0
- sharedbox-0.8.0/src/sharedbox/_native/dict.cpp +386 -0
- sharedbox-0.8.0/src/sharedbox/_native/dict.hpp +88 -0
- sharedbox-0.8.0/src/sharedbox/_native/keys.cpp +369 -0
- sharedbox-0.8.0/src/sharedbox/_native/keys.hpp +130 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/module.cpp +421 -58
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/scalars.cpp +253 -41
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/scalars.hpp +13 -5
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/segment.cpp +93 -13
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/segment.hpp +31 -14
- sharedbox-0.8.0/src/sharedbox/_native/set.cpp +335 -0
- sharedbox-0.8.0/src/sharedbox/_native/set.hpp +87 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/stream.cpp +217 -31
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/types.cpp +435 -80
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/types.hpp +118 -7
- sharedbox-0.8.0/src/sharedbox/_native.pyi +1419 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_refs.py +6 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_stream.py +501 -88
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_types.py +488 -66
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_version.py +3 -3
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/ops.py +283 -4
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/stream.py +2 -2
- {sharedbox-0.6.0 → sharedbox-0.8.0}/stubtest-allowlist.txt +17 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/CMakeLists.txt +1 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/consumer/consumer.c +4 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_c_smoke.c +25 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_c_smoke_box.cpp +5 -5
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_layout3.cpp +72 -5
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_mapping.cpp +8 -8
- sharedbox-0.8.0/tests/cpp/test_metadata.cpp +1022 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_stream.cpp +224 -2
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_stream_layout.cpp +54 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_types.cpp +162 -2
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_values.cpp +30 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/crossproc.py +31 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/forged_open.py +10 -1
- sharedbox-0.8.0/tests/signatures.py +12 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/streamproc.py +77 -3
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_read_into.py +2 -2
- sharedbox-0.8.0/tests/test_bounded_dict.py +728 -0
- sharedbox-0.8.0/tests/test_bounded_list.py +944 -0
- sharedbox-0.8.0/tests/test_bounded_set.py +873 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_box.py +2 -2
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_capsule.py +29 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_doc_examples.py +5 -2
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_events_bytes.py +1 -1
- sharedbox-0.8.0/tests/test_exit.py +257 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_fields.py +57 -8
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_layout.py +36 -0
- sharedbox-0.8.0/tests/test_metadata.py +509 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_segment.py +5 -4
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_stream.py +6 -14
- sharedbox-0.8.0/tests/test_properties_bounded.py +286 -0
- sharedbox-0.8.0/tests/test_properties_bounded_dict.py +250 -0
- sharedbox-0.8.0/tests/test_properties_bounded_set.py +249 -0
- sharedbox-0.8.0/tests/test_properties_numpy.py +99 -0
- sharedbox-0.8.0/tests/test_properties_stream.py +353 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_read_into.py +6 -6
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_refs.py +2 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_stream.py +438 -12
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_stream_async.py +71 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_stream_events.py +32 -1
- sharedbox-0.8.0/tests/test_stream_metadata.py +478 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_stream_processes.py +40 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_stream_writing.py +1 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_arrays.py +86 -36
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_arrays_bfloat16.py +1 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_arrays_torch.py +1 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_collections.py +43 -0
- sharedbox-0.8.0/tests/test_types_numpy.py +456 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_records.py +102 -6
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_records_attrs.py +18 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_unions.py +14 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_value_reuse.py +1 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_writing.py +4 -4
- sharedbox-0.8.0/tests/type_checks/bounded_types.py +36 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/type_checks/box_types.py +1 -1
- sharedbox-0.8.0/tests/type_checks/metadata_types.py +132 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/uv.lock +68 -1
- {sharedbox-0.6.0 → sharedbox-0.8.0}/zensical.toml +5 -0
- sharedbox-0.6.0/benchmarks/test_bench_box.py +0 -98
- sharedbox-0.6.0/src/sharedbox/_native.pyi +0 -535
- sharedbox-0.6.0/tests/test_exit.py +0 -53
- sharedbox-0.6.0/tests/test_properties_stream.py +0 -121
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.clang-format +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/dependabot.yml +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/pull_request_template.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/check-changelog.yaml +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/check-docs.yaml +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/codspeed.yml +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/contention.yaml +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/prepare-release.yaml +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/publish-docs.yaml +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/streams.yaml +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/.gitignore +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/LICENSE +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/README.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/benchmarks/test_bench_stream.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/changelog.d/.gitkeep +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/cmake/sharedbox-config.cmake +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/cmake/sharedbox-require-cxx.cmake +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/assets/benchmarks/ops.json +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/assets/benchmarks/roundtrip.json +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/assets/benchmarks/stream-matrix.json +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/assets/benchmarks/stream-throughput.json +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/diagrams/style.d2 +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/change_several_fields_at_once.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/clean_up_segments.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/follow_a_whole_reference_graph.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/name_a_box.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/send_a_box_to_another_process.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/set_defaults_and_check_values.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/store_records.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/checking-a-process-is-alive.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/closing-and-lifetime.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/how-the-module-is-built.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/index.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/limits.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/performance.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/reading-and-writing.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/references.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/waiting-for-changes.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/when-to-use-sharedbox.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/accept-a-box-in-cpp.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/ai-contribution-policy.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/build-docs.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/change-several-fields-at-once.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/clean-up-segments.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/contribute.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/follow-a-whole-reference-graph.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/install-sharedbox.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/make-a-release.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/name-a-box.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/open-a-box-from-a-program.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/run-benchmarks.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/run-commit-checks.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/run-tests.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/send-a-box-to-another-process.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/set-defaults-and-check-values.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/set-up-development.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/store-records.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/write-docs.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/index.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/javascripts/charts.js +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/index.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/library-authors.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/references.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/streams.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/changelog.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/cpp-and-c-api.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/index.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/tutorials/index.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/tutorials/mailbox.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/tutorials/react-to-changes.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/tutorials/refer-to-another-box.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/tutorials/share-a-record.md +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/include/sharedbox/sharedbox.hpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/prek.toml +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/scripts/check_xrefs.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/scripts/release_notes.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/scripts/stream_compare.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/scripts/vscode_setup.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_follow.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/stream.hpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/__init__.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/__main__.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/_app.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/cli.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/contention.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/plot.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/roundtrip.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/size.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/size_diff.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/py.typed +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/conftest.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/bench_stream.cpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/compile_fail.cpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/consumer/CMakeLists.txt +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/table_builder.hpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_atomics.cpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_core_alone.cpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_fork.cpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_lock.cpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_result.cpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_slots.cpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_small_shm.cpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_wait.cpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_windows_h.cpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_write_in_place.cpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/unique.hpp +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/forged_types.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/os_names.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/refs_future.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/stress_helpers.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_contention.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_crashes.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_follow.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_lock_timeout.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_memory.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_waiters.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_watchers.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_benchbox_all.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_benchbox_contention.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_benchbox_plot.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_benchbox_roundtrip.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_benchbox_stream.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_box_sync_async.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_doc_tutorials.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_events_async.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_events_future.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_events_signals.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_events_sync.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_follow.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_fork.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_codec.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_liveness.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_types.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_wait.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_waiters.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_properties_codec.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_properties_forged.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_properties_layout.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_properties_stateful.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_properties_types.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_refs_lazy.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_stream_fork.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_choices.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_records_msgspec.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_scalars.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/type_checks/array_types.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/type_checks/events_types.py +0 -0
- {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/type_checks/stream_types.py +0 -0
|
@@ -114,11 +114,11 @@ jobs:
|
|
|
114
114
|
ref: ${{ github.event_name == 'release' && github.event.release.tag_name || '' }}
|
|
115
115
|
|
|
116
116
|
- name: Build wheels
|
|
117
|
-
uses: pypa/cibuildwheel@v4.3.
|
|
117
|
+
uses: pypa/cibuildwheel@v4.3.4
|
|
118
118
|
env:
|
|
119
119
|
CIBW_BUILD: ${{ matrix.python }}-${{ matrix.platform_id }}
|
|
120
120
|
CIBW_CONTAINER_ENGINE: "docker; create_args: --shm-size=1g"
|
|
121
|
-
CIBW_TEST_REQUIRES: pytest hypothesis numpy
|
|
121
|
+
CIBW_TEST_REQUIRES: pytest hypothesis numpy attrs
|
|
122
122
|
CIBW_TEST_COMMAND: pytest {project}/tests
|
|
123
123
|
with:
|
|
124
124
|
package-dir: .
|
|
@@ -212,11 +212,11 @@ jobs:
|
|
|
212
212
|
shell: bash
|
|
213
213
|
run: |
|
|
214
214
|
uv venv --python 3.12 .stress
|
|
215
|
-
uv pip install --python .stress wheelhouse/*.whl pytest hypothesis
|
|
215
|
+
uv pip install --python .stress wheelhouse/*.whl pytest hypothesis numpy attrs
|
|
216
216
|
python=.stress/bin/python
|
|
217
217
|
[ -x "$python" ] || python=.stress/Scripts/python.exe
|
|
218
218
|
"$python" -m pytest -m stress -q -p no:cacheprovider
|
|
219
|
-
"$python" -m pytest tests/
|
|
219
|
+
"$python" -m pytest tests/test_properties_*.py -q -p no:cacheprovider --hypothesis-profile=thorough
|
|
220
220
|
|
|
221
221
|
- uses: actions/upload-artifact@v7
|
|
222
222
|
if: always()
|
|
@@ -246,7 +246,7 @@ jobs:
|
|
|
246
246
|
- uses: actions/checkout@v7
|
|
247
247
|
with:
|
|
248
248
|
fetch-depth: 0
|
|
249
|
-
ref: ${{ github.
|
|
249
|
+
ref: ${{ github.event.release.tag_name }}
|
|
250
250
|
|
|
251
251
|
- name: Check the changelog has a section for a final release
|
|
252
252
|
env:
|
|
@@ -8,6 +8,7 @@ on:
|
|
|
8
8
|
- src/sharedbox/_native/**
|
|
9
9
|
- src/sharedbox/benchmarks/ops.py
|
|
10
10
|
- .github/workflows/ops.yaml
|
|
11
|
+
- CMakeLists.txt
|
|
11
12
|
workflow_dispatch:
|
|
12
13
|
|
|
13
14
|
permissions:
|
|
@@ -41,13 +42,28 @@ jobs:
|
|
|
41
42
|
|
|
42
43
|
- name: Run benchbox ops, alternating base and head
|
|
43
44
|
shell: bash
|
|
45
|
+
env:
|
|
46
|
+
# The 64k set and dict rows nearly double the job, so a pull request skips them.
|
|
47
|
+
SIZES: ${{ github.event_name == 'pull_request' && '[!6]*' || '*' }}
|
|
44
48
|
run: |
|
|
45
49
|
mkdir results
|
|
50
|
+
step=0
|
|
51
|
+
total=18 # 3 rounds x 2 sides x (int, record), plus list, set and dict once per side
|
|
46
52
|
for round in 1 2 3; do
|
|
47
53
|
for side in base head; do
|
|
48
|
-
for rows in int record; do
|
|
54
|
+
for rows in int record list set dict; do
|
|
55
|
+
case "$rows" in list|set|dict) [ "$round" != 1 ] && continue ;; esac # not gated, one round is enough
|
|
56
|
+
step=$((step + 1))
|
|
57
|
+
echo "::group::[$step/$total] round $round, $side, $rows rows"
|
|
58
|
+
case "$rows" in
|
|
59
|
+
list) pattern="*list*/*" ;;
|
|
60
|
+
set) pattern="*set$SIZES/*" ;;
|
|
61
|
+
dict) pattern="*dict$SIZES/*" ;;
|
|
62
|
+
*) pattern="*$rows/SharedBox" ;;
|
|
63
|
+
esac
|
|
49
64
|
(cd "$side" && uv run --no-sync benchbox ops --fast \
|
|
50
|
-
--filter "
|
|
65
|
+
--filter "$pattern" --json "../results/$side-$round-$rows.json")
|
|
66
|
+
echo "::endgroup::"
|
|
51
67
|
done
|
|
52
68
|
done
|
|
53
69
|
done
|
|
@@ -69,7 +85,9 @@ jobs:
|
|
|
69
85
|
side = path.name.split("-")[0]
|
|
70
86
|
for bench in pyperf.BenchmarkSuite.load(str(path)).get_benchmarks():
|
|
71
87
|
means.setdefault((bench.get_name(), side), []).append(bench.mean())
|
|
72
|
-
print("### benchbox ops on Windows cp311, median of three rounds")
|
|
88
|
+
print("### benchbox ops on Windows cp311, median of three rounds, list, set and dict rows one round")
|
|
89
|
+
print()
|
|
90
|
+
print("A pull request skips the 64k set and dict rows; start the workflow by hand for them.")
|
|
73
91
|
print()
|
|
74
92
|
print(machine())
|
|
75
93
|
print()
|
|
@@ -9,6 +9,192 @@ Dates are marked as `DD-MM-YYYY`
|
|
|
9
9
|
|
|
10
10
|
<!-- towncrier release notes start -->
|
|
11
11
|
|
|
12
|
+
## [0.8.0](https://github.com/jacopoabramo/sharedbox/releases/tag/v0.8.0) - 30-10-2026
|
|
13
|
+
|
|
14
|
+
### Breaking
|
|
15
|
+
|
|
16
|
+
- `sharedbox.Shape` takes its dimensions as one tuple, `Shape((480, 640))`, in
|
|
17
|
+
place of one argument per dimension. See
|
|
18
|
+
[How to migrate from 0.7](https://jacopoabramo.github.io/sharedbox/how-to/migrate-from-0.7/). ([#88](https://github.com/jacopoabramo/sharedbox/pull/88))
|
|
19
|
+
- `SharedBox` reserves the names `metadata`, `metadata_version` and
|
|
20
|
+
`metadata_version_of`: a field or `InitVar` with one of them raises
|
|
21
|
+
`TypeError` when the class is defined. Rename the field:
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
# 0.7
|
|
25
|
+
class Parcel(SharedBox):
|
|
26
|
+
metadata: Annotated[str, Capacity(64)] = ""
|
|
27
|
+
|
|
28
|
+
# 0.8
|
|
29
|
+
class Parcel(SharedBox):
|
|
30
|
+
label: Annotated[str, Capacity(64)] = ""
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`SharedBox.update` takes the keyword `metadata`, so a type checker refuses
|
|
34
|
+
`update(**values)` when the values of the dictionary have a type that the
|
|
35
|
+
box's metadata type does not accept, such as `str`:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
# 0.7
|
|
39
|
+
def restock(parcel: Parcel, values: dict[str, str]) -> None:
|
|
40
|
+
parcel.update(**values)
|
|
41
|
+
|
|
42
|
+
# 0.8
|
|
43
|
+
def restock(parcel: Parcel, values: dict[str, Any]) -> None:
|
|
44
|
+
parcel.update(**values)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
See
|
|
48
|
+
[How to migrate from 0.7](https://jacopoabramo.github.io/sharedbox/how-to/migrate-from-0.7/). ([#91](https://github.com/jacopoabramo/sharedbox/pull/91))
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- `MaxShape`: an array of a stream item declared with a maximum shape, as in
|
|
53
|
+
`Annotated[npt.NDArray[np.uint16], MaxShape((2048, 2048))]`, stores its own
|
|
54
|
+
shape with each item, as kind 75 of stream layout 1.2. `writing()` views the
|
|
55
|
+
slot in the shape of the template's array, `slot.send` publishes the first
|
|
56
|
+
rows of that view without a copy, and `receive_into` returns a view of the
|
|
57
|
+
stored shape over `out`. ([#88](https://github.com/jacopoabramo/sharedbox/pull/88))
|
|
58
|
+
- `SharedStream.sender(on_full="release")`: a send that has waited its whole
|
|
59
|
+
`timeout` releases the lossless readers a full ring behind and sends, as in
|
|
60
|
+
`stream.sender(on_full="release").send(item, timeout=0.1)`. Each released
|
|
61
|
+
reader raises `ReaderReleased`, whose `missed` counts the items it lost, and
|
|
62
|
+
goes on at the newest item; `ReceiveEvents.released` reports the count to
|
|
63
|
+
callbacks. `SharedSendStream.asend` and `awriting` take a `timeout`. In
|
|
64
|
+
`stream.hpp`, `send`, `send_with` and `begin` take an `on_full` policy, and a
|
|
65
|
+
released reader's `receive` gives `status::released`, in stream layout 1.3. ([#89](https://github.com/jacopoabramo/sharedbox/pull/89))
|
|
66
|
+
- `MetadataFullError` and `MetadataGoneError`: raised when an add finds no
|
|
67
|
+
room for a version, and when the version a read asks for is no longer held. ([#91](https://github.com/jacopoabramo/sharedbox/pull/91))
|
|
68
|
+
- `SharedStream.metadata`: a stream keeps metadata the same way.
|
|
69
|
+
`SharedStream.create(Reading, capacity=8, metadata={"unit": "kg"})` stores
|
|
70
|
+
version 1. `SharedSendStream.send`, `asend`, `send_nowait` and
|
|
71
|
+
`SendSlot.send` take `metadata=` and add a version that applies from that
|
|
72
|
+
item. `SharedReceiveStream.metadata` and `metadata_version` give the version
|
|
73
|
+
of the item the reader received last. `SharedStream.create` takes
|
|
74
|
+
`metadata_capacity` and `metadata_versions`, and `create` and `attach` take
|
|
75
|
+
`metadata_type`. `sharedbox` 0.7.0 and earlier cannot open a stream created
|
|
76
|
+
with metadata or a `metadata_capacity`. ([#91](https://github.com/jacopoabramo/sharedbox/pull/91))
|
|
77
|
+
- `box.hpp`, `stream.hpp` and `sharedbox_c.h`: box layout 3.2 and stream
|
|
78
|
+
layout 1.4 hold metadata after the record or the description table.
|
|
79
|
+
`handle` and `stream` gain `metadata_head` and `read_metadata`, and
|
|
80
|
+
`stream_reader` gains `metadata_version_at`. `handle` and `stream_sender`
|
|
81
|
+
gain `add_metadata`. `handle::write(values, doc, lock_timeout)` and
|
|
82
|
+
`write_large` with the same arguments write fields and add a version in one
|
|
83
|
+
write, and
|
|
84
|
+
`stream_sender::can_add_metadata` checks an add without making it.
|
|
85
|
+
`sharedbox_c.h` adds `sbx_metadata_head`, `sbx_read_metadata`,
|
|
86
|
+
`sbx_add_metadata` and `SBX_E_METADATA_FULL`. ([#91](https://github.com/jacopoabramo/sharedbox/pull/91))
|
|
87
|
+
- `SharedBox.metadata`: a box keeps metadata, JSON-like values stored as CBOR
|
|
88
|
+
in its segment, in numbered versions. `Scale.create(name, metadata={"unit":
|
|
89
|
+
"kg"})` stores version 1, and `SharedBox.update(metadata=...)` adds the next
|
|
90
|
+
one from any process, with or without field values, in one write.
|
|
91
|
+
`metadata`, `metadata_version` and `metadata_version_of` read the versions,
|
|
92
|
+
a map as a read-only mapping and a list as a tuple. `BoxEvents.metadata` is
|
|
93
|
+
emitted with each new version. The class keywords `metadata_capacity` and
|
|
94
|
+
`metadata_versions` size the room for versions, and
|
|
95
|
+
`class Scale(SharedBox[Calibration])` gives the metadata's type to type
|
|
96
|
+
checkers. ([#91](https://github.com/jacopoabramo/sharedbox/pull/91))
|
|
97
|
+
|
|
98
|
+
### Changed
|
|
99
|
+
|
|
100
|
+
- `sharedbox.DType` is a `StrEnum` with one member per element type:
|
|
101
|
+
`DType(numpy.uint8)` returns `DType.uint8`, which equals `"uint8"`. ([#88](https://github.com/jacopoabramo/sharedbox/pull/88))
|
|
102
|
+
|
|
103
|
+
### Fixed
|
|
104
|
+
|
|
105
|
+
- `SharedBox` and `SharedStream` at exit: the `atexit` hook of `sharedbox`
|
|
106
|
+
closes every box and stream the process still has open and releases the
|
|
107
|
+
native objects of `SharedBox` subclasses, their watches and events groups,
|
|
108
|
+
so nanobind reports no leaked instances when a box class defined at module
|
|
109
|
+
level outlives shutdown. A box or stream used after the hook raises
|
|
110
|
+
`BoxClosedError` or `StreamClosedError`, and creating or attaching a box
|
|
111
|
+
raises `BoxClosedError`. ([#90](https://github.com/jacopoabramo/sharedbox/pull/90))
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
## [0.7.0](https://github.com/jacopoabramo/sharedbox/releases/tag/v0.7.0) - 28-10-2026
|
|
115
|
+
|
|
116
|
+
### Added
|
|
117
|
+
|
|
118
|
+
- `np.int8`, `np.int16`, `np.int32`, `np.uint8`, `np.uint16`, `np.uint32`,
|
|
119
|
+
`np.uint64`, `np.float16`, `np.float32`, `np.complex64` and `np.datetime64`
|
|
120
|
+
as field types, record members, collection elements and stream items,
|
|
121
|
+
stored at their own width as kinds 13 to 23 of box layout 3.1 and stream
|
|
122
|
+
layout 1.1. A field reads back as its numpy type, and a value that does not
|
|
123
|
+
fit the width raises `OverflowError`. A `np.datetime64` field stores
|
|
124
|
+
nanoseconds since 1970. ([#66](https://github.com/jacopoabramo/sharedbox/pull/66))
|
|
125
|
+
- `sbx_read_float16`, `sbx_write_float16`, `sbx_read_float32` and
|
|
126
|
+
`sbx_write_float32` in `sharedbox_c.h`. ([#66](https://github.com/jacopoabramo/sharedbox/pull/66))
|
|
127
|
+
- An array annotated `X | None` as a field, record member or stream item,
|
|
128
|
+
holding `None` or an array of its sizes, as in
|
|
129
|
+
`scan: npt.NDArray[np.uint8] | None = field(default=None, shape=(32, 32))`.
|
|
130
|
+
`receive_into` does not fill one. ([#67](https://github.com/jacopoabramo/sharedbox/pull/67))
|
|
131
|
+
- `field(capacity=...)`: the capacity of a box field of text, bytes,
|
|
132
|
+
`bytearray`, `Decimal` or a collection, as in
|
|
133
|
+
`samples: list[float] = field(capacity=16)`. ([#68](https://github.com/jacopoabramo/sharedbox/pull/68))
|
|
134
|
+
- An array member of a dataclass or attrs record takes its sizes from
|
|
135
|
+
`metadata={"shape": (32, 32)}` on its field. ([#68](https://github.com/jacopoabramo/sharedbox/pull/68))
|
|
136
|
+
- `BoundedList[T]`: a list value that keeps the stored bytes of a list field,
|
|
137
|
+
as in `samples: Annotated[BoundedList[float], Capacity(65536)]`. It takes
|
|
138
|
+
every element type `list[T]` takes and is stored as `list[T]` is. A read
|
|
139
|
+
copies the bytes without decoding an element, a write of a `BoundedList` of
|
|
140
|
+
the field's element type copies them back, indexing decodes or encodes one
|
|
141
|
+
element, and a change past the capacity raises `ValueError`. Subclasses,
|
|
142
|
+
generic or with a fixed element type, can be declared in its place. ([#73](https://github.com/jacopoabramo/sharedbox/pull/73))
|
|
143
|
+
- `BoundedSet[T]`: a set value that keeps the stored bytes of a set field,
|
|
144
|
+
as in `seen: Annotated[BoundedSet[int], Capacity(65536)]`. It is stored as
|
|
145
|
+
`set[T]` is. A read copies the bytes without decoding an element, a write
|
|
146
|
+
of a `BoundedSet` of the field's element type copies them back, and `in`,
|
|
147
|
+
`add` and `remove` encode one key and compare stored bytes, through an
|
|
148
|
+
index after 64 lookups in a set of more than 8 elements. The set operators take any set and return a
|
|
149
|
+
`BoundedSet` of the same class and capacity, the comparisons take any set,
|
|
150
|
+
and a change past the capacity raises `ValueError`. A declaration raises
|
|
151
|
+
`TypeError` for an element type whose equal values could be stored
|
|
152
|
+
differently, such as `Decimal` or `int | float`. Subclasses, generic or
|
|
153
|
+
with a fixed element type, can be declared in its place. ([#77](https://github.com/jacopoabramo/sharedbox/pull/77))
|
|
154
|
+
- `BoundedDict[K, V]`: a dict value that keeps the stored bytes of a dict
|
|
155
|
+
field, as in `weights: Annotated[BoundedDict[int, float], Capacity(4096)]`.
|
|
156
|
+
It is stored as `dict[K, V]` is. A read copies the bytes without decoding
|
|
157
|
+
an item, a write of a `BoundedDict` of the field's key and value types
|
|
158
|
+
copies them back, and `d[key]`, `get` and `in` encode one key and compare
|
|
159
|
+
stored bytes, through an index after 64 lookups in a dict of more than 8
|
|
160
|
+
keys. It keeps insertion order, `|` takes any mapping and returns a
|
|
161
|
+
`BoundedDict` of the same class and capacity, and a change past the
|
|
162
|
+
capacity raises `ValueError`. Keys follow the rules of `BoundedSet`
|
|
163
|
+
elements, and values can be of any type a `dict` field holds. Subclasses,
|
|
164
|
+
generic or with fixed key and value types, can be declared in its place. ([#82](https://github.com/jacopoabramo/sharedbox/pull/82))
|
|
165
|
+
- `BoundedList` of `int`, `float`, `bool`, `complex` or NumPy integer, float,
|
|
166
|
+
complex or `bool_` elements supports the buffer protocol: `np.asarray(value)`
|
|
167
|
+
and `memoryview(value)` share its elements without decoding them, read only
|
|
168
|
+
for `bool` and `bool_`, and a change of length raises `BufferError` while
|
|
169
|
+
such a view exists. ([#85](https://github.com/jacopoabramo/sharedbox/pull/85))
|
|
170
|
+
|
|
171
|
+
### Changed
|
|
172
|
+
|
|
173
|
+
- Reading a `list`, `tuple`, `set`, `frozenset` or `dict` field allocates and
|
|
174
|
+
copies less, and reading a record whose class takes every member by position
|
|
175
|
+
no longer builds a dict of keyword arguments. ([#65](https://github.com/jacopoabramo/sharedbox/pull/65))
|
|
176
|
+
- A union stores a number through its first member of the same kind of
|
|
177
|
+
number, so `np.int64(5)` written to `float | int` reads back as `5`. ([#66](https://github.com/jacopoabramo/sharedbox/pull/66))
|
|
178
|
+
- `int`, `float`, `complex` and `bool` fields take numpy's integer, floating,
|
|
179
|
+
complex and bool scalars, and read back the Python type. `np.int64`,
|
|
180
|
+
`np.float64`, `np.complex128` and `np.bool_` fields read back as those types
|
|
181
|
+
and hash as `int`, `float`, `complex` and `bool`. ([#66](https://github.com/jacopoabramo/sharedbox/pull/66))
|
|
182
|
+
- The extension is compiled for speed instead of size. Writing a `list`, `set`
|
|
183
|
+
or `dict` field, and reading, indexing or looking up a `BoundedList` or
|
|
184
|
+
`BoundedSet`, take less time. The wheels are about 75 KB larger on Linux and
|
|
185
|
+
17 KB larger on Windows. ([#79](https://github.com/jacopoabramo/sharedbox/pull/79))
|
|
186
|
+
|
|
187
|
+
### Fixed
|
|
188
|
+
|
|
189
|
+
- A `list`, `set` or `dict` whose slots end short of its alignment, such as
|
|
190
|
+
`Annotated[list[Color], Capacity(3)]` for an `Enum` `Color`, is accepted;
|
|
191
|
+
its size is rounded up to the alignment. `sharedbox` 0.6 refuses a segment
|
|
192
|
+
that holds one. ([#66](https://github.com/jacopoabramo/sharedbox/pull/66))
|
|
193
|
+
- A `TypeError` about the sizes of an array member of a dataclass or attrs
|
|
194
|
+
record names its metadata shape, as in `metadata shape (3)`, instead of
|
|
195
|
+
`field(shape=...)`. ([#70](https://github.com/jacopoabramo/sharedbox/pull/70))
|
|
196
|
+
|
|
197
|
+
|
|
12
198
|
## [0.6.0](https://github.com/jacopoabramo/sharedbox/releases/tag/v0.6.0) - 24-10-2026
|
|
13
199
|
|
|
14
200
|
### Added
|
|
@@ -13,11 +13,11 @@ the layout and the native module converts values.
|
|
|
13
13
|
```text
|
|
14
14
|
sharedbox/
|
|
15
15
|
|-- include/sharedbox/
|
|
16
|
-
| |-- core.hpp what every segment kind uses: result and error, liveness, names, mappings, the open step, waiter slots, the type codec
|
|
17
|
-
| |-- box.hpp box layout 3.
|
|
18
|
-
| |-- stream.hpp stream layout 1.
|
|
16
|
+
| |-- core.hpp what every segment kind uses: result and error, liveness, names, mappings, the open step, waiter slots, the type codec, the metadata area and its CBOR check
|
|
17
|
+
| |-- box.hpp box layout 3.2 and its protocols: create, publish, open, lock, read, write, metadata, capsule handle
|
|
18
|
+
| |-- stream.hpp stream layout 1.4: create, open, the sender, readers, the gate, dead ends, metadata
|
|
19
19
|
| |-- sharedbox.hpp includes every kind; the header consumers include
|
|
20
|
-
| |-- sharedbox_c.h minimal C interface: sbx_open, sbx_import, sbx_read, sbx_write, sbx_schema_hash, sbx_release, sbx_field_desc, typed sbx_read_* and sbx_write_
|
|
20
|
+
| |-- sharedbox_c.h minimal C interface: sbx_open, sbx_import, sbx_read, sbx_write, sbx_schema_hash, sbx_release, sbx_field_desc, typed sbx_read_* and sbx_write_*, sbx_metadata_head, sbx_read_metadata, sbx_add_metadata
|
|
21
21
|
| `-- sharedbox_c.cpp its implementation, compiled by the consumer (CMake target sharedbox::c)
|
|
22
22
|
|-- cmake/
|
|
23
23
|
| |-- sharedbox-config.cmake find_package(sharedbox) from an installed wheel; the build writes
|
|
@@ -28,11 +28,14 @@ sharedbox/
|
|
|
28
28
|
| |-- _box.py SharedBox: class keywords, fields, fields(), create/attach, __post_init__, update, snapshot, unlink, __sharedbox_box__
|
|
29
29
|
| |-- _layout.py Capacity, field() and Field, field offsets and kind codes, schema hash
|
|
30
30
|
| |-- _types.py annotation parsing into TypeSpec, the description table
|
|
31
|
-
| |-- _arrays.py Shape, DType, SupportsDLPack, register_array_type
|
|
31
|
+
| |-- _arrays.py Shape, MaxShape, DType, SupportsDLPack, register_array_type
|
|
32
32
|
| |-- _events.py BoxEvents, FieldWatch, the watcher thread
|
|
33
33
|
| |-- _follow.py BoxEvents.follow and unfollow: forwarding the events of boxes that references reach
|
|
34
34
|
| |-- _stream.py SharedStream, SharedSendStream, SharedReceiveStream, ReceiveEvents, the statistics classes, the worker threads
|
|
35
|
+
| |-- _metadata.py metadata documents: the type variable M, CBOR encoding, read-only decoding, the cache of decoded versions
|
|
35
36
|
| |-- _refs.py reference fields: BoxRef, the class registry, BrokenReferenceError, UnknownBoxClassError
|
|
37
|
+
| |-- _exit.py the exit handler: stops the watcher and stream threads, closes boxes, streams and ends,
|
|
38
|
+
| | replaces the native objects of watchers and box classes
|
|
36
39
|
| |-- _native.pyi hand-written stub for the extension
|
|
37
40
|
| |-- py.typed
|
|
38
41
|
| |-- benchmarks/ the benchbox command (extra: benchmarks)
|
|
@@ -53,7 +56,7 @@ sharedbox/
|
|
|
53
56
|
| | checks every value of an update before any is written,
|
|
54
57
|
| | with_record reads the whole record at once
|
|
55
58
|
| |-- types.{hpp,cpp} Types: conversions of kinds above 5, arrays
|
|
56
|
-
| |-- scalars.{hpp,cpp} kinds 6 to
|
|
59
|
+
| |-- scalars.{hpp,cpp} kinds 6 to 23, the datetime C API on full-API builds
|
|
57
60
|
| |-- segment.{hpp,cpp} Segment: a sharedbox::handle plus error messages and the lifetime lock
|
|
58
61
|
| `-- stream.{hpp,cpp} Stream, Sender and Reader: the Python binding of a stream and its errors
|
|
59
62
|
|-- tests/ pytest; many tests spawn processes
|
|
@@ -67,7 +70,9 @@ sharedbox/
|
|
|
67
70
|
| |-- test_follow.py BoxEvents.follow, unfollow and nested
|
|
68
71
|
| |-- test_native_waiters.py waiter slots, dead owners, interrupt
|
|
69
72
|
| |-- test_box_sync_async.py a sync and an async watch on one box in two threads
|
|
73
|
+
| |-- test_metadata.py metadata of a box: documents, versions, events, typed access, reserved names
|
|
70
74
|
| |-- test_stream.py SharedStream, sender and reader, blocking and non-blocking calls
|
|
75
|
+
| |-- test_stream_metadata.py metadata of a stream: the version of each item, in one process and across processes
|
|
71
76
|
| |-- test_stream_async.py asyncio calls on a stream, cancellation
|
|
72
77
|
| |-- test_stream_events.py ReceiveEvents delivery
|
|
73
78
|
| |-- test_stream_processes.py streams across processes, dead senders and readers
|
|
@@ -91,7 +96,7 @@ sharedbox/
|
|
|
91
96
|
| |-- examples/ one script per how-to guide, included by the guide
|
|
92
97
|
| |-- javascripts/charts.js draws each div of class sbx-chart from a plotly figure JSON file
|
|
93
98
|
| |-- assets/benchmarks/ the figure JSON files of the performance page, from benchbox plot
|
|
94
|
-
| `-- reference/segment-layout.md core 1.0, box layout 3.
|
|
99
|
+
| `-- reference/segment-layout.md core 1.0, box layout 3.2, stream layout 1.4, names and protocols
|
|
95
100
|
|-- includes/abbreviations.md acronym tooltips appended to every page
|
|
96
101
|
|-- zensical.toml site configuration and navigation
|
|
97
102
|
|-- .github/workflows/ci.yaml lint, docs check, C++ tests, cibuildwheel wheels, tests, stress,
|
|
@@ -135,18 +140,19 @@ class's identity (the `identity` class keyword, by default
|
|
|
135
140
|
always asks for a new name and raises `SegmentExistsError` if it is taken.
|
|
136
141
|
|
|
137
142
|
Every segment starts with the same 64-byte line, whatever its kind. Core
|
|
138
|
-
version 1.0, box layout 3.
|
|
143
|
+
version 1.0, box layout 3.2, from offset 0:
|
|
139
144
|
|
|
140
145
|
- Common line 0, written once at creation: `magic` (`SBX_BOX_` for a box,
|
|
141
146
|
`SBX_STRM` for a stream), `core_major` 1, `core_minor` 0, `kind_major` 3,
|
|
142
|
-
`kind_minor`
|
|
147
|
+
`kind_minor` 2, `schema_hash`, `create_id`, `creator_start`,
|
|
143
148
|
`creator_pidns`, `creator_pid`, `waiter_slots`, `size`.
|
|
144
149
|
- Box line 1, at offset 64: `seq` (sequence lock; the generation is
|
|
145
150
|
`seq >> 1`, there is no generation field), `writer_pid`, `wake_word`,
|
|
146
151
|
`waiters` and `sleepers`, which writes and waits change; then written
|
|
147
152
|
once at creation `field_count`, `record_size`, `record`, `tail` (always
|
|
148
|
-
128)
|
|
149
|
-
|
|
153
|
+
128), `types_size`, `metadata_size` and `metadata` (the offset of the
|
|
154
|
+
metadata area, 0 for none); last `metadata_head`, the newest metadata
|
|
155
|
+
version, 0 for none, which each add changes. The header is 128 bytes.
|
|
150
156
|
- The tail: `field_count` field table entries of 8 bytes (`u32 offset`,
|
|
151
157
|
`u32 capacity_and_kind`: top 8 bits the kind code, the low 24 the
|
|
152
158
|
capacity or size, or for kinds 64 and up the offset of the field's
|
|
@@ -155,9 +161,15 @@ version 1.0, box layout 3.0, from offset 0:
|
|
|
155
161
|
`asleep_on`: the offset of the count the slot's current wait added 1 to,
|
|
156
162
|
which freeing a dead owner's slot takes back), then the description
|
|
157
163
|
table of `types_size` bytes. Kinds are 0 to 5, 6 to 12 (fixed-size
|
|
158
|
-
scalars)
|
|
159
|
-
|
|
160
|
-
|
|
164
|
+
scalars), 13 to 23 (fixed-width numbers and `datetime64`) and 64 to 75
|
|
165
|
+
(described types; 75, an array up to a maximum shape, only in a stream).
|
|
166
|
+
- The record, at a multiple of 64. `record + record_size <= 2**32 - 4096`.
|
|
167
|
+
- The metadata area, when `metadata` is not 0, at the first multiple of 64
|
|
168
|
+
after the record, `metadata + metadata_size <= 2**32 - 4096`: a 64-byte
|
|
169
|
+
line (`entries`, `ring_size`), `entries` version entries of 32 bytes
|
|
170
|
+
(`seq`, `version`, `position`, `offset`, `length`), then a ring of
|
|
171
|
+
`ring_size` bytes holding one CBOR document per version. The mapping size
|
|
172
|
+
is rounded up to 4 KiB.
|
|
161
173
|
|
|
162
174
|
`magic` is stored last on create, with release ordering, after the initial
|
|
163
175
|
values are in the record; attach waits for it. Attach copies line 0 and the
|
|
@@ -173,8 +185,11 @@ layout 1.0 or 2.0, which 0.5 and earlier wrote.
|
|
|
173
185
|
A stream's segment starts with a 256-byte header: the common line, a line
|
|
174
186
|
of geometry written once, the sender's line and the readers' line. Then
|
|
175
187
|
come a 64-byte entry per reader, the waiter slots, `capacity` slots each
|
|
176
|
-
holding a `seq` and one item,
|
|
177
|
-
|
|
188
|
+
holding a `seq` and one item, the description table, and the metadata
|
|
189
|
+
area laid out as a box's. Stream layout 1.4 keeps `metadata_size` and
|
|
190
|
+
`metadata` in the geometry line and `metadata_head` in the sender's line.
|
|
191
|
+
Every offset is 64-bit. The full specification is in
|
|
192
|
+
`docs/reference/segment-layout.md`.
|
|
178
193
|
|
|
179
194
|
### Record encoding
|
|
180
195
|
|
|
@@ -41,11 +41,16 @@ nanobind_add_module(_native
|
|
|
41
41
|
STABLE_ABI
|
|
42
42
|
FREE_THREADED
|
|
43
43
|
LTO
|
|
44
|
+
NOMINSIZE
|
|
44
45
|
NB_DOMAIN sharedbox
|
|
45
46
|
src/sharedbox/_native/codec.cpp
|
|
47
|
+
src/sharedbox/_native/collection.cpp
|
|
48
|
+
src/sharedbox/_native/dict.cpp
|
|
49
|
+
src/sharedbox/_native/keys.cpp
|
|
46
50
|
src/sharedbox/_native/module.cpp
|
|
47
51
|
src/sharedbox/_native/scalars.cpp
|
|
48
52
|
src/sharedbox/_native/segment.cpp
|
|
53
|
+
src/sharedbox/_native/set.cpp
|
|
49
54
|
src/sharedbox/_native/stream.cpp
|
|
50
55
|
src/sharedbox/_native/types.cpp)
|
|
51
56
|
target_link_libraries(_native PRIVATE sharedbox::headers)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sharedbox
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: Python containers using shared memory.
|
|
5
5
|
Author-Email: Jacopo Abramo <jacopo.abramo@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -14,7 +14,9 @@ Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
|
|
|
14
14
|
Classifier: Programming Language :: C++
|
|
15
15
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
16
|
Requires-Python: >=3.11
|
|
17
|
+
Requires-Dist: cbor2>=6.1.5
|
|
17
18
|
Requires-Dist: psygnal>=0.16.1
|
|
19
|
+
Requires-Dist: typing-extensions>=4.16.0; python_full_version < "3.13"
|
|
18
20
|
Provides-Extra: benchmarks
|
|
19
21
|
Requires-Dist: numpy>=2.4.6; extra == "benchmarks"
|
|
20
22
|
Requires-Dist: plotly>=7.1.0; extra == "benchmarks"
|