sharedbox 0.3.1__tar.gz → 0.4.1__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 (206) hide show
  1. sharedbox-0.4.1/.github/dependabot.yml +23 -0
  2. {sharedbox-0.3.1 → sharedbox-0.4.1}/.github/workflows/check-docs.yaml +2 -2
  3. {sharedbox-0.3.1 → sharedbox-0.4.1}/.github/workflows/ci.yaml +16 -16
  4. {sharedbox-0.3.1 → sharedbox-0.4.1}/.github/workflows/codspeed.yml +1 -1
  5. {sharedbox-0.3.1 → sharedbox-0.4.1}/.github/workflows/publish-docs.yaml +2 -2
  6. {sharedbox-0.3.1 → sharedbox-0.4.1}/CHANGELOG.md +82 -0
  7. {sharedbox-0.3.1 → sharedbox-0.4.1}/CLAUDE.md +42 -30
  8. {sharedbox-0.3.1 → sharedbox-0.4.1}/CMakeLists.txt +3 -1
  9. {sharedbox-0.3.1 → sharedbox-0.4.1}/PKG-INFO +3 -1
  10. sharedbox-0.4.1/docs/assets/benchmarks/ops-dark.svg +1209 -0
  11. sharedbox-0.4.1/docs/assets/benchmarks/ops-light.svg +1209 -0
  12. sharedbox-0.4.1/docs/assets/benchmarks/roundtrip-dark.svg +334 -0
  13. sharedbox-0.4.1/docs/assets/benchmarks/roundtrip-light.svg +334 -0
  14. sharedbox-0.4.1/docs/examples/store_arrays.py +40 -0
  15. sharedbox-0.4.1/docs/examples/store_collections.py +39 -0
  16. sharedbox-0.4.1/docs/examples/store_records.py +52 -0
  17. sharedbox-0.4.1/docs/explanation/field-types.md +91 -0
  18. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/explanation/glossary.md +12 -4
  19. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/explanation/how-a-box-is-stored.md +5 -6
  20. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/explanation/how-the-module-is-built.md +3 -2
  21. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/explanation/index.md +4 -0
  22. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/explanation/limits.md +14 -7
  23. sharedbox-0.4.1/docs/explanation/performance.md +78 -0
  24. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/accept-a-box-in-cpp.md +1 -1
  25. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/clean-up-segments.md +3 -3
  26. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/index.md +6 -0
  27. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/make-a-release.md +1 -1
  28. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/run-benchmarks.md +13 -0
  29. sharedbox-0.4.1/docs/how-to/store-arrays.md +58 -0
  30. sharedbox-0.4.1/docs/how-to/store-collections.md +59 -0
  31. sharedbox-0.4.1/docs/how-to/store-records.md +68 -0
  32. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/index.md +0 -1
  33. sharedbox-0.4.1/docs/reference/api/arrays.md +28 -0
  34. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/reference/api/box.md +1 -1
  35. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/reference/api/index.md +1 -0
  36. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/reference/cpp-and-c-api.md +2 -2
  37. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/reference/segment-layout.md +255 -48
  38. {sharedbox-0.3.1 → sharedbox-0.4.1}/include/sharedbox/sharedbox.hpp +1344 -108
  39. sharedbox-0.4.1/include/sharedbox/sharedbox_c.cpp +321 -0
  40. sharedbox-0.4.1/include/sharedbox/sharedbox_c.h +131 -0
  41. {sharedbox-0.3.1 → sharedbox-0.4.1}/includes/abbreviations.md +3 -1
  42. {sharedbox-0.3.1 → sharedbox-0.4.1}/pyproject.toml +9 -1
  43. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/__init__.py +5 -0
  44. sharedbox-0.4.1/src/sharedbox/_arrays.py +163 -0
  45. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/_box.py +94 -32
  46. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/_events.py +71 -13
  47. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/_layout.py +129 -112
  48. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/_native/codec.cpp +43 -17
  49. sharedbox-0.4.1/src/sharedbox/_native/codec.hpp +87 -0
  50. sharedbox-0.4.1/src/sharedbox/_native/module.cpp +947 -0
  51. sharedbox-0.4.1/src/sharedbox/_native/scalars.cpp +490 -0
  52. sharedbox-0.4.1/src/sharedbox/_native/scalars.hpp +31 -0
  53. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/_native/segment.cpp +105 -57
  54. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/_native/segment.hpp +29 -16
  55. sharedbox-0.4.1/src/sharedbox/_native/types.cpp +833 -0
  56. sharedbox-0.4.1/src/sharedbox/_native/types.hpp +110 -0
  57. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/_native.pyi +99 -9
  58. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/_refs.py +4 -2
  59. sharedbox-0.4.1/src/sharedbox/_types.py +985 -0
  60. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/_version.py +3 -3
  61. sharedbox-0.4.1/src/sharedbox/benchmarks/__init__.py +5 -0
  62. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/benchmarks/_app.py +18 -0
  63. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/benchmarks/ops.py +49 -4
  64. sharedbox-0.4.1/src/sharedbox/benchmarks/plot.py +161 -0
  65. {sharedbox-0.3.1 → sharedbox-0.4.1}/stubtest-allowlist.txt +2 -0
  66. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/conftest.py +32 -0
  67. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/CMakeLists.txt +1 -1
  68. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/consumer/consumer.c +14 -0
  69. sharedbox-0.4.1/tests/cpp/table_builder.hpp +49 -0
  70. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/test_c_smoke.c +30 -0
  71. sharedbox-0.4.1/tests/cpp/test_c_smoke_box.cpp +39 -0
  72. sharedbox-0.4.1/tests/cpp/test_layout2.cpp +126 -0
  73. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/test_mapping.cpp +7 -6
  74. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/test_result.cpp +1 -1
  75. sharedbox-0.4.1/tests/cpp/test_types.cpp +293 -0
  76. sharedbox-0.4.1/tests/cpp/test_values.cpp +237 -0
  77. sharedbox-0.4.1/tests/crossproc.py +36 -0
  78. sharedbox-0.4.1/tests/forged_types.py +100 -0
  79. sharedbox-0.4.1/tests/test_benchbox_plot.py +63 -0
  80. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_box.py +273 -1
  81. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_capsule.py +66 -5
  82. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_doc_examples.py +3 -0
  83. sharedbox-0.4.1/tests/test_events_bytes.py +56 -0
  84. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_events_signals.py +29 -0
  85. sharedbox-0.4.1/tests/test_exit.py +53 -0
  86. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_layout.py +9 -6
  87. sharedbox-0.4.1/tests/test_layout_v1.py +50 -0
  88. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_native_segment.py +10 -9
  89. sharedbox-0.4.1/tests/test_native_types.py +284 -0
  90. sharedbox-0.4.1/tests/test_properties_forged.py +24 -0
  91. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_properties_layout.py +3 -2
  92. sharedbox-0.4.1/tests/test_properties_types.py +136 -0
  93. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_refs.py +47 -0
  94. sharedbox-0.4.1/tests/test_types_arrays.py +212 -0
  95. sharedbox-0.4.1/tests/test_types_arrays_bfloat16.py +34 -0
  96. sharedbox-0.4.1/tests/test_types_arrays_torch.py +18 -0
  97. sharedbox-0.4.1/tests/test_types_choices.py +158 -0
  98. sharedbox-0.4.1/tests/test_types_collections.py +183 -0
  99. sharedbox-0.4.1/tests/test_types_records.py +311 -0
  100. sharedbox-0.4.1/tests/test_types_records_attrs.py +21 -0
  101. sharedbox-0.4.1/tests/test_types_records_msgspec.py +35 -0
  102. sharedbox-0.4.1/tests/test_types_scalars.py +142 -0
  103. sharedbox-0.4.1/tests/test_types_unions.py +170 -0
  104. {sharedbox-0.3.1 → sharedbox-0.4.1}/uv.lock +861 -1
  105. {sharedbox-0.3.1 → sharedbox-0.4.1}/zensical.toml +6 -0
  106. sharedbox-0.3.1/include/sharedbox/sharedbox_c.cpp +0 -87
  107. sharedbox-0.3.1/include/sharedbox/sharedbox_c.h +0 -83
  108. sharedbox-0.3.1/src/sharedbox/_native/codec.hpp +0 -18
  109. sharedbox-0.3.1/src/sharedbox/_native/module.cpp +0 -372
  110. sharedbox-0.3.1/src/sharedbox/benchmarks/__init__.py +0 -3
  111. sharedbox-0.3.1/tests/cpp/test_c_smoke_box.cpp +0 -26
  112. sharedbox-0.3.1/tests/test_properties_forged.py +0 -19
  113. {sharedbox-0.3.1 → sharedbox-0.4.1}/.clang-format +0 -0
  114. {sharedbox-0.3.1 → sharedbox-0.4.1}/.claude/settings.json +0 -0
  115. {sharedbox-0.3.1 → sharedbox-0.4.1}/.gitignore +0 -0
  116. {sharedbox-0.3.1 → sharedbox-0.4.1}/LICENSE +0 -0
  117. {sharedbox-0.3.1 → sharedbox-0.4.1}/README.md +0 -0
  118. {sharedbox-0.3.1 → sharedbox-0.4.1}/benchmarks/test_bench_box.py +0 -0
  119. {sharedbox-0.3.1 → sharedbox-0.4.1}/cmake/sharedbox-config.cmake +0 -0
  120. {sharedbox-0.3.1 → sharedbox-0.4.1}/cmake/sharedbox-require-cxx.cmake +0 -0
  121. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/examples/change_several_fields_at_once.py +0 -0
  122. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/examples/clean_up_segments.py +0 -0
  123. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/examples/follow_a_whole_reference_graph.py +0 -0
  124. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/examples/name_a_box.py +0 -0
  125. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/examples/send_a_box_to_another_process.py +0 -0
  126. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/examples/set_defaults_and_check_values.py +0 -0
  127. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/examples/store_text_and_bytes.py +0 -0
  128. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/explanation/checking-a-process-is-alive.md +0 -0
  129. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/explanation/closing-and-lifetime.md +0 -0
  130. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/explanation/reading-and-writing.md +0 -0
  131. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/explanation/references.md +0 -0
  132. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/explanation/waiting-for-changes.md +0 -0
  133. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/explanation/when-to-use-sharedbox.md +0 -0
  134. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/accept-a-box-in-c.md +0 -0
  135. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/ai-contribution-policy.md +0 -0
  136. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/build-docs.md +0 -0
  137. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/change-several-fields-at-once.md +0 -0
  138. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/commits-and-prs.md +0 -0
  139. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/contribute.md +0 -0
  140. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/follow-a-whole-reference-graph.md +0 -0
  141. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/install-sharedbox.md +0 -0
  142. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/name-a-box.md +0 -0
  143. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/open-a-box-from-a-program.md +0 -0
  144. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/run-commit-checks.md +0 -0
  145. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/run-tests.md +0 -0
  146. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/send-a-box-to-another-process.md +0 -0
  147. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/set-defaults-and-check-values.md +0 -0
  148. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/set-up-development.md +0 -0
  149. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/store-text-and-bytes.md +0 -0
  150. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/how-to/write-docs.md +0 -0
  151. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/reference/api/errors.md +0 -0
  152. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/reference/api/events.md +0 -0
  153. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/reference/api/library-authors.md +0 -0
  154. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/reference/api/references.md +0 -0
  155. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/reference/changelog.md +0 -0
  156. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/reference/index.md +0 -0
  157. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/tutorials/index.md +0 -0
  158. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/tutorials/motor.py +0 -0
  159. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/tutorials/react-to-changes.md +0 -0
  160. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/tutorials/refer-to-another-box.md +0 -0
  161. {sharedbox-0.3.1 → sharedbox-0.4.1}/docs/tutorials/share-a-record.md +0 -0
  162. {sharedbox-0.3.1 → sharedbox-0.4.1}/prek.toml +0 -0
  163. {sharedbox-0.3.1 → sharedbox-0.4.1}/scripts/check_xrefs.py +0 -0
  164. {sharedbox-0.3.1 → sharedbox-0.4.1}/scripts/vscode_setup.py +0 -0
  165. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/_follow.py +0 -0
  166. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/benchmarks/__main__.py +0 -0
  167. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/benchmarks/cli.py +0 -0
  168. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/benchmarks/roundtrip.py +0 -0
  169. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/benchmarks/size.py +0 -0
  170. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/benchmarks/size_diff.py +0 -0
  171. {sharedbox-0.3.1 → sharedbox-0.4.1}/src/sharedbox/py.typed +0 -0
  172. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/compile_fail.cpp +0 -0
  173. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/consumer/CMakeLists.txt +0 -0
  174. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/test_atomics.cpp +0 -0
  175. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/test_fork.cpp +0 -0
  176. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/test_lock.cpp +0 -0
  177. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/test_slots.cpp +0 -0
  178. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/test_small_shm.cpp +0 -0
  179. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/test_wait.cpp +0 -0
  180. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/test_windows_h.cpp +0 -0
  181. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/cpp/unique.hpp +0 -0
  182. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/forged_open.py +0 -0
  183. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/refs_future.py +0 -0
  184. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/stress/stress_helpers.py +0 -0
  185. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/stress/test_stress_contention.py +0 -0
  186. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/stress/test_stress_crashes.py +0 -0
  187. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/stress/test_stress_follow.py +0 -0
  188. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/stress/test_stress_lock_timeout.py +0 -0
  189. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/stress/test_stress_memory.py +0 -0
  190. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/stress/test_stress_waiters.py +0 -0
  191. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/stress/test_stress_watchers.py +0 -0
  192. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_doc_tutorials.py +0 -0
  193. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_events_async.py +0 -0
  194. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_events_sync.py +0 -0
  195. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_fields.py +0 -0
  196. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_follow.py +0 -0
  197. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_fork.py +0 -0
  198. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_native_codec.py +0 -0
  199. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_native_liveness.py +0 -0
  200. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_native_wait.py +0 -0
  201. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_native_waiters.py +0 -0
  202. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_properties_codec.py +0 -0
  203. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_properties_stateful.py +0 -0
  204. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/test_refs_lazy.py +0 -0
  205. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/type_checks/box_types.py +0 -0
  206. {sharedbox-0.3.1 → sharedbox-0.4.1}/tests/type_checks/events_types.py +0 -0
