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.
Files changed (285) hide show
  1. {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/ci.yaml +5 -5
  2. {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/ops.yaml +21 -3
  3. {sharedbox-0.6.0 → sharedbox-0.8.0}/CHANGELOG.md +186 -0
  4. {sharedbox-0.6.0 → sharedbox-0.8.0}/CLAUDE.md +31 -16
  5. {sharedbox-0.6.0 → sharedbox-0.8.0}/CMakeLists.txt +5 -0
  6. {sharedbox-0.6.0 → sharedbox-0.8.0}/PKG-INFO +3 -1
  7. sharedbox-0.8.0/benchmarks/test_bench_box.py +440 -0
  8. sharedbox-0.8.0/docs/examples/attach_metadata.py +78 -0
  9. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/send_items_through_a_stream.py +59 -1
  10. sharedbox-0.8.0/docs/examples/store_a_large_list.py +81 -0
  11. sharedbox-0.8.0/docs/examples/store_a_large_set_or_dict.py +107 -0
  12. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/store_arrays.py +38 -1
  13. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/store_collections.py +1 -1
  14. sharedbox-0.8.0/docs/examples/store_numpy_numbers.py +82 -0
  15. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/store_text_and_bytes.py +2 -2
  16. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/field-types.md +24 -0
  17. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/glossary.md +30 -0
  18. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/how-a-box-is-stored.md +1 -1
  19. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/accept-a-box-in-c.md +5 -3
  20. sharedbox-0.8.0/docs/how-to/attach-metadata.md +192 -0
  21. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/commits-and-prs.md +13 -3
  22. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/index.md +7 -0
  23. sharedbox-0.8.0/docs/how-to/migrate-from-0.7.md +83 -0
  24. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/send-items-through-a-stream.md +80 -7
  25. sharedbox-0.8.0/docs/how-to/store-a-large-list.md +152 -0
  26. sharedbox-0.8.0/docs/how-to/store-a-large-set-or-dict.md +235 -0
  27. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/store-arrays.md +33 -3
  28. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/store-collections.md +9 -1
  29. sharedbox-0.8.0/docs/how-to/store-numpy-numbers.md +107 -0
  30. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/store-text-and-bytes.md +7 -1
  31. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/arrays.md +5 -0
  32. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/box.md +18 -0
  33. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/errors.md +15 -0
  34. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/events.md +1 -0
  35. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/segment-layout.md +466 -66
  36. {sharedbox-0.6.0 → sharedbox-0.8.0}/include/sharedbox/box.hpp +192 -20
  37. {sharedbox-0.6.0 → sharedbox-0.8.0}/include/sharedbox/core.hpp +598 -27
  38. {sharedbox-0.6.0 → sharedbox-0.8.0}/include/sharedbox/sharedbox_c.cpp +71 -0
  39. {sharedbox-0.6.0 → sharedbox-0.8.0}/include/sharedbox/sharedbox_c.h +20 -0
  40. {sharedbox-0.6.0 → sharedbox-0.8.0}/include/sharedbox/stream.hpp +267 -55
  41. {sharedbox-0.6.0 → sharedbox-0.8.0}/includes/abbreviations.md +1 -0
  42. {sharedbox-0.6.0 → sharedbox-0.8.0}/pyproject.toml +6 -1
  43. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/__init__.py +13 -1
  44. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_arrays.py +77 -23
  45. sharedbox-0.8.0/src/sharedbox/_bounded.py +354 -0
  46. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_box.py +232 -49
  47. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_events.py +35 -7
  48. sharedbox-0.8.0/src/sharedbox/_exit.py +193 -0
  49. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_layout.py +64 -20
  50. sharedbox-0.8.0/src/sharedbox/_metadata.py +134 -0
  51. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/codec.cpp +35 -18
  52. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/codec.hpp +56 -0
  53. sharedbox-0.8.0/src/sharedbox/_native/collection.cpp +662 -0
  54. sharedbox-0.8.0/src/sharedbox/_native/collection.hpp +226 -0
  55. sharedbox-0.8.0/src/sharedbox/_native/dict.cpp +386 -0
  56. sharedbox-0.8.0/src/sharedbox/_native/dict.hpp +88 -0
  57. sharedbox-0.8.0/src/sharedbox/_native/keys.cpp +369 -0
  58. sharedbox-0.8.0/src/sharedbox/_native/keys.hpp +130 -0
  59. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/module.cpp +421 -58
  60. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/scalars.cpp +253 -41
  61. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/scalars.hpp +13 -5
  62. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/segment.cpp +93 -13
  63. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/segment.hpp +31 -14
  64. sharedbox-0.8.0/src/sharedbox/_native/set.cpp +335 -0
  65. sharedbox-0.8.0/src/sharedbox/_native/set.hpp +87 -0
  66. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/stream.cpp +217 -31
  67. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/types.cpp +435 -80
  68. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/types.hpp +118 -7
  69. sharedbox-0.8.0/src/sharedbox/_native.pyi +1419 -0
  70. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_refs.py +6 -1
  71. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_stream.py +501 -88
  72. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_types.py +488 -66
  73. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_version.py +3 -3
  74. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/ops.py +283 -4
  75. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/stream.py +2 -2
  76. {sharedbox-0.6.0 → sharedbox-0.8.0}/stubtest-allowlist.txt +17 -0
  77. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/CMakeLists.txt +1 -1
  78. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/consumer/consumer.c +4 -0
  79. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_c_smoke.c +25 -0
  80. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_c_smoke_box.cpp +5 -5
  81. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_layout3.cpp +72 -5
  82. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_mapping.cpp +8 -8
  83. sharedbox-0.8.0/tests/cpp/test_metadata.cpp +1022 -0
  84. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_stream.cpp +224 -2
  85. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_stream_layout.cpp +54 -1
  86. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_types.cpp +162 -2
  87. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_values.cpp +30 -0
  88. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/crossproc.py +31 -1
  89. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/forged_open.py +10 -1
  90. sharedbox-0.8.0/tests/signatures.py +12 -0
  91. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/streamproc.py +77 -3
  92. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_read_into.py +2 -2
  93. sharedbox-0.8.0/tests/test_bounded_dict.py +728 -0
  94. sharedbox-0.8.0/tests/test_bounded_list.py +944 -0
  95. sharedbox-0.8.0/tests/test_bounded_set.py +873 -0
  96. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_box.py +2 -2
  97. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_capsule.py +29 -0
  98. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_doc_examples.py +5 -2
  99. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_events_bytes.py +1 -1
  100. sharedbox-0.8.0/tests/test_exit.py +257 -0
  101. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_fields.py +57 -8
  102. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_layout.py +36 -0
  103. sharedbox-0.8.0/tests/test_metadata.py +509 -0
  104. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_segment.py +5 -4
  105. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_stream.py +6 -14
  106. sharedbox-0.8.0/tests/test_properties_bounded.py +286 -0
  107. sharedbox-0.8.0/tests/test_properties_bounded_dict.py +250 -0
  108. sharedbox-0.8.0/tests/test_properties_bounded_set.py +249 -0
  109. sharedbox-0.8.0/tests/test_properties_numpy.py +99 -0
  110. sharedbox-0.8.0/tests/test_properties_stream.py +353 -0
  111. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_read_into.py +6 -6
  112. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_refs.py +2 -1
  113. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_stream.py +438 -12
  114. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_stream_async.py +71 -1
  115. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_stream_events.py +32 -1
  116. sharedbox-0.8.0/tests/test_stream_metadata.py +478 -0
  117. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_stream_processes.py +40 -0
  118. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_stream_writing.py +1 -1
  119. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_arrays.py +86 -36
  120. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_arrays_bfloat16.py +1 -1
  121. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_arrays_torch.py +1 -1
  122. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_collections.py +43 -0
  123. sharedbox-0.8.0/tests/test_types_numpy.py +456 -0
  124. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_records.py +102 -6
  125. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_records_attrs.py +18 -0
  126. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_unions.py +14 -0
  127. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_value_reuse.py +1 -1
  128. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_writing.py +4 -4
  129. sharedbox-0.8.0/tests/type_checks/bounded_types.py +36 -0
  130. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/type_checks/box_types.py +1 -1
  131. sharedbox-0.8.0/tests/type_checks/metadata_types.py +132 -0
  132. {sharedbox-0.6.0 → sharedbox-0.8.0}/uv.lock +68 -1
  133. {sharedbox-0.6.0 → sharedbox-0.8.0}/zensical.toml +5 -0
  134. sharedbox-0.6.0/benchmarks/test_bench_box.py +0 -98
  135. sharedbox-0.6.0/src/sharedbox/_native.pyi +0 -535
  136. sharedbox-0.6.0/tests/test_exit.py +0 -53
  137. sharedbox-0.6.0/tests/test_properties_stream.py +0 -121
  138. {sharedbox-0.6.0 → sharedbox-0.8.0}/.clang-format +0 -0
  139. {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/dependabot.yml +0 -0
  140. {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/pull_request_template.md +0 -0
  141. {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/check-changelog.yaml +0 -0
  142. {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/check-docs.yaml +0 -0
  143. {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/codspeed.yml +0 -0
  144. {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/contention.yaml +0 -0
  145. {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/prepare-release.yaml +0 -0
  146. {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/publish-docs.yaml +0 -0
  147. {sharedbox-0.6.0 → sharedbox-0.8.0}/.github/workflows/streams.yaml +0 -0
  148. {sharedbox-0.6.0 → sharedbox-0.8.0}/.gitignore +0 -0
  149. {sharedbox-0.6.0 → sharedbox-0.8.0}/LICENSE +0 -0
  150. {sharedbox-0.6.0 → sharedbox-0.8.0}/README.md +0 -0
  151. {sharedbox-0.6.0 → sharedbox-0.8.0}/benchmarks/test_bench_stream.py +0 -0
  152. {sharedbox-0.6.0 → sharedbox-0.8.0}/changelog.d/.gitkeep +0 -0
  153. {sharedbox-0.6.0 → sharedbox-0.8.0}/cmake/sharedbox-config.cmake +0 -0
  154. {sharedbox-0.6.0 → sharedbox-0.8.0}/cmake/sharedbox-require-cxx.cmake +0 -0
  155. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/assets/benchmarks/ops.json +0 -0
  156. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/assets/benchmarks/roundtrip.json +0 -0
  157. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/assets/benchmarks/stream-matrix.json +0 -0
  158. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/assets/benchmarks/stream-throughput.json +0 -0
  159. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/diagrams/style.d2 +0 -0
  160. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/change_several_fields_at_once.py +0 -0
  161. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/clean_up_segments.py +0 -0
  162. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/follow_a_whole_reference_graph.py +0 -0
  163. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/name_a_box.py +0 -0
  164. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/send_a_box_to_another_process.py +0 -0
  165. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/set_defaults_and_check_values.py +0 -0
  166. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/examples/store_records.py +0 -0
  167. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/checking-a-process-is-alive.md +0 -0
  168. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/closing-and-lifetime.md +0 -0
  169. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/how-the-module-is-built.md +0 -0
  170. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/index.md +0 -0
  171. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/limits.md +0 -0
  172. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/performance.md +0 -0
  173. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/reading-and-writing.md +0 -0
  174. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/references.md +0 -0
  175. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/waiting-for-changes.md +0 -0
  176. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/explanation/when-to-use-sharedbox.md +0 -0
  177. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/accept-a-box-in-cpp.md +0 -0
  178. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/ai-contribution-policy.md +0 -0
  179. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/build-docs.md +0 -0
  180. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/change-several-fields-at-once.md +0 -0
  181. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/clean-up-segments.md +0 -0
  182. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/contribute.md +0 -0
  183. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/follow-a-whole-reference-graph.md +0 -0
  184. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/install-sharedbox.md +0 -0
  185. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/make-a-release.md +0 -0
  186. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/name-a-box.md +0 -0
  187. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/open-a-box-from-a-program.md +0 -0
  188. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/run-benchmarks.md +0 -0
  189. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/run-commit-checks.md +0 -0
  190. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/run-tests.md +0 -0
  191. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/send-a-box-to-another-process.md +0 -0
  192. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/set-defaults-and-check-values.md +0 -0
  193. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/set-up-development.md +0 -0
  194. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/store-records.md +0 -0
  195. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/how-to/write-docs.md +0 -0
  196. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/index.md +0 -0
  197. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/javascripts/charts.js +0 -0
  198. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/index.md +0 -0
  199. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/library-authors.md +0 -0
  200. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/references.md +0 -0
  201. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/api/streams.md +0 -0
  202. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/changelog.md +0 -0
  203. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/cpp-and-c-api.md +0 -0
  204. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/reference/index.md +0 -0
  205. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/tutorials/index.md +0 -0
  206. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/tutorials/mailbox.py +0 -0
  207. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/tutorials/react-to-changes.md +0 -0
  208. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/tutorials/refer-to-another-box.md +0 -0
  209. {sharedbox-0.6.0 → sharedbox-0.8.0}/docs/tutorials/share-a-record.md +0 -0
  210. {sharedbox-0.6.0 → sharedbox-0.8.0}/include/sharedbox/sharedbox.hpp +0 -0
  211. {sharedbox-0.6.0 → sharedbox-0.8.0}/prek.toml +0 -0
  212. {sharedbox-0.6.0 → sharedbox-0.8.0}/scripts/check_xrefs.py +0 -0
  213. {sharedbox-0.6.0 → sharedbox-0.8.0}/scripts/release_notes.py +0 -0
  214. {sharedbox-0.6.0 → sharedbox-0.8.0}/scripts/stream_compare.py +0 -0
  215. {sharedbox-0.6.0 → sharedbox-0.8.0}/scripts/vscode_setup.py +0 -0
  216. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_follow.py +0 -0
  217. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/_native/stream.hpp +0 -0
  218. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/__init__.py +0 -0
  219. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/__main__.py +0 -0
  220. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/_app.py +0 -0
  221. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/cli.py +0 -0
  222. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/contention.py +0 -0
  223. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/plot.py +0 -0
  224. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/roundtrip.py +0 -0
  225. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/size.py +0 -0
  226. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/benchmarks/size_diff.py +0 -0
  227. {sharedbox-0.6.0 → sharedbox-0.8.0}/src/sharedbox/py.typed +0 -0
  228. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/conftest.py +0 -0
  229. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/bench_stream.cpp +0 -0
  230. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/compile_fail.cpp +0 -0
  231. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/consumer/CMakeLists.txt +0 -0
  232. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/table_builder.hpp +0 -0
  233. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_atomics.cpp +0 -0
  234. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_core_alone.cpp +0 -0
  235. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_fork.cpp +0 -0
  236. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_lock.cpp +0 -0
  237. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_result.cpp +0 -0
  238. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_slots.cpp +0 -0
  239. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_small_shm.cpp +0 -0
  240. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_wait.cpp +0 -0
  241. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_windows_h.cpp +0 -0
  242. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/test_write_in_place.cpp +0 -0
  243. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/cpp/unique.hpp +0 -0
  244. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/forged_types.py +0 -0
  245. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/os_names.py +0 -0
  246. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/refs_future.py +0 -0
  247. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/stress_helpers.py +0 -0
  248. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_contention.py +0 -0
  249. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_crashes.py +0 -0
  250. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_follow.py +0 -0
  251. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_lock_timeout.py +0 -0
  252. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_memory.py +0 -0
  253. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_waiters.py +0 -0
  254. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/stress/test_stress_watchers.py +0 -0
  255. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_benchbox_all.py +0 -0
  256. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_benchbox_contention.py +0 -0
  257. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_benchbox_plot.py +0 -0
  258. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_benchbox_roundtrip.py +0 -0
  259. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_benchbox_stream.py +0 -0
  260. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_box_sync_async.py +0 -0
  261. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_doc_tutorials.py +0 -0
  262. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_events_async.py +0 -0
  263. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_events_future.py +0 -0
  264. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_events_signals.py +0 -0
  265. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_events_sync.py +0 -0
  266. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_follow.py +0 -0
  267. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_fork.py +0 -0
  268. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_codec.py +0 -0
  269. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_liveness.py +0 -0
  270. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_types.py +0 -0
  271. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_wait.py +0 -0
  272. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_native_waiters.py +0 -0
  273. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_properties_codec.py +0 -0
  274. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_properties_forged.py +0 -0
  275. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_properties_layout.py +0 -0
  276. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_properties_stateful.py +0 -0
  277. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_properties_types.py +0 -0
  278. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_refs_lazy.py +0 -0
  279. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_stream_fork.py +0 -0
  280. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_choices.py +0 -0
  281. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_records_msgspec.py +0 -0
  282. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/test_types_scalars.py +0 -0
  283. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/type_checks/array_types.py +0 -0
  284. {sharedbox-0.6.0 → sharedbox-0.8.0}/tests/type_checks/events_types.py +0 -0
  285. {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.2
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/test_properties_codec.py tests/test_properties_layout.py tests/test_properties_forged.py tests/test_properties_stateful.py -q -p no:cacheprovider --hypothesis-profile=thorough
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.event_name == 'release' && github.event.release.tag_name || '' }}
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 "*$rows/SharedBox" --json "../results/$side-$round-$rows.json")
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.0 and its protocols: create, publish, open, lock, read, write, capsule handle
18
- | |-- stream.hpp stream layout 1.0: create, open, the sender, readers, the gate, dead ends
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 12, the datetime C API on full-API builds
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.0, names and protocols
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.0, from offset 0:
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` 0, `schema_hash`, `create_id`, `creator_start`,
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) and `types_size`, followed by reserved zero bytes. The header is
149
- 128 bytes.
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) and 64 to 74 (described types).
159
- - The record, at a multiple of 64. The mapping size is rounded up to 4 KiB.
160
- `record + record_size <= 2**32 - 4096`.
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, and the description table. Every offset is
177
- 64-bit. The full specification is in `docs/reference/segment-layout.md`.
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.6.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"