blosc2 4.4.2__tar.gz → 4.4.3__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 (439) hide show
  1. blosc2-4.4.3/ANNOUNCE.rst +105 -0
  2. {blosc2-4.4.2 → blosc2-4.4.3}/CMakeLists.txt +1 -1
  3. {blosc2-4.4.2 → blosc2-4.4.3}/PKG-INFO +1 -1
  4. {blosc2-4.4.2 → blosc2-4.4.3}/RELEASE_NOTES.md +71 -0
  5. {blosc2-4.4.2 → blosc2-4.4.3}/doc/python-blosc2.rst +1 -1
  6. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/ctable.rst +2 -0
  7. {blosc2-4.4.2 → blosc2-4.4.3}/pyproject.toml +1 -1
  8. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/__init__.py +4 -0
  9. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/cli/parquet_to_blosc2.py +10 -0
  10. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/ctable.py +128 -5
  11. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/ctable_indexing.py +14 -2
  12. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/dict_store.py +7 -1
  13. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/groupby.py +26 -4
  14. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/lazyexpr.py +39 -27
  15. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/version.py +1 -1
  16. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_arrow_interop.py +40 -0
  17. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_column.py +87 -0
  18. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_ctable_computed_cols.py +34 -0
  19. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_groupby.py +25 -0
  20. blosc2-4.4.2/ANNOUNCE.rst +0 -101
  21. {blosc2-4.4.2 → blosc2-4.4.3}/.gitattributes +0 -0
  22. {blosc2-4.4.2 → blosc2-4.4.3}/.gitignore +0 -0
  23. {blosc2-4.4.2 → blosc2-4.4.3}/.guix/modules/python-blosc2-package.scm +0 -0
  24. {blosc2-4.4.2 → blosc2-4.4.3}/.guix-channel +0 -0
  25. {blosc2-4.4.2 → blosc2-4.4.3}/.pre-commit-config.yaml +0 -0
  26. {blosc2-4.4.2 → blosc2-4.4.3}/.skills/wasm32-pyodide-dev/SKILL.md +0 -0
  27. {blosc2-4.4.2 → blosc2-4.4.3}/.skills/wasm32-pyodide-dev/references/commands.md +0 -0
  28. {blosc2-4.4.2 → blosc2-4.4.3}/ADD_LAZYFUNCS.md +0 -0
  29. {blosc2-4.4.2 → blosc2-4.4.3}/AGENTS.md +0 -0
  30. {blosc2-4.4.2 → blosc2-4.4.3}/CONTRIBUTING.rst +0 -0
  31. {blosc2-4.4.2 → blosc2-4.4.3}/LICENSE.txt +0 -0
  32. {blosc2-4.4.2 → blosc2-4.4.3}/ONBOARDING.md +0 -0
  33. {blosc2-4.4.2 → blosc2-4.4.3}/README.rst +0 -0
  34. {blosc2-4.4.2 → blosc2-4.4.3}/README_DEVELOPERS.md +0 -0
  35. {blosc2-4.4.2 → blosc2-4.4.3}/RELEASING.rst +0 -0
  36. {blosc2-4.4.2 → blosc2-4.4.3}/ROADMAP-TO-4.0.md +0 -0
  37. {blosc2-4.4.2 → blosc2-4.4.3}/code_of_conduct.md +0 -0
  38. {blosc2-4.4.2 → blosc2-4.4.3}/doc/_static/blosc-favicon_32x32.png +0 -0
  39. {blosc2-4.4.2 → blosc2-4.4.3}/doc/_static/blosc-favicon_64x64.png +0 -0
  40. {blosc2-4.4.2 → blosc2-4.4.3}/doc/_static/blosc-logo_128.png +0 -0
  41. {blosc2-4.4.2 → blosc2-4.4.3}/doc/_static/blosc-logo_256.png +0 -0
  42. {blosc2-4.4.2 → blosc2-4.4.3}/doc/_static/css/custom.css +0 -0
  43. {blosc2-4.4.2 → blosc2-4.4.3}/doc/conf.py +0 -0
  44. {blosc2-4.4.2 → blosc2-4.4.3}/doc/development/code-of-conduct.rst +0 -0
  45. {blosc2-4.4.2 → blosc2-4.4.3}/doc/development/contributing.rst +0 -0
  46. {blosc2-4.4.2 → blosc2-4.4.3}/doc/development/index.rst +0 -0
  47. {blosc2-4.4.2 → blosc2-4.4.3}/doc/development/roadmap.rst +0 -0
  48. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/dsl_syntax.md +0 -0
  49. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/index.rst +0 -0
  50. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/installation.rst +0 -0
  51. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/overview.rst +0 -0
  52. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/parquet_to_blosc2.rst +0 -0
  53. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/01.ndarray-basics.ipynb +0 -0
  54. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/02.lazyarray-expressions.ipynb +0 -0
  55. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/03.lazyarray-udf-kernels.ipynb +0 -0
  56. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/03.lazyarray-udf.ipynb +0 -0
  57. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/04.reductions.ipynb +0 -0
  58. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/05.persistent-reductions.ipynb +0 -0
  59. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/06.remote_proxy.ipynb +0 -0
  60. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/07.schunk-basics.ipynb +0 -0
  61. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/08.schunk-slicing_and_beyond.ipynb +0 -0
  62. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/09.ucodecs-ufilters.ipynb +0 -0
  63. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/10.prefilters.ipynb +0 -0
  64. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/11.containers.ipynb +0 -0
  65. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/11.objectarray.ipynb +0 -0
  66. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/12.batcharray.ipynb +0 -0
  67. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/13.ctable-basics.ipynb +0 -0
  68. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/14.indexing-arrays.ipynb +0 -0
  69. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/15.indexing-ctables.ipynb +0 -0
  70. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/blosc2-pipeline.png +0 -0
  71. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/blosc2-pipeline.svg +0 -0
  72. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/containers/README.md +0 -0
  73. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/containers/overview.svg +0 -0
  74. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/lazyexpr-broadcast.png +0 -0
  75. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/proxyconnection.png +0 -0
  76. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/reductions/3D-cube-plane.png +0 -0
  77. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/reductions/3D-cube.png +0 -0
  78. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/reductions/memory-access-2D-x.png +0 -0
  79. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/reductions/memory-access-2D-y.png +0 -0
  80. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/remote_proxy.png +0 -0
  81. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/ucodecs-filters/backward.png +0 -0
  82. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/ucodecs-filters/backward.svg +0 -0
  83. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/ucodecs-filters/decoder.png +0 -0
  84. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/ucodecs-filters/decoder.svg +0 -0
  85. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/ucodecs-filters/decoder2.png +0 -0
  86. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/ucodecs-filters/decoder2.svg +0 -0
  87. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/ucodecs-filters/encoder.png +0 -0
  88. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/ucodecs-filters/encoder.svg +0 -0
  89. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/ucodecs-filters/encoder2.png +0 -0
  90. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/ucodecs-filters/encoder2.svg +0 -0
  91. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/ucodecs-filters/forward.png +0 -0
  92. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials/images/ucodecs-filters/forward.svg +0 -0
  93. {blosc2-4.4.2 → blosc2-4.4.3}/doc/getting_started/tutorials.rst +0 -0
  94. {blosc2-4.4.2 → blosc2-4.4.3}/doc/index.rst +0 -0
  95. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/additional_funcs.rst +0 -0
  96. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/array.rst +0 -0
  97. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/array_operations.rst +0 -0
  98. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/batch_array.rst +0 -0
  99. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/c2array.rst +0 -0
  100. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/classes.rst +0 -0
  101. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/dict_store.rst +0 -0
  102. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/embed_store.rst +0 -0
  103. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/index.rst +0 -0
  104. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/index_class.rst +0 -0
  105. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/index_funcs.rst +0 -0
  106. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/lazyarray.rst +0 -0
  107. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/linalg.rst +0 -0
  108. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/list_array.rst +0 -0
  109. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/low_level.rst +0 -0
  110. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/misc.rst +0 -0
  111. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/msgpack_serialization.rst +0 -0
  112. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/ndarray.rst +0 -0
  113. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/ndfield.rst +0 -0
  114. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/objectarray.rst +0 -0
  115. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/proxy.rst +0 -0
  116. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/proxyndsource.rst +0 -0
  117. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/proxysource.rst +0 -0
  118. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/reduction_functions.rst +0 -0
  119. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/ref.rst +0 -0
  120. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/save_load.rst +0 -0
  121. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/schunk.rst +0 -0
  122. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/simpleproxy.rst +0 -0
  123. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/storage.rst +0 -0
  124. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/tree_store.rst +0 -0
  125. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/ufuncs.rst +0 -0
  126. {blosc2-4.4.2 → blosc2-4.4.3}/doc/reference/utilities.rst +0 -0
  127. {blosc2-4.4.2 → blosc2-4.4.3}/doc/release_notes/index.md +0 -0
  128. {blosc2-4.4.2 → blosc2-4.4.3}/examples/batch_array.py +0 -0
  129. {blosc2-4.4.2 → blosc2-4.4.3}/examples/blosc2_hdf5_compression.py +0 -0
  130. {blosc2-4.4.2 → blosc2-4.4.3}/examples/btune.py +0 -0
  131. {blosc2-4.4.2 → blosc2-4.4.3}/examples/c2array-get-slice.py +0 -0
  132. {blosc2-4.4.2 → blosc2-4.4.3}/examples/compress2_decompress2.py +0 -0
  133. {blosc2-4.4.2 → blosc2-4.4.3}/examples/compress_decompress.py +0 -0
  134. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/aggregates.py +0 -0
  135. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/arrow_interop.py +0 -0
  136. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/basics.py +0 -0
  137. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/computed-columns.py +0 -0
  138. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/copying.py +0 -0
  139. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/csv_interop.py +0 -0
  140. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/group_by.py +0 -0
  141. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/index_on_b2z.py +0 -0
  142. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/indexing.py +0 -0
  143. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/mutations.py +0 -0
  144. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/ndim-cols.py +0 -0
  145. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/nullable.py +0 -0
  146. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/persistence.py +0 -0
  147. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/querying.py +0 -0
  148. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/real_world.py +0 -0
  149. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/schema.py +0 -0
  150. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/udf-computed-col.py +0 -0
  151. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ctable/varlen_columns.py +0 -0
  152. {blosc2-4.4.2 → blosc2-4.4.3}/examples/dict-store.py +0 -0
  153. {blosc2-4.4.2 → blosc2-4.4.3}/examples/embed-store.py +0 -0
  154. {blosc2-4.4.2 → blosc2-4.4.3}/examples/embedded-expr-udf-b2z.py +0 -0
  155. {blosc2-4.4.2 → blosc2-4.4.3}/examples/filler.py +0 -0
  156. {blosc2-4.4.2 → blosc2-4.4.3}/examples/gil.py +0 -0
  157. {blosc2-4.4.2 → blosc2-4.4.3}/examples/mmap-rw.py +0 -0
  158. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/animated_plot.py +0 -0
  159. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/arange-constructor.py +0 -0
  160. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/asarray_.py +0 -0
  161. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/black-scholes_hist-dsl.ipynb +0 -0
  162. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/blosc2_3_10_demo.py +0 -0
  163. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/broadcast_expr.py +0 -0
  164. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/buffer.py +0 -0
  165. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/bytedelta_filter.py +0 -0
  166. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/c2array_expr.py +0 -0
  167. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/compute_expr.py +0 -0
  168. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/compute_fields.py +0 -0
  169. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/compute_udf_numba.py +0 -0
  170. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/compute_where.py +0 -0
  171. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/copy_.py +0 -0
  172. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/dsl_save.py +0 -0
  173. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/empty_.py +0 -0
  174. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/expression_index.py +0 -0
  175. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/eye-constructor.py +0 -0
  176. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/fancy-indexing.py +0 -0
  177. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/filter_sort_fields.py +0 -0
  178. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/formats.py +0 -0
  179. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/fromiter-constructor.py +0 -0
  180. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/general_expressions.py +0 -0
  181. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/getitem.py +0 -0
  182. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/index_append_maintenance.py +0 -0
  183. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/index_sorted_iteration.py +0 -0
  184. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/ironpill1.ipynb +0 -0
  185. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/iterchunks_info.py +0 -0
  186. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/jit-expr.py +0 -0
  187. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/jit-numpy-funcs.py +0 -0
  188. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/jit-reduc.py +0 -0
  189. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/lazyexpr_where_indexing.py +0 -0
  190. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/linspace-constructor.py +0 -0
  191. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/lists-vs-bools-idx.py +0 -0
  192. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/malformed_dsl.py +0 -0
  193. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/mandelbrot-dsl.ipynb +0 -0
  194. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/mandelbrot-pure-dsl.ipynb +0 -0
  195. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/meta.py +0 -0
  196. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/ndarray_copy.py +0 -0
  197. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/ndmean.py +0 -0
  198. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/persistency.py +0 -0
  199. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/proxy-carray.py +0 -0
  200. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/proxy-ndarray.py +0 -0
  201. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/reduce_and_enlarge.py +0 -0
  202. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/reduce_expr.py +0 -0
  203. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/reduce_expr_save.py +0 -0
  204. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/reduce_string_expr.py +0 -0
  205. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/resize_.py +0 -0
  206. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/string_arrays.ipynb +0 -0
  207. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/take.py +0 -0
  208. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/work_with_numpy.py +0 -0
  209. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/xarray-expression.py +0 -0
  210. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ndarray/zfp_codec.py +0 -0
  211. {blosc2-4.4.2 → blosc2-4.4.3}/examples/objectarray.py +0 -0
  212. {blosc2-4.4.2 → blosc2-4.4.3}/examples/pack_array.py +0 -0
  213. {blosc2-4.4.2 → blosc2-4.4.3}/examples/pack_tensor.py +0 -0
  214. {blosc2-4.4.2 → blosc2-4.4.3}/examples/postfilter1.py +0 -0
  215. {blosc2-4.4.2 → blosc2-4.4.3}/examples/postfilter2.py +0 -0
  216. {blosc2-4.4.2 → blosc2-4.4.3}/examples/postfilter3.py +0 -0
  217. {blosc2-4.4.2 → blosc2-4.4.3}/examples/prefilter.py +0 -0
  218. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ref-object.py +0 -0
  219. {blosc2-4.4.2 → blosc2-4.4.3}/examples/save_tensor.py +0 -0
  220. {blosc2-4.4.2 → blosc2-4.4.3}/examples/schunk.py +0 -0
  221. {blosc2-4.4.2 → blosc2-4.4.3}/examples/schunk_roundtrip.py +0 -0
  222. {blosc2-4.4.2 → blosc2-4.4.3}/examples/tree-store-blog.py +0 -0
  223. {blosc2-4.4.2 → blosc2-4.4.3}/examples/tree-store.py +0 -0
  224. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ucodecs.py +0 -0
  225. {blosc2-4.4.2 → blosc2-4.4.3}/examples/ufilters.py +0 -0
  226. {blosc2-4.4.2 → blosc2-4.4.3}/examples/vlmeta.py +0 -0
  227. {blosc2-4.4.2 → blosc2-4.4.3}/examples/vlstore-lazyudf.py +0 -0
  228. {blosc2-4.4.2 → blosc2-4.4.3}/generate_version.py +0 -0
  229. {blosc2-4.4.2 → blosc2-4.4.3}/guix.scm +0 -0
  230. {blosc2-4.4.2 → blosc2-4.4.3}/images/Complete-Write-Read-B2ND.png +0 -0
  231. {blosc2-4.4.2 → blosc2-4.4.3}/images/M1-i386-vs-arm64-pack.png +0 -0
  232. {blosc2-4.4.2 → blosc2-4.4.3}/images/M1-i386-vs-arm64-unpack.png +0 -0
  233. {blosc2-4.4.2 → blosc2-4.4.3}/images/Read-Partial-Slices-B2ND.png +0 -0
  234. {blosc2-4.4.2 → blosc2-4.4.3}/images/b2nd-2level-parts.png +0 -0
  235. {blosc2-4.4.2 → blosc2-4.4.3}/images/eval-expr-full-mem-M2.png +0 -0
  236. {blosc2-4.4.2 → blosc2-4.4.3}/images/eval-expr-scarce-mem-M2.png +0 -0
  237. {blosc2-4.4.2 → blosc2-4.4.3}/images/lazyarray-dask-large.png +0 -0
  238. {blosc2-4.4.2 → blosc2-4.4.3}/images/lazyarray-dask-small.png +0 -0
  239. {blosc2-4.4.2 → blosc2-4.4.3}/images/lazyarray-expr-large.png +0 -0
  240. {blosc2-4.4.2 → blosc2-4.4.3}/images/lazyarray-expr.png +0 -0
  241. {blosc2-4.4.2 → blosc2-4.4.3}/images/linspace-compress.png +0 -0
  242. {blosc2-4.4.2 → blosc2-4.4.3}/images/linspace-decompress.png +0 -0
  243. {blosc2-4.4.2 → blosc2-4.4.3}/images/pack-array-cratios.png +0 -0
  244. {blosc2-4.4.2 → blosc2-4.4.3}/images/reduc-float64-amd.png +0 -0
  245. {blosc2-4.4.2 → blosc2-4.4.3}/images/reduc-float64-log-amd.png +0 -0
  246. {blosc2-4.4.2 → blosc2-4.4.3}/plans/b2view.md +0 -0
  247. {blosc2-4.4.2 → blosc2-4.4.3}/plans/changing-default-open-mode.md +0 -0
  248. {blosc2-4.4.2 → blosc2-4.4.3}/plans/computed-column-copilot.md +0 -0
  249. {blosc2-4.4.2 → blosc2-4.4.3}/plans/containers-tutorial.md +0 -0
  250. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-dictionary-type.md +0 -0
  251. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-direct-expr-indexing.md +0 -0
  252. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-getitem-row.md +0 -0
  253. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-groupby.md +0 -0
  254. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-implementation-log.md +0 -0
  255. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-indexes-opsi.md +0 -0
  256. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-indexing.md +0 -0
  257. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-ndarray-cols-copilot-sonnet.md +0 -0
  258. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-ndarray-cols.md +0 -0
  259. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-nested-fields.md +0 -0
  260. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-nulls.md +0 -0
  261. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-object-array.md +0 -0
  262. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-parquet-metadata.md +0 -0
  263. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-persistency.md +0 -0
  264. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-schema.md +0 -0
  265. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-separate-nested-cols.md +0 -0
  266. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-user-guide.md +0 -0
  267. {blosc2-4.4.2 → blosc2-4.4.3}/plans/ctable-varlen-cols.md +0 -0
  268. {blosc2-4.4.2 → blosc2-4.4.3}/plans/external-js-glue-blosc2-todo.md +0 -0
  269. {blosc2-4.4.2 → blosc2-4.4.3}/plans/external-js-glue.md +0 -0
  270. {blosc2-4.4.2 → blosc2-4.4.3}/plans/maskout-cbuffer.md +0 -0
  271. {blosc2-4.4.2 → blosc2-4.4.3}/plans/materialized-computed-column.md +0 -0
  272. {blosc2-4.4.2 → blosc2-4.4.3}/plans/new-ctable-views.md +0 -0
  273. {blosc2-4.4.2 → blosc2-4.4.3}/plans/phase0-t1-dsl-syntax-inventory.md +0 -0
  274. {blosc2-4.4.2 → blosc2-4.4.3}/plans/tree_store_ctable_ndarray.md +0 -0
  275. {blosc2-4.4.2 → blosc2-4.4.3}/plans/tree_store_extensions.md +0 -0
  276. {blosc2-4.4.2 → blosc2-4.4.3}/plans/treestore-ctable-extension.md +0 -0
  277. {blosc2-4.4.2 → blosc2-4.4.3}/plans/wasm32-todo.md +0 -0
  278. {blosc2-4.4.2 → blosc2-4.4.3}/pytest.ini +0 -0
  279. {blosc2-4.4.2 → blosc2-4.4.3}/scripts/install-codex-skill-wasm32.sh +0 -0
  280. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/b2objects.py +0 -0
  281. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/b2view/__init__.py +0 -0
  282. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/b2view/app.py +0 -0
  283. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/b2view/cli.py +0 -0
  284. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/b2view/model.py +0 -0
  285. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/b2view/render.py +0 -0
  286. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/batch_array.py +0 -0
  287. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/blosc2_ext.pyx +0 -0
  288. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/c2array.py +0 -0
  289. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/cli/__init__.py +0 -0
  290. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/core.py +0 -0
  291. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/ctable_storage.py +0 -0
  292. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/dictionary_column.py +0 -0
  293. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/dsl_kernel.py +0 -0
  294. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/embed_store.py +0 -0
  295. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/exceptions.py +0 -0
  296. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/fft.py +0 -0
  297. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/groupby_ext.pyx +0 -0
  298. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/indexing.py +0 -0
  299. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/indexing_ext.pyx +0 -0
  300. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/info.py +0 -0
  301. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/linalg.py +0 -0
  302. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/list_array.py +0 -0
  303. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/matmul_kernels.c +0 -0
  304. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/matmul_kernels.h +0 -0
  305. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/msgpack_utils.py +0 -0
  306. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/ndarray.py +0 -0
  307. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/objectarray.py +0 -0
  308. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/proxy.py +0 -0
  309. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/ref.py +0 -0
  310. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/scalar_array.py +0 -0
  311. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/schema.py +0 -0
  312. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/schema_compiler.py +0 -0
  313. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/schema_validation.py +0 -0
  314. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/schema_vectorized.py +0 -0
  315. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/schunk.py +0 -0
  316. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/storage.py +0 -0
  317. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/tree_store.py +0 -0
  318. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/utils.py +0 -0
  319. {blosc2-4.4.2 → blosc2-4.4.3}/src/blosc2/wasm_jit.py +0 -0
  320. {blosc2-4.4.2 → blosc2-4.4.3}/tests/array-api-xfails.txt +0 -0
  321. {blosc2-4.4.2 → blosc2-4.4.3}/tests/conftest.py +0 -0
  322. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_column_ndarray_like.py +0 -0
  323. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_compact.py +0 -0
  324. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_construct.py +0 -0
  325. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_csv_interop.py +0 -0
  326. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_ctable_dataclass_schema.py +0 -0
  327. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_ctable_dsl_columns.py +0 -0
  328. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_ctable_indexing.py +0 -0
  329. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_ctable_ndarray_columns.py +0 -0
  330. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_ctable_take.py +0 -0
  331. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_delete_rows.py +0 -0
  332. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_dictionary_column.py +0 -0
  333. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_extend_delete.py +0 -0
  334. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_getitem_access.py +0 -0
  335. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_nested_access_storage.py +0 -0
  336. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_nested_append.py +0 -0
  337. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_nested_metadata_root.py +0 -0
  338. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_nullable.py +0 -0
  339. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_object_spec.py +0 -0
  340. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_parquet_interop.py +0 -0
  341. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_row_logic.py +0 -0
  342. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_schema_compiler.py +0 -0
  343. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_schema_mutations.py +0 -0
  344. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_schema_specs.py +0 -0
  345. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_schema_validation.py +0 -0
  346. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_select_describe_cov.py +0 -0
  347. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_sort_by.py +0 -0
  348. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_table_persistency.py +0 -0
  349. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_varlen_columns.py +0 -0
  350. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_varlen_schema_compiler.py +0 -0
  351. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_vlstring_vlbytes.py +0 -0
  352. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ctable/test_where_expressions.py +0 -0
  353. {blosc2-4.4.2 → blosc2-4.4.3}/tests/data/legacy_lazyexpr_v1/a.b2nd +0 -0
  354. {blosc2-4.4.2 → blosc2-4.4.3}/tests/data/legacy_lazyexpr_v1/b.b2nd +0 -0
  355. {blosc2-4.4.2 → blosc2-4.4.3}/tests/data/legacy_lazyexpr_v1/expr.b2nd +0 -0
  356. {blosc2-4.4.2 → blosc2-4.4.3}/tests/data/legacy_lazyudf_v1/a.b2nd +0 -0
  357. {blosc2-4.4.2 → blosc2-4.4.3}/tests/data/legacy_lazyudf_v1/b.b2nd +0 -0
  358. {blosc2-4.4.2 → blosc2-4.4.3}/tests/data/legacy_lazyudf_v1/expr.b2nd +0 -0
  359. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_auto_parts.py +0 -0
  360. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_buffer.py +0 -0
  361. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_c2array_expr.py +0 -0
  362. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_c2array_reductions.py +0 -0
  363. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_c2array_udf.py +0 -0
  364. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_concat.py +0 -0
  365. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_copy.py +0 -0
  366. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_dsl_kernels.py +0 -0
  367. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_elementwise_funcs.py +0 -0
  368. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_empty.py +0 -0
  369. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_evaluate.py +0 -0
  370. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_full.py +0 -0
  371. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_get_slice_nchunks.py +0 -0
  372. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_getitem.py +0 -0
  373. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_indexing.py +0 -0
  374. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_iterchunks_info.py +0 -0
  375. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_jit.py +0 -0
  376. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_lazyexpr.py +0 -0
  377. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_lazyexpr_fields.py +0 -0
  378. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_lazyudf.py +0 -0
  379. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_linalg.py +0 -0
  380. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_lossy.py +0 -0
  381. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_metalayers.py +0 -0
  382. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_mode.py +0 -0
  383. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_nans.py +0 -0
  384. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_ndarray.py +0 -0
  385. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_numpy.py +0 -0
  386. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_persistency.py +0 -0
  387. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_proxy.py +0 -0
  388. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_proxy_c2array.py +0 -0
  389. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_proxy_expr.py +0 -0
  390. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_reductions.py +0 -0
  391. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_resize.py +0 -0
  392. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_setitem.py +0 -0
  393. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_slice.py +0 -0
  394. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_squeeze.py +0 -0
  395. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_stringarrays.py +0 -0
  396. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_struct_dtype.py +0 -0
  397. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_wasm_dsl_jit.py +0 -0
  398. {blosc2-4.4.2 → blosc2-4.4.3}/tests/ndarray/test_zeros.py +0 -0
  399. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_b2objects.py +0 -0
  400. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_b2view_model.py +0 -0
  401. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_batch_array.py +0 -0
  402. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_bytes_array.py +0 -0
  403. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_comp_info.py +0 -0
  404. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_compress2.py +0 -0
  405. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_compression_parameters.py +0 -0
  406. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_compressors.py +0 -0
  407. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_decompress.py +0 -0
  408. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_dict_store.py +0 -0
  409. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_embed_store.py +0 -0
  410. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_group_reduce.py +0 -0
  411. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_iterchunks.py +0 -0
  412. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_list_array.py +0 -0
  413. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_mmap.py +0 -0
  414. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_numexpr_threads.py +0 -0
  415. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_objectarray.py +0 -0
  416. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_open.py +0 -0
  417. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_open_c2array.py +0 -0
  418. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_pandas_udf_engine.py +0 -0
  419. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_pathlib.py +0 -0
  420. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_postfilters.py +0 -0
  421. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_prefilters.py +0 -0
  422. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_proxy_schunk.py +0 -0
  423. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_python_blosc.py +0 -0
  424. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_schunk.py +0 -0
  425. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_schunk_constructor.py +0 -0
  426. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_schunk_delete.py +0 -0
  427. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_schunk_get_slice.py +0 -0
  428. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_schunk_get_slice_nchunks.py +0 -0
  429. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_schunk_insert.py +0 -0
  430. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_schunk_reorder_offsets.py +0 -0
  431. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_schunk_set_slice.py +0 -0
  432. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_schunk_update.py +0 -0
  433. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_storage.py +0 -0
  434. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_tensor.py +0 -0
  435. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_tree_store.py +0 -0
  436. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_ucodecs.py +0 -0
  437. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_ufilters.py +0 -0
  438. {blosc2-4.4.2 → blosc2-4.4.3}/tests/test_vlmeta.py +0 -0
  439. {blosc2-4.4.2 → blosc2-4.4.3}/update_version.py +0 -0
