fpstreams 2.2.0__tar.gz → 2.2.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 (197) hide show
  1. {fpstreams-2.2.0 → fpstreams-2.2.1}/CHANGELOG.md +16 -0
  2. {fpstreams-2.2.0 → fpstreams-2.2.1}/PKG-INFO +11 -1
  3. {fpstreams-2.2.0 → fpstreams-2.2.1}/README.md +10 -0
  4. {fpstreams-2.2.0 → fpstreams-2.2.1}/pyproject.toml +1 -1
  5. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/Cargo.lock +1 -1
  6. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/Cargo.toml +1 -1
  7. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/__init__.py +3 -2
  8. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/native.py +75 -35
  9. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/streams/flow.py +14 -12
  10. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/__init__.py +3 -1
  11. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/factory.py +5 -13
  12. {fpstreams-2.2.0 → fpstreams-2.2.1}/LICENSE +0 -0
  13. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/build.rs +0 -0
  14. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/common.rs +0 -0
  15. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/float/affine_pair.rs +0 -0
  16. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/float/endpoints.rs +0 -0
  17. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/float.rs +0 -0
  18. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/integer/endpoints.rs +0 -0
  19. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/integer.rs +0 -0
  20. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/lib.rs +0 -0
  21. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/numeric_mean.rs +0 -0
  22. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/numpy_export.rs +0 -0
  23. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/numpy_group/buffer.rs +0 -0
  24. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/numpy_group.rs +0 -0
  25. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/pair/expr.rs +0 -0
  26. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/pair/prefix.rs +0 -0
  27. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/pair/row_filter.rs +0 -0
  28. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/pair/unique.rs +0 -0
  29. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/pair/value_filter.rs +0 -0
  30. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/pair/value_map.rs +0 -0
  31. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/pair.rs +0 -0
  32. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/pivot.rs +0 -0
  33. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/records.rs +0 -0
  34. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational/adapters/namedtuple.rs +0 -0
  35. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational/adapters.rs +0 -0
  36. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational/global_numeric.rs +0 -0
  37. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational/group_numeric.rs +0 -0
  38. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational/group_pair_expr.rs +0 -0
  39. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational/join_callable/many.rs +0 -0
  40. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational/join_callable/unique.rs +0 -0
  41. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational/join_callable.rs +0 -0
  42. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational/join_exact.rs +0 -0
  43. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational/join_i64.rs +0 -0
  44. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational.rs +0 -0
  45. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational_fixed/composite.rs +0 -0
  46. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational_fixed/global_multi/same_field.rs +0 -0
  47. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational_fixed/global_multi.rs +0 -0
  48. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational_fixed/group_multi.rs +0 -0
  49. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational_fixed/single.rs +0 -0
  50. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/relational_fixed.rs +0 -0
  51. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/scalar_sort.rs +0 -0
  52. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/scalar_unique.rs +0 -0
  53. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/select.rs +0 -0
  54. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/adapters.rs +0 -0
  55. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/group_exact/pairs.rs +0 -0
  56. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/group_exact/rows.rs +0 -0
  57. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/group_exact.rs +0 -0
  58. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/group_fixed.rs +0 -0
  59. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/join_callable/behavior.rs +0 -0
  60. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/join_callable/direct.rs +0 -0
  61. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/join_callable.rs +0 -0
  62. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/join_exact.rs +0 -0
  63. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/numeric/buffers.rs +0 -0
  64. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/numeric/kernels.rs +0 -0
  65. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/numeric/reductions.rs +0 -0
  66. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/numeric.rs +0 -0
  67. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests/numpy_group.rs +0 -0
  68. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/tests.rs +0 -0
  69. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/unnest.rs +0 -0
  70. {fpstreams-2.2.0 → fpstreams-2.2.1}/rust/src/unpivot.rs +0 -0
  71. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/_native.pyi +0 -0
  72. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/_provenance.py +0 -0
  73. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/aggregate.py +0 -0
  74. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/async_flow.py +0 -0
  75. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/collecting/__init__.py +0 -0
  76. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/collecting/_collector_base.py +0 -0
  77. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/collecting/aggregate_program.py +0 -0
  78. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/collecting/aggregation.py +0 -0
  79. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/collecting/collector.py +0 -0
  80. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/collecting/program.py +0 -0
  81. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/collecting/reducer.py +0 -0
  82. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/collecting/statistics.py +0 -0
  83. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/collectors.py +0 -0
  84. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/column.py +0 -0
  85. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/errors.py +0 -0
  86. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/exceptions.py +0 -0
  87. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/__init__.py +0 -0
  88. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/_pair_aggregate.py +0 -0
  89. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/_pair_dict.py +0 -0
  90. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/_pair_row_filter.py +0 -0
  91. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/_rows_fusion.py +0 -0
  92. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/_scalar_fusion.py +0 -0
  93. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/arrow.py +0 -0
  94. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/async_iterators.py +0 -0
  95. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/async_map.py +0 -0
  96. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/async_merge.py +0 -0
  97. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/async_ops.py +0 -0
  98. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/async_prefetch.py +0 -0
  99. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/async_queue.py +0 -0
  100. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/async_scheduler.py +0 -0
  101. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/async_timers.py +0 -0
  102. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/native.py +0 -0
  103. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/numpy_group.py +0 -0
  104. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/numpy_prefix.py +0 -0
  105. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/physical.py +0 -0
  106. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/relational/__init__.py +0 -0
  107. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/relational/arrow_global.py +0 -0
  108. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/relational/arrow_group.py +0 -0
  109. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/relational/arrow_group_rows.py +0 -0
  110. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/relational/join.py +0 -0
  111. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/sorted_streams.py +0 -0
  112. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/sorting.py +0 -0
  113. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/sync.py +0 -0
  114. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/execution/sync_ops.py +0 -0
  115. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/expr.py +0 -0
  116. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/expressions/__init__.py +0 -0
  117. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/expressions/_codegen.py +0 -0
  118. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/expressions/_row_codegen.py +0 -0
  119. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/expressions/program.py +0 -0
  120. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/expressions/row.py +0 -0
  121. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/expressions/row_eval.py +0 -0
  122. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/expressions/row_ir.py +0 -0
  123. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/expressions/scalar.py +0 -0
  124. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/expressions/selectors.py +0 -0
  125. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/expressions/typed_ir.py +0 -0
  126. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/functional.py +0 -0
  127. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/gather.py +0 -0
  128. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/io_safety.py +0 -0
  129. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/option.py +0 -0
  130. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/physical/__init__.py +0 -0
  131. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/physical/async_plan.py +0 -0
  132. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/physical/compiled.py +0 -0
  133. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/physical/kernel_cache.py +0 -0
  134. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/physical/plan.py +0 -0
  135. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/physical/relational.py +0 -0
  136. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/__init__.py +0 -0
  137. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/_pair_stages.py +0 -0
  138. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/arrow.py +0 -0
  139. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/arrow_source.py +0 -0
  140. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/async_.py +0 -0
  141. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/async_utils.py +0 -0
  142. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/compiler.py +0 -0
  143. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/explain.py +0 -0
  144. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/gather.py +0 -0
  145. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/logical.py +0 -0
  146. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/numpy.py +0 -0
  147. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/pair_i64_expression.py +0 -0
  148. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/plan_cache.py +0 -0
  149. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/semantic_analyzer.py +0 -0
  150. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/semantic_rules.py +0 -0
  151. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/semantics.py +0 -0
  152. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/source.py +0 -0
  153. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/planning/sync.py +0 -0
  154. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/primitives/__init__.py +0 -0
  155. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/primitives/option.py +0 -0
  156. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/primitives/result.py +0 -0
  157. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/py.typed +0 -0
  158. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/result.py +0 -0
  159. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/runtime/__init__.py +0 -0
  160. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/runtime/_distinct.py +0 -0
  161. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/runtime/failpoints.py +0 -0
  162. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/runtime/files.py +0 -0
  163. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/runtime/iterators.py +0 -0
  164. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/runtime/limits.py +0 -0
  165. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/runtime/metrics.py +0 -0
  166. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/runtime/query.py +0 -0
  167. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/runtime/report.py +0 -0
  168. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/runtime/resources.py +0 -0
  169. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/runtime/spill.py +0 -0
  170. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/runtime/tasks.py +0 -0
  171. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/storage/__init__.py +0 -0
  172. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/storage/codec.py +0 -0
  173. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/storage/spill_store.py +0 -0
  174. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/streams/__init__.py +0 -0
  175. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/streams/_async_identity.py +0 -0
  176. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/streams/_flow_structural_list.py +0 -0
  177. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/streams/_flow_unique_list.py +0 -0
  178. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/streams/async_flow.py +0 -0
  179. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/streams/async_terminals.py +0 -0
  180. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/streams/flow_terminals.py +0 -0
  181. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/streams/pairs.py +0 -0
  182. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/_text_sources.py +0 -0
  183. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/arrow.py +0 -0
  184. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/dataframe.py +0 -0
  185. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/grouped.py +0 -0
  186. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/io.py +0 -0
  187. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/join.py +0 -0
  188. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/numpy.py +0 -0
  189. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/polars.py +0 -0
  190. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/records.py +0 -0
  191. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/rows.py +0 -0
  192. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/spill.py +0 -0
  193. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/spill_io.py +0 -0
  194. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/spill_limits.py +0 -0
  195. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/sql.py +0 -0
  196. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/tabular/sqlite_sink.py +0 -0
  197. {fpstreams-2.2.0 → fpstreams-2.2.1}/src/fpstreams/testing.py +0 -0