@@ -0,0 +1,23 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: github-actions
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ commit-message:
8
+ prefix: ci
9
+ groups:
10
+ actions:
11
+ patterns:
12
+ - "*"
13
+ - package-ecosystem: uv
14
+ directory: /
15
+ schedule:
16
+ interval: weekly
17
+ commit-message:
18
+ prefix: build
19
+ include: scope
20
+ groups:
21
+ python:
22
+ patterns:
23
+ - "*"
@@ -8,7 +8,7 @@ jobs:
8
8
  name: Build and check cross-references
9
9
  runs-on: ubuntu-latest
10
10
  steps:
11
- - uses: actions/checkout@v5
11
+ - uses: actions/checkout@v7
12
12
 
13
13
  - name: Install uv
14
14
  uses: astral-sh/setup-uv@v7
@@ -23,7 +23,7 @@ jobs:
23
23
  # the publish job deploys this artifact rather than building again,
24
24
  # so what reaches Pages is what was checked
25
25
  - name: Store the built site
26
- uses: actions/upload-artifact@v4
26
+ uses: actions/upload-artifact@v7
27
27
  with:
28
28
  name: docs-site
29
29
  path: site/
@@ -14,7 +14,7 @@ jobs:
14
14
  name: Lint
15
15
  runs-on: ubuntu-latest
16
16
  steps:
17
- - uses: actions/checkout@v5
17
+ - uses: actions/checkout@v7
18
18
 
19
19
  # local hooks in prek.toml call `uv run --locked --only-group lint ...`
20
20
  - uses: astral-sh/setup-uv@v7
@@ -62,7 +62,7 @@ jobs:
62
62
  ASAN_OPTIONS: detect_leaks=1
63
63
  UBSAN_OPTIONS: print_stacktrace=1
64
64
  steps:
65
- - uses: actions/checkout@v5
65
+ - uses: actions/checkout@v7
66
66
  with:
67
67
  fetch-depth: 0
68
68
 
@@ -108,24 +108,24 @@ jobs:
108
108
  - { os: ubuntu-latest, python: cp314t, platform_id: musllinux_x86_64 }
109
109
 
110
110
  steps:
111
- - uses: actions/checkout@v5
111
+ - uses: actions/checkout@v7
112
112
  with:
113
113
  fetch-depth: 0
114
114
  ref: ${{ github.event_name == 'release' && github.event.release.tag_name || '' }}
115
115
 
116
116
  - name: Build wheels
117
- uses: pypa/cibuildwheel@v3.2.0
117
+ uses: pypa/cibuildwheel@v4.2.1
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
121
+ CIBW_TEST_REQUIRES: pytest hypothesis numpy
122
122
  CIBW_TEST_COMMAND: pytest {project}/tests