@@ -0,0 +1,105 @@
1
+ Announcing Python-Blosc2 4.4.3
2
+ ==============================
3
+
4
+ We are happy to announce this maintenance release that makes CTable
5
+ cold-start, printing, querying and groupby noticeably faster, trims the
6
+ memory footprint of ``import blosc2``, adds raw-storage access for columns,
7
+ and exposes the new JPEG 2000 codec plugins.
8
+
9
+ The main highlights are:
10
+
11
+ - **Faster CTable cold-start**: views created by ``select()`` now open
12
+ columns lazily — only the columns actually read are loaded from storage —
13
+ and queries only open the SUMMARY indexes referenced by the predicate,
14
+ instead of every indexed column on a wide persistent table.
15
+
16
+ - **Faster printing and groupby**: table rendering now performs a single
17
+ combined sparse read per column (instead of ~6), and groupby takes the
18
+ dense fast path for float key columns whose values are integral and fit a
19
+ compact non-negative range.
20
+
21
+ - **Lighter imports**: the on-disk chunk prefetcher no longer uses asyncio,
22
+ so ``import blosc2`` skips ~30 asyncio modules and saves ~3 MB of memory.
23
+ A latent prefetcher deadlock on early iterator close was fixed as well.
24
+
25
+ - **New ``Column.raw`` accessor**: the underlying storage container
26
+ (``NDArray``, ``ListArray``, …) as a blosc2-native compressed object —
27
+ unlike ``col[...]`` reads, which always materialize NumPy arrays. Useful
28
+ as a lazy-expression operand and for storage introspection.
29
+
30
+ - **J2K and HTJ2K codecs**: ``blosc2.Codec.J2K`` and ``blosc2.Codec.HTJ2K``
31
+ expose the IDs for the new JPEG 2000 plugins (``pip install blosc2-j2k``
32
+ / ``pip install blosc2-htj2k``). Also, C-Blosc2 has been updated to 3.1.3.
33
+
34
+ - **Fixes**: ``--float-trunc-prec`` in the ``parquet_to_blosc2`` CLI now
35
+ propagates to nested columns; unsupported computed-column expressions are
36
+ rejected early with an actionable error; and opening a ``.b2z``/``.b2d``
37
+ store in read mode no longer creates a temporary directory.
38
+
39
+ A quick example of the new ``Column.raw`` accessor::
40
+
41
+ import blosc2
42
+ import dataclasses
43
+
44
+ @dataclasses.dataclass
45
+ class Row:
46
+ price: float = blosc2.field(blosc2.float64())
47
+ qty: int = blosc2.field(blosc2.int64())
48
+
49
+ t = blosc2.CTable(Row, new_data=[(1.5, 10), (2.0, 5), (3.0, 3)])
50
+
51
+ # The raw storage container, as a blosc2-native compressed object.
52
+ # It is over-allocated to chunk capacity, so slice to the live row count.
53
+ raw = t["price"].raw # a blosc2.NDArray
54
+ print(raw[:len(t)]) # [1.5 2. 3. ]
55
+
56
+ # Usable directly as a lazy-expression operand, without decompressing
57
+ expr = raw * 2.0
58
+ print(expr[:len(t)]) # [3. 4. 6.]
59
+
60
+ Install it with::
61
+
62
+ pip install blosc2 --upgrade # if you prefer wheels
63
+ conda install -c conda-forge python-blosc2 mkl # if you prefer conda and MKL
64
+
65
+ For more info, see the release notes at:
66
+
67
+ https://github.com/Blosc/python-blosc2/releases
68
+
69
+ What is Python-Blosc2?
70
+ ----------------------
71
+
72
+ Python-Blosc2 is a high-performance compressor, compute engine, and format
73
+ for binary data containers that are portable and open-source. It comes with
74
+ a lazy expression engine allowing for complex calculations on compressed data,
75
+ whether stored in memory, on disk, or over the network (e.g., via
76
+ `Caterva2 <https://github.com/ironArray/Caterva2>`_). It is especially
77
+ optimized for storing and retrieving data from N-dimensional arrays (`NDArray`),
78
+ columnar tables (`CTable`), and a query/indexing layer. The main use case is
79
+ fast, compressed, out-of-core numerical data — especially when data is too
80
+ large to fit comfortably in RAM.
81
+
82
+ More info: https://www.blosc.org/python-blosc2/getting_started/overview.html
83
+
84
+
85
+ Sources repository
86
+ ------------------
87
+
88
+ The sources and documentation are managed through GitHub services at:
89
+
90
+ https://github.com/Blosc/python-blosc2
91
+
92
+ Python-Blosc2 is distributed using the BSD license, see
93
+ https://github.com/Blosc/python-blosc2/blob/main/LICENSE.txt
94
+ for details.
95
+
96
+ Mastodon feed
97
+ -------------
98
+
99
+ Follow https://fosstodon.org/@Blosc2 to get informed about the latest
100
+ developments.
101
+
102
+ Enjoy!
103
+
104
+ - Blosc Development Team
105
+ Compress Better, Compute Bigger
@@ -15,7 +15,7 @@ endif()
15
15
  project(python-blosc2)