@@ -5,6 +5,22 @@ including changed defaults.
5
5
 
6
6
  ## Unreleased
7
7
 
8
+ ## 2.2.1 - 2026-10-07
9
+
10
+ ### Fixed
11
+
12
+ - Editors resolve the public `rows` factory directly, preserving method completion,
13
+ parameter hints, and docstrings instead of treating it as the record module.
14
+ - Core `flow()` and `rows()` factories retain iterable element types without optional
15
+ data adapters installed. A shared series protocol preserves one-dimensional series
16
+ typing without importing Polars into the core type declarations.
17
+
18
+ ### Changed
19
+
20
+ - Automatic planning skips NumPy buffer probes for exact list, tuple, and range
21
+ sources. Python identity terminal plans on exact containers also avoid a temporary
22
+ decision object, reducing the fixed cost of small workloads.
23
+
8
24
  ## 2.2.0 - 2026-10-06
9
25
 
10
26
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fpstreams
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: Programming Language :: Python :: 3.11
@@ -87,6 +87,16 @@ python -m pip install "fpstreams[data]" # NumPy, pandas, and PyArrow
87
87
  python -m pip install "fpstreams[polars]" # Polars and PyArrow
88
88
  ~~~
89
89
 
90
+ ## Editor support
91
+
92
+ fpstreams includes inline type annotations, docstrings, and the `py.typed` marker.
93
+ Select the Python interpreter where fpstreams is installed in your editor to get
94
+ method completions, parameter hints, and hover documentation.
95
+
96
+ Version 2.2.1 fixes `rows` factory completion and keeps core
97
+ iterable element types when optional data adapters are absent. For example,
98
+ `flow([1, 2, 3])` is inferred as `Flow[int]`.
99
+
90
100
  ## Quick start