123
123
  with:
124
124
  package-dir: .
125
125
  output-dir: wheelhouse
126
126
 
127
127
  - name: Upload wheel artifacts
128
- uses: actions/upload-artifact@v4
128
+ uses: actions/upload-artifact@v7
129
129
  with:
130
130
  name: cibw-wheels-${{ matrix.python }}-${{ matrix.platform_id }}
131
131
  path: ./wheelhouse/*.whl
@@ -139,7 +139,7 @@ jobs:
139
139
  python src/sharedbox/benchmarks/size.py wheelhouse/*.whl --json wheelhouse/sizes.json --markdown >> "$GITHUB_STEP_SUMMARY"
140
140
 
141
141
  - name: Upload size artifact
142
- uses: actions/upload-artifact@v4
142
+ uses: actions/upload-artifact@v7
143
143
  with:
144
144
  name: wheel-sizes-${{ matrix.python }}-${{ matrix.platform_id }}
145
145
  path: wheelhouse/sizes.json
@@ -153,10 +153,10 @@ jobs:
153
153
  actions: read
154
154
  continue-on-error: true
155
155
  steps:
156
- - uses: actions/checkout@v5
156
+ - uses: actions/checkout@v7
157
157
 
158
158
  - name: Download this run's size artifacts
159
- uses: actions/download-artifact@v5
159
+ uses: actions/download-artifact@v8
160
160
  with:
161
161
  pattern: wheel-sizes-*
162
162
  path: sizes/this
@@ -173,7 +173,7 @@ jobs:
173
173
  - name: Download the baseline's size artifacts
174
174
  if: steps.baseline.outputs.run_id != ''
175
175
  continue-on-error: true
176
- uses: actions/download-artifact@v5
176
+ uses: actions/download-artifact@v8
177
177
  with:
178
178
  pattern: wheel-sizes-*
179
179
  path: sizes/main
@@ -199,11 +199,11 @@ jobs:
199
199
  - { os: ubuntu-latest, wheel: cibw-wheels-cp312-manylinux_x86_64 }
200
200
  - { os: windows-latest, wheel: cibw-wheels-cp312-win_amd64 }
201
201
  steps:
202
- - uses: actions/checkout@v5
202
+ - uses: actions/checkout@v7
203
203
 
204
204
  - uses: astral-sh/setup-uv@v7
205
205
 
206
- - uses: actions/download-artifact@v5
206
+ - uses: actions/download-artifact@v8
207
207
  with:
208
208
  name: ${{ matrix.wheel }}
209
209
  path: wheelhouse
@@ -218,7 +218,7 @@ jobs:
218
218
  "$python" -m pytest -m stress -q -p no:cacheprovider
219
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
220
220
 
221
- - uses: actions/upload-artifact@v4
221
+ - uses: actions/upload-artifact@v7
222
222
  if: always()
223
223
  with:
224
224
  name: stress-${{ matrix.os }}
@@ -243,7 +243,7 @@ jobs:
243
243
  *) [ "$PRERELEASE" = "false" ] || { echo "::error::$TAG must not be marked pre-release"; exit 1; } ;;
244
244
  esac
245
245
 
246
- - uses: actions/checkout@v5
246
+ - uses: actions/checkout@v7
247
247
  with:
248
248
  fetch-depth: 0
249
249
  ref: ${{ github.event_name == 'release' && github.event.release.tag_name || '' }}
@@ -256,7 +256,7 @@ jobs:
256
256
  TAG: ${{ github.event.release.tag_name }}
257
257
  run: test -f "dist/sharedbox-${TAG#v}.tar.gz"
258
258
 
259
- - uses: actions/upload-artifact@v4
259
+ - uses: actions/upload-artifact@v7
260
260
  with:
261
261
  name: cibw-sdist
262
262
  path: dist/*.tar.gz
@@ -272,7 +272,7 @@ jobs:
272
272
  id-token: write
273
273
  if: github.event_name == 'release' && github.event.action == 'published'
274
274
  steps:
275
- - uses: actions/download-artifact@v5
275
+ - uses: actions/download-artifact@v8
276
276
  with:
277
277
  # unpacks all CIBW artifacts into dist/
278
278
  pattern: cibw-*
@@ -16,7 +16,7 @@ jobs:
16
16
  name: Run benchmarks
17
17
  runs-on: ubuntu-latest
18
18
  steps:
19
- - uses: actions/checkout@v5
19
+ - uses: actions/checkout@v7
20
20
  with:
21
21
  fetch-depth: 0
22
22
 
@@ -10,10 +10,10 @@ jobs:
10
10
  permissions:
11
11
  contents: write
12
12
  steps:
13
- - uses: actions/checkout@v5
13
+ - uses: actions/checkout@v7
14
14
 
15
15
  - name: Download the built site
16
- uses: actions/download-artifact@v5
16
+ uses: actions/download-artifact@v8
17
17
  with:
18
18
  name: docs-site
19
19
  path: site/
@@ -7,6 +7,86 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  Dates are marked as `DD-MM-YYYY`
9
9
 
10
+ ## [Unreleased]
11
+
12
+ ### Changed
13
+
14
+ - `SharedBox.update`: takes about 7 to 9 ns less per call on Windows.
15
+
16
+ ### Fixed
17
+
18
+ - `SharedBox.events`, `SharedBox.watch` and `BoxEvents.follow`: a process
19
+ that exits while watcher threads still run no longer aborts with
20
+ `terminate called without an active exception` on Linux with CPython
21
+ 3.11 to 3.13. At exit, sharedbox stops every watcher thread and waits
22
+ up to 2 seconds in all for them to end, including any callback they are
23
+ running.
24
+
25
+ ## [0.4.0] - 05-10-2026
26
+
27
+ ### Added
28
+
29
+ - `benchbox plot`: draws the results of `benchbox all` as SVG charts, in a
30
+ light and a dark variant. The `benchmarks` extra now includes
31
+ matplotlib.
32
+ - `SharedBox`: fields of type `complex`, `datetime.date`, `datetime.time`,
33
+ `datetime.datetime`, `datetime.timedelta`, `uuid.UUID` and
34
+ `Annotated[decimal.Decimal, Capacity(n)]`.
35
+ - `SharedBox`: `enum.Enum`, `enum.Flag` and `typing.Literal` fields.
36
+ - `SharedBox`: `X | None` and union fields.
37
+ - `SharedBox`: record fields: dataclasses, `NamedTuple`, fixed-length
38
+ tuples, `TypedDict`, attrs classes and `msgspec.Struct`.
39
+ - `SharedBox`: `list`, `tuple[T, ...]`, `set`, `frozenset`, `dict` and
40
+ `bytearray` fields and their `collections.abc` forms, with a `Capacity`
41
+ in elements.
42
+ - `Shape`, `DType`, `SupportsDLPack`, `register_array_type`: array fields
43
+ through DLPack.
44
+ - `sharedbox.hpp`: `type_view`, `handle::field_type`,
45
+ `handle::types_table`, `handle::major_version`, `oldest_layout_major`,
46
+ `time_value`, `datetime_value`, `timedelta_value`, the kind codes
47
+ `kind_complex` to `kind_decimal` and `kind_enum` to `kind_array`,
48
+ `max_type_depth`, `max_types_size`, `max_mapping_size`,
49
+ `first_described_kind`, `max_date_ordinal`, `unix_epoch_ordinal`,
50
+ `micros_per_day`, `max_offset_minutes`, `literal_none` to
51
+ `literal_enum`, `type_head`, `dl_dtype`, `literal_value`,
52
+ `encode_*` and `decode_*` functions for complex, date, time, datetime,
53
+ timedelta, uuid, flag and position values, `decode_bool`,
54
+ `decode_present`, `decode_tag`, `decode_length`, `handle::read_used`,
55
+ `handle::read_large`, `handle::read_record_large` and
56
+ `handle::write_large`.
57
+ - `sharedbox_c.h`: `sbx_field_desc`, the structs `sbx_time`,
58
+ `sbx_datetime` and `sbx_timedelta`, and typed reads and writes of
59
+ complex, date, time, datetime, timedelta, UUID, enum and literal
60
+ positions, flag bits and optional presence.
61
+ - `benchbox ops`: rows for datetime, record, list and array fields.
62
+
63
+ ```python
64
+ class Frame(SharedBox):
65
+ taken: datetime.datetime
66
+ image: Annotated[np.ndarray, Shape(480, 640), DType("uint8")]
67
+ tags: Annotated[list[Annotated[str, Capacity(16)]], Capacity(8)] = field(default_factory=list)
68
+ ```
69
+
70
+ ### Changed
71
+
72
+ - Segments use layout 2.0. Releases 0.3.0 and 0.3.1 cannot open a box made
73
+ by this version; this version opens boxes made by them.
74
+ - `SharedBox.events` and `SharedBox.watch()`: a field counts as changed
75
+ when its stored bytes change. Writing `NaN` again no longer emits;
76
+ `-0.0` after `0.0` does.
77
+ - `Capacity`: also sets the most elements of a collection.
78
+ - `sharedbox.hpp`: the inline namespace is `v2`; `handle::create` and
79
+ `handle::create_unpublished` take a description table.
80
+ - The `benchmarks` extra includes numpy.
81
+ - `SharedBox.update` and `SharedBox.snapshot`: native methods, unless a
82
+ class defines or inherits its own.
83
+
84
+ ### Fixed
85
+
86
+ - `SharedBox`: a class with more than one box base keeps the defaults and
87
+ default factories of the fields it inherits from every base, not only
88
+ the first.
89
+
10
90
  ## [0.3.1] - 01-10-2026
11
91
 
12
92
  ### Added
@@ -212,6 +292,8 @@ stage.events.nested.connect(lambda path, new, old: print(path, new))
212
292
 
213
293
  - Initial release
214
294
 
295
+ [Unreleased]: https://github.com/jacopoabramo/sharedbox/compare/v0.4.0...HEAD
296
+ [0.4.0]: https://github.com/jacopoabramo/sharedbox/compare/v0.3.1...v0.4.0
215
297
  [0.3.1]: https://github.com/jacopoabramo/sharedbox/compare/v0.3.0...v0.3.1
216
298
  [0.3.0]: https://github.com/jacopoabramo/sharedbox/compare/0.2.4...v0.3.0
217
299
  [0.2.4]: https://github.com/jacopoabramo/sharedbox/compare/0.1.0...0.2.4
@@ -13,8 +13,8 @@ the layout and the native module converts values.
13
13
  ```text
14
14
  sharedbox/
15
15
  |-- include/sharedbox/
16
- | |-- sharedbox.hpp layout 1.0 and its protocols: create, publish, open, lock, read, write, waiter slots, capsule handle
17
- | |-- sharedbox_c.h minimal C interface: sbx_open, sbx_import, sbx_read, sbx_write, sbx_schema_hash, sbx_release
16
+ | |-- sharedbox.hpp layout 2.0 (and 1.0 reading) and its protocols: create, publish, open, lock, read, write, description table, waiter slots, capsule handle
17
+ | |-- 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_*
18
18
  | `-- sharedbox_c.cpp its implementation, compiled by the consumer (CMake target sharedbox::c)
19
19
  |-- cmake/
20
20
  | |-- sharedbox-config.cmake find_package(sharedbox) from an installed wheel; the build writes
@@ -24,6 +24,8 @@ sharedbox/
24
24
  | |-- __init__.py re-exports the public API, get_include()
25
25
  | |-- _box.py SharedBox: class keywords, fields, fields(), create/attach, __post_init__, update, snapshot, unlink, __sharedbox_box__
26
26
  | |-- _layout.py Capacity, field() and Field, field offsets and kind codes, schema hash
27
+ | |-- _types.py annotation parsing into TypeSpec, the description table
28
+ | |-- _arrays.py Shape, DType, SupportsDLPack, register_array_type
27
29
  | |-- _events.py BoxEvents, FieldWatch, the watcher thread
28
30
  | |-- _follow.py BoxEvents.follow and unfollow: forwarding the events of boxes that references reach
29
31
  | |-- _refs.py reference fields: BoxRef, the class registry, BrokenReferenceError, UnknownBoxClassError
@@ -31,16 +33,25 @@ sharedbox/
31
33
  | |-- py.typed
32
34
  | |-- benchmarks/ the benchbox command (extra: benchmarks)
33
35
  | | |-- cli.py entry point; exits with an install hint without Typer
34
- | | |-- _app.py Typer commands: ops, roundtrip, size, all
36
+ | | |-- _app.py Typer commands: ops, roundtrip, size, plot, all
35
37
  | | |-- ops.py pyperf timings of single operations, against the stdlib
36
38
  | | |-- roundtrip.py cross-process round trip percentiles
39
+ | | |-- plot.py SVG charts of the ops and roundtrip results (matplotlib)
37
40
  | | |-- size.py wheel and extension size (standard library only)
38
41
  | | `-- size_diff.py wheel size table against main, for CI (standard library only)
39
42
  | `-- _native/
40
- | |-- module.cpp nanobind module: Segment, the Field descriptor and the error classes
41
- | |-- codec.{hpp,cpp} converts field values to and from their stored bytes
43
+ | |-- module.cpp nanobind module: Segment, the Field descriptor, the BoxMethod type
44
+ | | (native update and snapshot) and the error classes
45
+ | |-- codec.{hpp,cpp} converts field values to and from their stored bytes; encode_all
46
+ | | checks every value of an update before any is written,
47
+ | | with_record reads the whole record at once
48
+ | |-- types.{hpp,cpp} Types: conversions of kinds above 5, arrays
49
+ | |-- scalars.{hpp,cpp} kinds 6 to 12, the datetime C API on full-API builds
42
50
  | `-- segment.{hpp,cpp} Segment: a sharedbox::handle plus error messages and the lifetime lock
43
51
  |-- tests/ pytest; many tests spawn processes
52
+ | |-- crossproc.py helpers that run a box in another process
53
+ | |-- forged_types.py builds segments with forged description tables
54
+ | |-- test_benchbox_plot.py benchbox plot; skipped without matplotlib and pyperf
44
55
  | |-- test_capsule.py __sharedbox_box__, and the C consumer in tests/cpp/consumer/
45
56
  | |-- test_doc_examples.py runs each docs/examples/*.py script
46
57
  | |-- test_doc_tutorials.py runs docs/tutorials/motor.py and checks the output its pages show
@@ -59,7 +70,7 @@ sharedbox/
59
70
  |-- docs/ Diataxis site built by Zensical: tutorials/, how-to/, explanation/, reference/
60
71
  | |-- tutorials/motor.py the script the three tutorials build and include
61
72
  | |-- examples/ one script per how-to guide, included by the guide
62
- | `-- reference/segment-layout.md layout 1.0, names and protocols
73
+ | `-- reference/segment-layout.md layout 2.0 and 1.0, names and protocols
63
74
  |-- includes/abbreviations.md acronym tooltips appended to every page
64
75
  |-- zensical.toml site configuration and navigation
65
76
  |-- .github/workflows/ci.yaml lint, docs check, C++ tests, cibuildwheel wheels, tests, stress,
@@ -92,42 +103,43 @@ the class's identity (the `identity` class keyword, by default
92
103
  `module.qualname`, with `__mp_main__` counted as `__main__`). Creating
93
104
  always asks for a new name and raises `SegmentExistsError` if it is taken.
94
105
 
95
- Layout 1.0, from offset 0:
106
+ Layout 2.0, from offset 0:
96
107
 
97
108
  - Header, 128 bytes. Line 0, written once at creation: `magic`,
98
- `layout_major` 1, `layout_minor` 0, `field_count`, `waiter_slots`,
99
- `schema_hash`, `record_size`, `record`, `tail` (always 128), `size`, and
100
- the creator fields `create_id`, `creator_start`, `creator_pid`. Line 1,
101
- changed by writes and waits: `seq` (sequence lock; the generation is
109
+ `layout_major` 2, `layout_minor` 0, `field_count`, `waiter_slots`,
110
+ `schema_hash`, `record_size`, `record`, `tail` (always 128), `size`,
111
+ `types_size` (offset 60; 0 in layout 1.0), and the creator fields
112
+ `create_id`, `creator_start`, `creator_pid`. Line 1, changed by writes
113
+ and waits: `seq` (sequence lock; the generation is
102
114
  `seq >> 1`, there is no generation field), `writer_pid`, `wake_word`,
103
115
  `waiters`, `creator_pidns`. Both lines keep reserved zero bytes.
104
116
  - The tail: `field_count` field table entries of 8 bytes (`u32 offset`,
105
- `u32 capacity_and_kind`: low 24 bits the capacity, top 8 the kind code),
106
- one `u64` write count per field, then `waiter_slots` slots of 24 bytes
107
- (`owner_start`, `owner_pidns`, `owner_pid`, `interrupt`).
117
+ `u32 capacity_and_kind`: top 8 bits the kind code, the low 24 the
118
+ capacity or size, or for kinds 64 and up the offset of the field's
119
+ description), one `u64` write count per field, then `waiter_slots` slots
120
+ of 24 bytes (`owner_start`, `owner_pidns`, `owner_pid`, `interrupt`),
121
+ then the description table of `types_size` bytes. Kinds are 0 to 5 as
122
+ in layout 1.0, 6 to 12 (fixed-size scalars) and 64 to 74 (described
123
+ types).
108
124
  - The record, at a multiple of 64. The mapping size is rounded up to 4 KiB.
125
+ `record + record_size <= 2**32 - 4096`.
109
126
 
110
127
  `magic` is stored last on create, with release ordering, after the initial
111
- values are in the record; attach waits for it. Attach refuses another
112
- `layout_major`, checks every geometry field against the mapping size,
113
- copies the field table and uses only the copy. `static_assert`s in
114
- `sharedbox.hpp` check every `sizeof` and `offsetof`.
128
+ values are in the record; attach waits for it. Attach accepts
129
+ `layout_major` 1 and 2 and refuses another, checks every geometry field
130
+ against the mapping size, copies the field table and uses only the copy.
131
+ `static_assert`s in `sharedbox.hpp` check every `sizeof` and `offsetof`.
115
132
 
116
133
  ### Record encoding
117
134
 
118
- Fields are packed by descending alignment (`int`, `float` and `ref` first,
119
- then `str`/`bytes`, then `bool`), not declaration order, each starting at a
120
- multiple of its own alignment. The native module converts values to and
121
- from these bytes; nothing is pickled. Everything is little-endian.
135
+ Fields are packed by descending alignment, not declaration order, each
136
+ starting at a multiple of its own alignment. The native module converts
137
+ values to and from these bytes; nothing is pickled. Everything is
138
+ little-endian. `docs/reference/segment-layout.md` gives every kind and its
139
+ bytes.
122
140
 
123
- - `bool`: 1 byte, `0x00` or `0x01`.
124
- - `int`: 8 bytes, signed.
125
- - `float`: 8 bytes, IEEE 754 double.
126
- - `str`, `bytes`: `u32` length, then up to `capacity` bytes (UTF-8 for `str`).
127
- - `ref` (kind 5): 144 bytes, `u64 create_id` (0 = empty), `u64 schema_hash`,
128
- then the box name NUL-padded to 128 bytes.
129
-
130
- At most 256 fields; a capacity is 1 byte to 1 MiB.
141
+ At most 256 fields; a capacity is 1 byte to 1 MiB, and a collection's
142
+ capacity counts elements, 1 to 1048576.
131
143
 
132
144
  ### Lifecycle
133
145
 
@@ -44,7 +44,9 @@ nanobind_add_module(_native
44
44
  NB_DOMAIN sharedbox
45
45
  src/sharedbox/_native/codec.cpp
46
46
  src/sharedbox/_native/module.cpp
47
- src/sharedbox/_native/segment.cpp)
47
+ src/sharedbox/_native/scalars.cpp
48
+ src/sharedbox/_native/segment.cpp
49
+ src/sharedbox/_native/types.cpp)
48
50
  target_link_libraries(_native PRIVATE sharedbox::headers)
49
51
 
50
52
  if(WIN32)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sharedbox
3
- Version: 0.3.1
3
+ Version: 0.4.1
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
@@ -16,6 +16,8 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
16
  Requires-Python: >=3.11
17
17
  Requires-Dist: psygnal>=0.16.1
18
18
  Provides-Extra: benchmarks
19
+ Requires-Dist: matplotlib>=3.11.2; extra == "benchmarks"
20
+ Requires-Dist: numpy>=2.4.6; extra == "benchmarks"
19
21
  Requires-Dist: pyperf>=2.10.0; extra == "benchmarks"
20
22
  Requires-Dist: typer>=0.27.2; extra == "benchmarks"
21
23
  Description-Content-Type: text/markdown