16
16
 
17
17
  set(BLOSC2_MIN_VERSION 3.0.0)
18
- set(BLOSC2_BUNDLED_VERSION v3.1.2)
18
+ set(BLOSC2_BUNDLED_VERSION v3.1.3)
19
19
 
20
20
  if(WIN32 AND NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")
21
21
  message(FATAL_ERROR "Windows builds require clang-cl. Set CC/CXX to clang-cl or configure CMake with -T ClangCL.")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: blosc2
3
- Version: 4.4.2
3
+ Version: 4.4.3
4
4
  Summary: A fast & compressed ndarray library with a flexible compute engine.
5
5
  Author-Email: Blosc Development Team <blosc@blosc.org>
6
6
  Maintainer-Email: Blosc Development Team <blosc@blosc.org>
@@ -1,5 +1,76 @@
1
1
  # Release notes
2
2
 
3
+ ## Changes from 4.4.2 to 4.4.3
4
+
5
+ This is a maintenance release focused on faster CTable cold-start, printing
6
+ and groupby performance, a lighter `import blosc2`, new raw-storage access
7
+ for columns, and support for the new J2K/HTJ2K codec plugins.
8
+
9
+ ### CTable performance
10
+
11
+ - **Lazy column opening in views**: `select()` (and other view-producing
12
+ operations) no longer open every projected column up front. A column is
13
+ only opened from storage when the view actually reads it, so selecting and
14
+ then touching a subset of columns — or aggregating a single one — skips
15
+ the cold-start cost of the rest.
16
+ - **Lazy index opening in queries**: query planning no longer opens every
17
+ SUMMARY-indexed column on a wide persistent table; only indexes for
18
+ columns actually referenced by the predicate are loaded.
19
+ - **Faster table printing**: `repr()`/`to_string()` now memoise per-column
20
+ sparse gathers for the duration of a render and combine the head and tail
21
+ rows into a single sparse read per column. Each column is read from
22
+ storage once instead of ~6 times (precision detection, width sizing and
23
+ row rendering all hit the cache).
24
+ - **Groupby with integral float keys**: float key columns whose values are
25
+ integral and fit a compact non-negative range (e.g. float32 id/second
26
+ columns) now take the dense single-key fast path instead of the markedly
27
+ slower generic float-hash path. Fractional or non-finite keys fall back
28
+ automatically.
29
+ - **No tempdir in read mode**: opening a `.b2z`/`.b2d` store in `'r'` mode
30
+ no longer creates a temporary working directory, since nothing is ever
31
+ written.
32
+
33
+ ### Lighter imports and prefetcher rework
34
+
35
+ - **asyncio dependency dropped**: the on-disk chunk prefetcher used by the
36
+ UDF and numexpr fallback engines now uses plain `concurrent.futures`
37
+ instead of an asyncio event loop. `import blosc2` no longer pulls in
38
+ ~30 asyncio modules, saving ~3 MB of memory footprint at import time.
39
+ - **Prefetcher deadlock fixed**: an exception during evaluation could leave
40
+ the generator finalizer blocked forever in `thread.join()` while the
41
+ reader thread was stuck on a full prefetch queue. A stop event now makes
42
+ the producer bail out when its consumer goes away.
43
+
44
+ ### New features
45
+
46
+ - **`Column.raw` accessor**: returns the underlying storage container of a
47
+ column (`NDArray`, `ListArray`, `DictionaryColumn`, …) directly. Unlike
48
+ `Column.__getitem__`, which always materializes NumPy arrays, this is the
49
+ column as a blosc2-native compressed object — usable as a lazy-expression
50
+ operand without decompressing, and exposing storage details like `schunk`,
51
+ `chunks` or `cparams`. Note that this is a *physical* view: fixed-width
52
+ containers are over-allocated to chunk capacity, so slice to `len(table)`
53
+ to get just the live rows, and no validity-mask or null-sentinel
54
+ processing is applied. Raises `AttributeError` for computed columns,
55
+ which have no backing storage.
56
+ - **J2K and HTJ2K codec IDs**: `blosc2.Codec.J2K` and `blosc2.Codec.HTJ2K`
57
+ expose the IDs for the new JPEG 2000 codec plugins (installable with
58
+ `pip install blosc2-j2k` and `pip install blosc2-htj2k`).
59
+
60
+ ### Fixes
61
+
62
+ - **`--float-trunc-prec` and nested columns**: the precision-truncation
63
+ filter of the `parquet_to_blosc2` CLI now propagates to float fields
64
+ inside nested (struct/list) columns too.
65
+ - **Guard for unsupported computed-column expressions**: expressions that
66
+ would serialize to an empty or non-round-trippable string are now rejected
67
+ with an early, actionable `ValueError` at `add_computed_column()` time,
68
+ instead of silently breaking on reload.
69
+
70
+ ### Build
71
+
72
+ - **C-Blosc2 updated to 3.1.3.**
73
+
3
74
  ## Changes from 4.4.1 to 4.4.2
4
75
 
5
76
  This is a feature and maintenance release that promotes DSL kernels to
@@ -6,7 +6,7 @@
6
6
 
7
7
  <p style="text-align: center; color: black; background-color: rgba(230, 169, 9, 0.65);">
8
8
  <a href="https://github.com/Blosc/python-blosc2/blob/main/RELEASE_NOTES.md"
9
- style="font-size: 1.5em;">Version 4.4.1 released on 2026-06-03!</a>
9
+ style="font-size: 1.5em;">Version 4.4.2 released on 2026-06-04!</a>
10
10
  <span style="display: inline-block; width: 20px;"></span>
11
11
  <span style="font-family: monospace;">pip install blosc2 -U</span>
12
12
  </p>
@@ -565,11 +565,13 @@ Data access
565
565
  .. autosummary::
566
566
 
567
567
  Column.view
568
+ Column.raw
568
569
  Column.take
569
570
  Column.iter_chunks
570
571
  Column.assign
571
572
 
572
573
  .. autoproperty:: Column.view
574
+ .. autoproperty:: Column.raw
573
575
  .. automethod:: Column.take
574
576
  .. automethod:: Column.iter_chunks
575
577
  .. automethod:: Column.assign
@@ -40,7 +40,7 @@ dependencies = [
40
40
  "requests",
41
41
  "threadpoolctl; platform_machine != 'wasm32'",
42
42
  ]
43
- version = "4.4.2"
43
+ version = "4.4.3"
44
44
  [project.entry-points."array_api"]
45
45
  blosc2 = "blosc2"
46
46
 
@@ -125,6 +125,10 @@ class Codec(Enum):
125
125
  GROK = 37
126
126
  #: Needs to be installed with ``pip install blosc2-openzl``
127
127
  OPENZL = 38
128
+ #: Needs to be installed with ``pip install blosc2-j2k``
129
+ J2K = 39
130
+ #: Needs to be installed with ``pip install blosc2-htj2k``
131
+ HTJ2K = 40
128
132
 
129
133
 
130
134
  class Filter(Enum):
@@ -1101,6 +1101,8 @@ def import_unnamed_root_separate_cols( # noqa: C901
1101
1101
  """
1102
1102
 
1103
1103
  inner_schema = blosc2.CTable._inner_schema_for_unnamed_root(pa, parquet_schema)
1104
+ flat_inner_schema = blosc2.CTable._flatten_arrow_struct_schema(pa, inner_schema)
1105
+ float_trunc_column_cparams = build_float_trunc_column_cparams(pa, flat_inner_schema, args)
1104
1106
  total_parquet_rows = pf.metadata.num_rows if pf.metadata is not None else None
1105
1107
 
1106
1108
  # ------------------------------------------------------------------
@@ -1187,6 +1189,13 @@ def import_unnamed_root_separate_cols( # noqa: C901
1187
1189
  print(f"Chunks: {args.chunks:,}")
1188
1190
  if args.blocks is not None:
1189
1191
  print(f"Blocks: {args.blocks:,}")
1192
+ trunc_global = getattr(args, "float_trunc_prec_global", None)
1193
+ trunc_columns = getattr(args, "float_trunc_prec_columns", {})
1194
+ if trunc_global is not None:
1195
+ print(f"Float trunc precision: {trunc_global} bits (all float columns)")
1196
+ if trunc_columns:
1197
+ formatted = ", ".join(f"{name}={bits}" for name, bits in sorted(trunc_columns.items()))
1198
+ print(f"Float trunc columns: {formatted}")
1190
1199
  print()
1191
1200
 
1192
1201
  cparams = blosc2.CParams(codec=blosc2.Codec[args.codec], clevel=args.clevel, use_dict=args.use_dict)
@@ -1204,6 +1213,7 @@ def import_unnamed_root_separate_cols( # noqa: C901
1204
1213
  blosc2_batch_size=args.blosc2_batch_size,
1205
1214
  blosc2_items_per_block=args.blosc2_items_per_block,
1206
1215
  list_serializer=args.list_serializer,
1216
+ column_cparams=float_trunc_column_cparams or None,
1207
1217
  create_summary_index=args.create_summary_index,
1208
1218
  chunks=args.chunks,
1209
1219
  blocks=args.blocks,
@@ -818,6 +818,34 @@ class Column:
818
818
  col = self._table._schema.columns_by_name.get(self._col_name)
819
819
  return col is not None and isinstance(col.spec, NDArraySpec)
820
820
 
821
+ @property
822
+ def raw(self):
823
+ """The underlying storage container for this column, without null-value processing.
824
+
825
+ Returns the raw :class:`blosc2.NDArray`, :class:`~blosc2.ListArray`,
826
+ :class:`~blosc2.DictionaryColumn`, or scalar varlen array directly.
827
+ Unlike :meth:`__getitem__`, which always materializes NumPy arrays,
828
+ this is the column as a blosc2-native compressed object: usable as a
829
+ lazy-expression operand without decompressing, and exposing storage
830
+ details such as ``schunk``, ``chunks``, ``cparams`` or
831
+ ``iterchunks_info()``.
832
+
833
+ This is a physical view of the column: fixed-width containers are
834
+ over-allocated to chunk capacity for appends, so their first axis is
835
+ longer than ``len(column)`` and positions of rows deleted from the
836
+ table still hold their old values. No validity-mask or null-sentinel
837
+ processing is applied; use the :class:`Column` interface for logical
838
+ reads.
839
+
840
+ Raises :exc:`AttributeError` for computed (virtual) columns, which have
841
+ no backing storage.
842
+ """
843
+ if self.is_computed:
844
+ raise AttributeError(
845
+ f"Column {self._col_name!r} is a computed column and has no underlying array"
846
+ )
847
+ return self._raw_col
848
+
821
849
  @property
822
850
  def _valid_rows(self):
823
851
  if self._mask is None:
@@ -2711,18 +2739,34 @@ class _LazyColumnDict(dict):
2711
2739
  the column payloads.
2712
2740
  """
2713
2741
 
2714
- def __init__(self, table: CTable, storage: TableStorage, col_names: list[str]):
2742
+ def __init__(
2743
+ self,
2744
+ table: CTable,
2745
+ storage: TableStorage,
2746
+ col_names: list[str],
2747
+ *,
2748
+ source_cols: dict | None = None,
2749
+ ):
2715
2750
  super().__init__()
2716
2751
  self._table = table
2717
2752
  self._storage = storage
2718
2753
  self._col_names = list(col_names)
2719
2754
  self._available = set(col_names)
2755
+ # When set, columns are projected lazily from another table's ``_cols``
2756
+ # mapping (e.g. a ``select()`` view) instead of opened from storage.
2757
+ # The source mapping itself opens on demand, so the same NDArray object
2758
+ # is shared (no copy) — identical to eager projection, just deferred.
2759
+ self._source_cols = source_cols
2720
2760
 
2721
2761
  def _load(self, name: str):
2722
2762
  if name not in self._available:
2723
2763
  raise KeyError(name)
2724
2764
  if not dict.__contains__(self, name):
2725
- dict.__setitem__(self, name, self._table._open_column_from_storage(self._storage, name))
2765
+ if self._source_cols is not None:
2766
+ value = self._source_cols[name]
2767
+ else:
2768
+ value = self._table._open_column_from_storage(self._storage, name)
2769
+ dict.__setitem__(self, name, value)
2726
2770
  return dict.__getitem__(self, name)
2727
2771
 
2728
2772
  def _load_all(self) -> None:
@@ -3901,6 +3945,28 @@ class CTable(_CTableIndexingMixin, Generic[RowT]):
3901
3945
  + self._format_display_row(values, widths, col_names, float_precisions)
3902
3946
  )
3903
3947
 
3948
+ def _prewarm_display_cache(self, display_cols: list[str], head_pos, tail_pos) -> None:
3949
+ """Pre-populate the render cache with one combined head+tail gather/col.
3950
+
3951
+ Each storage column is then sparse-read a single time (for head ∪ tail)
3952
+ instead of once per slice; the values are split back so the
3953
+ ``(col, id(head_pos))`` and ``(col, id(tail_pos))`` lookups made by
3954
+ precision detection, width sizing and row rendering all hit the cache.
3955
+ Only pays off when both slices are non-empty.
3956
+ """
3957
+ cache = getattr(self, "_display_fetch_cache", None)
3958
+ if cache is None or len(head_pos) == 0 or len(tail_pos) == 0:
3959
+ return
3960
+ real_cols = [n for n in display_cols if n != "..." and (n in self._cols or n in self._computed_cols)]
3961
+ if not real_cols:
3962
+ return
3963
+ nh = len(head_pos)
3964
+ combined = np.concatenate([head_pos, tail_pos])
3965
+ for name in real_cols:
3966
+ vals = self._fetch_col_at_positions_uncached(name, combined)
3967
+ cache[(name, id(head_pos))] = vals[:nh]
3968
+ cache[(name, id(tail_pos))] = vals[nh:]
3969
+
3904
3970
  def _rows_to_dicts(self, positions, col_names: list[str] | None = None) -> list[dict]:
3905
3971
  if len(positions) == 0:
3906
3972
  return []
@@ -4116,10 +4182,26 @@ class CTable(_CTableIndexingMixin, Generic[RowT]):
4116
4182
  nrows = self._n_rows
4117
4183
  ncols = len(self.col_names)
4118
4184
  head_pos, tail_pos, hidden = self._display_positions()
4185
+ # Memoise per-column sparse gathers for the duration of this render so
4186
+ # the repeated (column, head_pos/tail_pos) lookups across precision,
4187
+ # width and row formatting only touch storage once. head_pos/tail_pos
4188
+ # stay referenced below, so keying the cache on their id() is safe.
4189
+ self._display_fetch_cache = {}
4190
+ try:
4191
+ return self._to_string_body(display_index, index_name, nrows, ncols, head_pos, tail_pos, hidden)
4192
+ finally:
4193
+ self._display_fetch_cache = None
4194
+
4195
+ def _to_string_body(self, display_index, index_name, nrows, ncols, head_pos, tail_pos, hidden) -> str:
4119
4196
  index_width = self._display_index_width(nrows, hidden, index_name) if display_index else 0
4120
4197
  display_cols, hidden_cols = self._display_columns(
4121
4198
  display_index=display_index, index_width=index_width
4122
4199
  )
4200
+ # Warm the fetch cache with a single combined head+tail gather per column.
4201
+ # head_pos/tail_pos land in different blocks, but folding them into one
4202
+ # sparse read still halves the per-call gather overhead vs reading head
4203
+ # and tail separately (and every downstream consumer hits the cache).
4204
+ self._prewarm_display_cache(display_cols, head_pos, tail_pos)
4123
4205
  fancy = _CTABLE_PRINT_OPTIONS["fancy"]
4124
4206
  float_precisions = {} if fancy else self._compact_float_precisions(display_cols, head_pos, tail_pos)
4125
4207
  widths = (
@@ -5148,8 +5230,12 @@ class CTable(_CTableIndexingMixin, Generic[RowT]):
5148
5230
  obj._summary_indexes_built = True # views never build indexes
5149
5231
  obj.base = self
5150
5232
 
5151
- # Stored columns — same NDArray objects, no copy
5152
- obj._cols = {name: self._cols[name] for name in cols if name in self._cols}
5233
+ # Stored columns — same NDArray objects, no copy. Project lazily so a
5234
+ # column is only opened when the view actually reads it: selecting then
5235
+ # touching a subset (or aggregating one column) no longer opens every
5236
+ # projected column up front.
5237
+ stored_names = [name for name in cols if name in self._cols]
5238
+ obj._cols = _LazyColumnDict(obj, self._storage, stored_names, source_cols=self._cols)
5153
5239
  obj.col_names = list(cols)
5154
5240
  obj._materialized_cols = {
5155
5241
  name: dict(self._materialized_cols[name]) for name in cols if name in self._materialized_cols
@@ -7844,7 +7930,25 @@ class CTable(_CTableIndexingMixin, Generic[RowT]):
7844
7930
  return re.sub(r"\bo(\d+)\b", _sub, cc["expression"])
7845
7931
 
7846
7932
  def _fetch_col_at_positions(self, name: str, positions: np.ndarray):
7847
- """Fetch values at *positions* (physical indices) — used for display."""
7933
+ """Fetch values at *positions* (physical indices) — used for display.
7934
+
7935
+ During a single ``to_string()`` call the same ``(column, positions)``
7936
+ pair is requested repeatedly — by float-precision detection, column
7937
+ width sizing and the final row rendering — all sharing the same
7938
+ ``head_pos``/``tail_pos`` arrays. When ``to_string`` installs a
7939
+ ``_display_fetch_cache`` we memoise the sparse gather (keyed by the
7940
+ positions array identity) so each column is read from storage once
7941
+ instead of ~6 times.
7942
+ """
7943
+ cache = getattr(self, "_display_fetch_cache", None)
7944
+ if cache is None:
7945
+ return self._fetch_col_at_positions_uncached(name, positions)
7946
+ key = (name, id(positions))
7947
+ if key not in cache:
7948
+ cache[key] = self._fetch_col_at_positions_uncached(name, positions)
7949
+ return cache[key]
7950
+
7951
+ def _fetch_col_at_positions_uncached(self, name: str, positions: np.ndarray):
7848
7952
  cc = self._computed_cols.get(name)
7849
7953
  if cc is not None:
7850
7954
  if len(positions) == 0:
@@ -8548,6 +8652,25 @@ class CTable(_CTableIndexingMixin, Generic[RowT]):
8548
8652
  "jit_backend": obj.kwargs.get("jit_backend"),
8549
8653
  }
8550
8654
  lazy, col_deps = self._normalize_expression_transformer(obj)
8655
+ # Guard: verify the expression string round-trips before storing.
8656
+ # An empty string means the LazyExpr was not fully constructed, and a
8657
+ # malformed string would silently break on reload. Catching both here
8658
+ # gives an early, actionable error instead of a confusing failure later.
8659
+ expression = lazy.expression
8660
+ if not expression:
8661
+ raise ValueError(
8662
+ "The computed-column expression serializes to an empty string "
8663
+ "and cannot be persisted. Make sure the lambda returns a "
8664
+ "blosc2 expression built from table columns (e.g. cols['x'] * 2)."
8665
+ )
8666
+ try:
8667
+ _ops = {f"o{i}": self._cols[dep] for i, dep in enumerate(col_deps)}
8668
+ blosc2.lazyexpr(expression, _ops)
8669
+ except Exception as exc:
8670
+ raise ValueError(
8671
+ f"The computed-column expression {expression!r} cannot be safely "
8672
+ f"persisted and reloaded: {exc}"
8673
+ ) from exc
8551
8674
  return {"kind": "expression", "lazy": lazy, "col_deps": col_deps}
8552
8675
 
8553
8676
  def _dsl_result_dtype(self, kernel, col_deps, dtype):
@@ -950,9 +950,21 @@ class _CTableIndexingMixin:
950
950
  indexed = []
951
951
  seen = set()
952
952
  indexed_arrays = {}
953
+ # Any column referenced by *operands* was already opened to build the
954
+ # predicate expression, so it is present in the column cache. A still
955
+ # un-materialized indexed column therefore cannot be an operand: skip it
956
+ # instead of opening it. Without this, a predicate on a few columns
957
+ # would eagerly open *every* indexed column (e.g. all 11 SUMMARY indexes
958
+ # on a wide persistent table) — a pure cold-start cost. Falling back to
959
+ # the old behaviour for non-dict mappings keeps correctness; at worst a
960
+ # genuinely-unloaded operand would miss the index and full-scan.
961
+ cache_is_dict = isinstance(root_cols, dict)
953
962
  for col_name, descriptor in catalog.items():
954
- if col_name in root_cols:
955
- indexed_arrays[col_name] = (root_cols[col_name], descriptor)
963
+ if col_name not in root_cols:
964
+ continue
965
+ if cache_is_dict and not dict.__contains__(root_cols, col_name):
966
+ continue
967
+ indexed_arrays[col_name] = (root_cols[col_name], descriptor)
956
968
 
957
969
  for operand in operands.values():
958
970
  if not isinstance(operand, blosc2.NDArray):
@@ -164,11 +164,17 @@ class DictStore:
164
164
  # Default extensionless new stores to directory-backed layout.
165
165
  self.is_zip_store = False
166
166
  if self.is_zip_store:
167
- if tmpdir is None:
167
+ if self.mode == "r":
168
+ # Read mode only needs working_dir as a path namespace for relative↔absolute
169
+ # key arithmetic. No files are ever written, so no real directory is needed.
170
+ self._temp_dir_obj = None
171
+ self.working_dir = os.path.splitext(os.path.abspath(self.localpath))[0]
172
+ elif tmpdir is None:
168
173
  b2z_parent = os.path.dirname(os.path.abspath(self.localpath))
169
174
  self._temp_dir_obj = tempfile.TemporaryDirectory(dir=b2z_parent)
170
175
  self.working_dir = self._temp_dir_obj.name
171
176
  else:
177
+ self._temp_dir_obj = None
172
178
  self.working_dir = tmpdir
173
179
  os.makedirs(tmpdir, exist_ok=True)
174
180
  self.b2z_path = self.localpath
@@ -264,10 +264,13 @@ class CTableGroupBy:
264
264
  fast = self._try_execute_cython_float_integral_key_f64_sum(specs)
265
265
  if fast is not None:
266
266
  return fast
267
- fast = self._try_execute_cython_float_hash(specs)
267
+ # Dense single-key path also covers integral-valued float keys with a
268
+ # compact non-negative range (e.g. float32 second/id columns), so try
269
+ # it before the generic float hash path, which is markedly slower.
270
+ fast = self._try_execute_dense_single_int_key(specs)
268
271
  if fast is not None:
269
272
  return fast
270
- fast = self._try_execute_dense_single_int_key(specs)
273
+ fast = self._try_execute_cython_float_hash(specs)
271
274
  if fast is not None:
272
275
  return fast
273
276
 
@@ -1033,8 +1036,12 @@ class CTableGroupBy:
1033
1036
  key_info = self.table._schema.columns_by_name[key_name]
1034
1037
  key_is_dict = self.table._is_dictionary_column(key_info)
1035
1038
  key_dtype = np.dtype(np.int32) if key_is_dict else getattr(key_info.spec, "dtype", None)
1036
- if key_dtype is None or key_dtype.kind not in "biu":
1039
+ if key_dtype is None or key_dtype.kind not in "biuf":
1037
1040
  return None
1041
+ # Float keys are accepted only when their values are integral and fit a
1042
+ # compact non-negative range; per-chunk casting verifies integrality and
1043
+ # bails (falling back to the hash path) on the first fractional value.
1044
+ key_is_integral_float = (not key_is_dict) and key_dtype.kind == "f"
1038
1045
  if any(spec.op in {"min", "max"} and spec.input_col is not None for spec in specs):
1039
1046
  for spec in specs:
1040
1047
  if spec.op in {"min", "max"} and spec.input_col is not None:
@@ -1107,6 +1114,16 @@ class CTableGroupBy:
1107
1114
  keys = np.asarray(raw_keys[live_mask])
1108
1115
  if keys.dtype.kind == "b":
1109
1116
  keys = keys.astype(np.int8, copy=False)
1117
+ elif key_is_integral_float:
1118
+ # Non-finite keys (NaN/inf, e.g. a retained NaN group when
1119
+ # dropna=False) and fractional keys both make the dense integer
1120
+ # mapping invalid; defer to the generic/hash fallback.
1121
+ if not np.all(np.isfinite(keys)):
1122
+ return None
1123
+ keys_int = keys.astype(np.int64)
1124
+ if not np.array_equal(keys_int, keys):
1125
+ return None
1126
+ keys = keys_int
1110
1127
  if len(keys) == 0:
1111
1128
  continue
1112
1129
  min_key = int(np.min(keys))
@@ -1159,7 +1176,12 @@ class CTableGroupBy:
1159
1176
  group_codes = np.nonzero(present)[0]
1160
1177
  rows = []
1161
1178
  for code in group_codes:
1162
- key_value = self.table._cols[key_name].decode(int(code)) if key_is_dict else _python_scalar(code)
1179
+ if key_is_dict:
1180
+ key_value = self.table._cols[key_name].decode(int(code))
1181
+ elif key_is_integral_float:
1182
+ key_value = float(code)
1183
+ else:
1184
+ key_value = _python_scalar(code)
1163
1185
  row = {key_name: key_value}
1164
1186
  for spec in specs:
1165
1187
  state = states[spec.output_col]