91
101
 
92
102
  This example filters paid orders, groups them by region, and reports both the
@@ -32,6 +32,16 @@ python -m pip install "fpstreams[data]" # NumPy, pandas, and PyArrow
32
32
  python -m pip install "fpstreams[polars]" # Polars and PyArrow
33
33
  ~~~
34
34
 
35
+ ## Editor support
36
+
37
+ fpstreams includes inline type annotations, docstrings, and the `py.typed` marker.
38
+ Select the Python interpreter where fpstreams is installed in your editor to get
39
+ method completions, parameter hints, and hover documentation.
40
+
41
+ Version 2.2.1 fixes `rows` factory completion and keeps core
42
+ iterable element types when optional data adapters are absent. For example,
43
+ `flow([1, 2, 3])` is inferred as `Flow[int]`.
44
+
35
45
  ## Quick start
36
46
 
37
47
  This example filters paid orders, groups them by region, and reports both the
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "fpstreams"
7
- version = "2.2.0"
7
+ version = "2.2.1"
8
8
  description = "Lazy Python pipelines for iterables and records, with bounded async concurrency."
9
9
  readme = "README.md"
10
10
  authors = [
@@ -4,7 +4,7 @@ version = 4
4
4
 
5
5
  [[package]]
6
6
  name = "fpstreams-native"
7
- version = "2.2.0"
7
+ version = "2.2.1"
8
8
  dependencies = [
9
9
  "pyo3",
10
10
  "pyo3-build-config",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "fpstreams-native"
3
- version = "2.2.0"
3
+ version = "2.2.1"
4
4
  edition = "2024"
5
5
  rust-version = "1.85"
6
6
  description = "Native fused execution kernels for fpstreams."
@@ -39,9 +39,10 @@ from .streams import (
39
39
  flow,
40
40
  pairs,
41
41
  )
42
- from .tabular import Rows, SpillLimits, rows
42
+ from .tabular import Rows, SpillLimits
43
+ from .tabular.factory import rows as rows
43
44
 
44
- __version__ = "2.2.0"
45
+ __version__ = "2.2.1"
45
46
  Stream = Flow
46
47
  ParallelStream = Flow
47
48
 
@@ -44,6 +44,9 @@ _I64_MIN = -(2**63)
44
44
  _I64_MAX = 2**63 - 1
45
45
  _AUTO_THRESHOLD = 8
46
46
  _AUTO_IDENTITY_I64_SUM_THRESHOLD = 65_536
47
+ _AUTO_IDENTITY_CONTAINER_REASON = (
48
+ "identity list/tuple stays in Python below its direct native crossover"
49
+ )
47
50
  _COPY_SHORT_CIRCUIT_LIMIT = 1_024
48
51
  _COPY_SHORT_CIRCUIT_RATIO = 64
49
52
  _ALLOCATING_I64_MAP_ROOTS = frozenset({"add", "sub", "mul", "floordiv", "neg"})
@@ -108,61 +111,65 @@ def validate_terminal(terminal: str) -> TerminalName:
108
111
 
109
112
 
110
113
  def _terminal_metadata(
111
- decision: EngineDecision,
114
+ decision: EngineDecision | None,
112
115
  plan: Pipeline,
113
116
  terminal: TerminalName,
114
117
  *,
115
118
  source_is_container: bool | None = None,
119
+ python_reason: str = "",
116
120
  ) -> EngineDecision:
117
- """Attach worst-case data movement and complexity metadata to a terminal decision."""
121
+ """Attach terminal metadata, constructing a Python-only decision in one allocation."""
118
122
  source = plan.source.native_data
119
- crosses_native_boundary = decision.engine in {"native", "hybrid"}
123
+ engine = "python" if decision is None else decision.engine
124
+ program = None if decision is None else decision.program
125
+ crosses_native_boundary = engine in {"native", "hybrid"}
120
126
  if source_is_container is None:
121
127
  source_is_container = (
122
128
  isinstance(source, (list, tuple)) or _numpy_buffer_kind(source) is not None
123
129
  )
124
130
  metadata_count = terminal == "count" and exact_count(plan) is not None
125
131
  direct_i64_container_sum = (
126
- decision.engine == "native"
127
- and decision.program is not None
128
- and decision.program.kind == "i64"
129
- and not decision.program.stages
132
+ engine == "native"
133
+ and program is not None
134
+ and program.kind == "i64"
135
+ and not program.stages
130
136
  and type(source) in (list, tuple)
131
137
  and terminal == "sum"
132
138
  )
133
139
  direct_exact_container_mean = (
134
- decision.engine == "native"
135
- and decision.program is not None
136
- and not decision.program.stages
140
+ engine == "native"
141
+ and program is not None
142
+ and not program.stages
137
143
  and type(source) in (list, tuple)
138
144
  and terminal == "mean"
139
145
  and _exact_number_mean_available()
140
146
  )
141
147
  range_metadata = (
142
- decision.engine == "native"
148
+ engine == "native"
143
149
  and type(source) is range
144
150
  and not plan.operations
145
151
  and terminal in {"sum", "min", "max", "last"}
146
152
  )
147
153
  probe_path = (
148
- decision.engine == "native"
149
- and decision.program is not None
154
+ engine == "native"
155
+ and program is not None
150
156
  and type(source) in (list, tuple)
151
157
  and terminal in {"first", "any", "all"}
152
- and _container_probe_available(decision.program.kind)
158
+ and _container_probe_available(program.kind)
153
159
  )
160
+ decision_reason = python_reason if decision is None else decision.reason
154
161
  reason = (
155
- f"{decision.reason}; bounded probe; only undecided fallback bulk-copies"
162
+ f"{decision_reason}; bounded probe; only undecided fallback bulk-copies"
156
163
  if probe_path
157
- else f"{decision.reason}; retained range terminal uses constant-time metadata"
164
+ else f"{decision_reason}; retained range terminal uses constant-time metadata"
158
165
  if range_metadata
159
- else decision.reason
166
+ else decision_reason
160
167
  )
161
168
  return EngineDecision(
162
- decision.engine,
169
+ engine,
163
170
  reason,
164
- decision.program,
165
- decision.native_operation_count,
171
+ program,
172
+ 0 if decision is None else decision.native_operation_count,
166
173
  # An undecided bounded probe restarts the legacy bulk adapter, and numeric
167
174
  # buffer kernels may snapshot exporters before detached computation.
168
175
  scans_source=crosses_native_boundary and source_is_container and not metadata_count,
@@ -173,7 +180,7 @@ def _terminal_metadata(
173
180
  and not direct_i64_container_sum
174
181
  and not direct_exact_container_mean
175
182
  ),
176
- materializes=terminal == "list" or decision.engine == "hybrid",
183
+ materializes=terminal == "list" or engine == "hybrid",
177
184
  complexity=(
178
185
  "O(1)"
179
186
  if metadata_count or range_metadata
@@ -234,6 +241,9 @@ def _numpy_f64_buffer(source: object) -> Any | None:
234
241
 
235
242
  def _numpy_buffer_kind(source: object) -> NativeKind | None:
236
243
  """Return the exact native representation exposed by an explicit NumPy column."""
244
+ source_type = type(source)
245
+ if source_type is list or source_type is tuple or source_type is range:
246
+ return None
237
247
  if _numpy_i64_buffer(source) is not None:
238
248
  return "i64"
239
249
  if _numpy_f64_buffer(source) is not None:
@@ -783,6 +793,45 @@ def _buffer_short_circuit_decision(
783
793
  return None
784
794
 
785
795
 
796
+ def _identity_source_terminal_context(
797
+ plan: Pipeline,
798
+ terminal: TerminalName,
799
+ source: object,
800
+ ) -> tuple[EngineDecision | None, NativeKind | None, bool]:
801
+ """Choose exact-container routes before considering numeric buffer metadata."""
802
+ source_type = type(source)
803
+ if (
804
+ plan.engine == "auto"
805
+ and (source_type is list or source_type is tuple)
806
+ and terminal not in {"mean", "statistics"}
807
+ and not _auto_direct_i64_sum_candidate(source, terminal)
808
+ ):
809
+ return (
810
+ _terminal_metadata(
811
+ None,
812
+ plan,
813
+ terminal,
814
+ source_is_container=True,
815
+ python_reason=_AUTO_IDENTITY_CONTAINER_REASON,
816
+ ),
817
+ None,
818
+ True,
819
+ )
820
+ buffer_kind = _numpy_buffer_kind(source)
821
+ source_is_container = isinstance(source, (list, tuple)) or buffer_kind is not None
822
+ return (
823
+ _forced_native_exact_count_decision(
824
+ plan,
825
+ terminal,
826
+ source,
827
+ buffer_kind,
828
+ source_is_container=source_is_container,
829
+ ),
830
+ buffer_kind,
831
+ source_is_container,
832
+ )
833
+
834
+
786
835
  def _select_operation_terminal_engine(
787
836
  plan: Pipeline,
788
837
  terminal: TerminalName,
@@ -850,17 +899,11 @@ def select_terminal_engine(plan: Pipeline, terminal: TerminalName) -> EngineDeci
850
899
  source = plan.source.native_data
851
900
  if retained_one_shot := _retained_one_shot_decision(plan):
852
901
  return _terminal_metadata(retained_one_shot, plan, terminal)
853
- buffer_kind = _numpy_buffer_kind(source)
854
- source_is_container = isinstance(source, (list, tuple)) or buffer_kind is not None
855
- metadata_count = _forced_native_exact_count_decision(
856
- plan,
857
- terminal,
858
- source,
859
- buffer_kind,
860
- source_is_container=source_is_container,
902
+ source_decision, buffer_kind, source_is_container = _identity_source_terminal_context(
903
+ plan, terminal, source
861
904
  )
862
- if metadata_count is not None:
863
- return metadata_count
905
+ if source_decision is not None:
906
+ return source_decision
864
907
  if buffered := _buffer_short_circuit_decision(plan, terminal, buffer_kind):
865
908
  return _terminal_metadata(
866
909
  buffered,
@@ -875,10 +918,7 @@ def select_terminal_engine(plan: Pipeline, terminal: TerminalName) -> EngineDeci
875
918
  and not _auto_direct_i64_sum_candidate(source, terminal)
876
919
  ):
877
920
  return _terminal_metadata(
878
- EngineDecision(
879
- "python",
880
- "identity list/tuple stays in Python below its direct native crossover",
881
- ),
921
+ EngineDecision("python", _AUTO_IDENTITY_CONTAINER_REASON),
882
922
  plan,
883
923
  terminal,
884
924
  source_is_container=source_is_container,
@@ -10,7 +10,6 @@ from contextlib import contextmanager
10
10
  from dataclasses import dataclass
11
11
  from importlib import import_module
12
12
  from typing import (
13
- TYPE_CHECKING,
14
13
  Any,
15
14
  Generic,
16
15
  Literal,
@@ -22,9 +21,6 @@ from typing import (
22
21
 
23
22
  import fpstreams
24
23
 
25
- if TYPE_CHECKING:
26
- import polars as pl
27
-
28
24
  from ..expressions.selectors import Selector, compile_selector
29
25
  from ..planning.explain import PlanExplanation, explain_query
30
26
  from ..planning.gather import Gatherer
@@ -95,6 +91,17 @@ _MISSING = object()
95
91
  _TABULAR_MODULE_ROOTS = frozenset(("pandas", "polars", "pyarrow"))
96
92
 
97
93
 
94
+ class _SeriesSource(Protocol[T]):
95
+ """Describe a one-dimensional series without importing an optional adapter."""
96
+
97
+ @property
98
+ def shape(self) -> tuple[int]: ...
99
+
100
+ def __iter__(self) -> Iterator[T]: ...
101
+
102
+ def to_list(self) -> list[T]: ...
103
+
104
+
98
105
  class _ArrowCStreamProvider(Protocol):
99
106
  """Static shape of the Arrow PyCapsule stream protocol."""
100
107
 
@@ -1365,14 +1372,6 @@ class _FlowFactory:
1365
1372
  return self.from_dataframe(source)
1366
1373
  return None
1367
1374
 
1368
- if TYPE_CHECKING:
1369
-
1370
- @overload
1371
- def __call__(
1372
- self,
1373
- source: pl.Series,
1374
- ) -> Flow[Any]: ...
1375
-
1376
1375
  @overload
1377
1376
  def __call__(self, source: Flow[T]) -> Flow[T]: ...
1378
1377
 
@@ -1381,6 +1380,9 @@ class _FlowFactory:
1381
1380
  # before considering structural tabular protocols.
1382
1381
  def __call__(self, source: fpstreams.Rows[T]) -> Flow[T]: ... # type: ignore[overload-overlap]
1383
1382
 
1383
+ @overload
1384
+ def __call__(self, source: _SeriesSource[T]) -> Flow[T]: ...
1385
+
1384
1386
  @overload
1385
1387
  def __call__(
1386
1388
  self,
@@ -1,8 +1,10 @@
1
1
  """Record-oriented pipelines and tabular interoperability."""
2
2
 
3
- from .factory import rows
3
+ from .factory import rows as _rows_factory
4
4
  from .grouped import GroupedRows
5
5
  from .rows import Rows
6
6
  from .spill_limits import SpillLimits
7
7
 
8
+ rows = _rows_factory
9
+
8
10
  __all__ = ["GroupedRows", "Rows", "SpillLimits", "rows"]
@@ -4,13 +4,10 @@ from __future__ import annotations
4
4
 
5
5
  import os
6
6
  from collections.abc import Callable, Iterable, Mapping
7
- from typing import TYPE_CHECKING, Any, BinaryIO, TextIO, TypeAlias, TypeVar, overload
8
-
9
- if TYPE_CHECKING:
10
- import polars as pl
7
+ from typing import Any, BinaryIO, TextIO, TypeAlias, TypeVar, overload
11
8
 
12
9
  from ..expressions.selectors import Selector
13
- from ..streams.flow import Flow, _ArrowCStreamProvider, _DataFrameProvider
10
+ from ..streams.flow import Flow, _ArrowCStreamProvider, _DataFrameProvider, _SeriesSource
14
11
  from .rows import Rows
15
12
  from .sql import (
16
13
  ConnectionFactory,
@@ -26,14 +23,6 @@ class _RowsFactory:
26
23
 
27
24
  __slots__ = ()
28
25
 
29
- if TYPE_CHECKING:
30
-
31
- @overload
32
- def __call__(
33
- self,
34
- source: pl.Series,
35
- ) -> Rows[Any]: ...
36
-
37
26
  @overload
38
27
  def __call__(self, source: Flow[T]) -> Rows[T]: ...
39
28
 
@@ -41,6 +30,9 @@ class _RowsFactory:
41
30
  # Rows also exports Arrow, but the compatibility factory must preserve its record type.
42
31
  def __call__(self, source: Rows[T]) -> Rows[T]: ... # type: ignore[overload-overlap]
43
32
 
33
+ @overload
34
+ def __call__(self, source: _SeriesSource[T]) -> Rows[T]: ...
35
+
44
36
  @overload
45
37
  def __call__(
46
38
  self,
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes