splitgrid 0.1.1__tar.gz → 0.1.2__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 (24) hide show
  1. {splitgrid-0.1.1 → splitgrid-0.1.2}/Makefile +14 -1
  2. {splitgrid-0.1.1/src/splitgrid.egg-info → splitgrid-0.1.2}/PKG-INFO +17 -1
  3. {splitgrid-0.1.1 → splitgrid-0.1.2}/README.md +16 -0
  4. {splitgrid-0.1.1 → splitgrid-0.1.2}/pyproject.toml +1 -1
  5. {splitgrid-0.1.1 → splitgrid-0.1.2}/src/splitgrid/__init__.py +1 -1
  6. {splitgrid-0.1.1 → splitgrid-0.1.2}/src/splitgrid/codec.py +14 -1
  7. {splitgrid-0.1.1 → splitgrid-0.1.2/src/splitgrid.egg-info}/PKG-INFO +17 -1
  8. {splitgrid-0.1.1 → splitgrid-0.1.2}/tests/test_payload_codec.py +39 -0
  9. {splitgrid-0.1.1 → splitgrid-0.1.2}/LICENSE +0 -0
  10. {splitgrid-0.1.1 → splitgrid-0.1.2}/MANIFEST.in +0 -0
  11. {splitgrid-0.1.1 → splitgrid-0.1.2}/setup.cfg +0 -0
  12. {splitgrid-0.1.1 → splitgrid-0.1.2}/setup.py +0 -0
  13. {splitgrid-0.1.1 → splitgrid-0.1.2}/src/splitgrid/deal_shim.py +0 -0
  14. {splitgrid-0.1.1 → splitgrid-0.1.2}/src/splitgrid/pack.c +0 -0
  15. {splitgrid-0.1.1 → splitgrid-0.1.2}/src/splitgrid/pack.pyx +0 -0
  16. {splitgrid-0.1.1 → splitgrid-0.1.2}/src/splitgrid.egg-info/SOURCES.txt +0 -0
  17. {splitgrid-0.1.1 → splitgrid-0.1.2}/src/splitgrid.egg-info/dependency_links.txt +0 -0
  18. {splitgrid-0.1.1 → splitgrid-0.1.2}/src/splitgrid.egg-info/requires.txt +0 -0
  19. {splitgrid-0.1.1 → splitgrid-0.1.2}/src/splitgrid.egg-info/top_level.txt +0 -0
  20. {splitgrid-0.1.1 → splitgrid-0.1.2}/tests/test_cython_parity.py +0 -0
  21. {splitgrid-0.1.1 → splitgrid-0.1.2}/tests/test_payload_codec_policy_verification.py +0 -0
  22. {splitgrid-0.1.1 → splitgrid-0.1.2}/tests/test_serialization_ab.py +0 -0
  23. {splitgrid-0.1.1 → splitgrid-0.1.2}/tests/test_serialization_ab_support.py +0 -0
  24. {splitgrid-0.1.1 → splitgrid-0.1.2}/tests/test_serialization_verification.py +0 -0
@@ -1,6 +1,6 @@
1
1
  # SplitGrid
2
2
 
3
- .PHONY: test test-all test-slow verify install-test
3
+ .PHONY: test test-all test-slow verify install-test bench bench-child profile-pack
4
4
 
5
5
  # Prefer a local venv so `make test` / `make verify` work without activating it.
6
6
  PYTEST := $(if $(wildcard .venv/bin/pytest),.venv/bin/pytest,python3 -m pytest)
@@ -22,3 +22,16 @@ test-slow:
22
22
  # deal contracts + hypothesis round-trips (excludes CrossHair subprocess).
23
23
  verify:
24
24
  $(PYTEST) tests/test_serialization_verification.py tests/test_payload_codec_policy_verification.py -m "not slow" -q
25
+
26
+ PYTHON := $(if $(wildcard .venv/bin/python),.venv/bin/python,python3)
27
+
28
+ # Asymmetric host/child serialization bench (needs numpy).
29
+ bench:
30
+ $(PYTHON) scripts/bench_serialization.py --direction both
31
+
32
+ bench-child:
33
+ $(PYTHON) scripts/bench_serialization.py --child-only
34
+
35
+ profile-pack:
36
+ $(PYTHON) scripts/profile_pack.py
37
+ $(PYTHON) scripts/profile_nones.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: splitgrid
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Asymmetric split-grid serialization: host stdlib flatten + optional Cython, child NumPy unpack
5
5
  Author-email: Keith Cu <keithcu@gmail.com>
6
6
  License: GPL-3.0-or-later
@@ -35,6 +35,8 @@ Dynamic: license-file
35
35
 
36
36
  # SplitGrid
37
37
 
38
+ [![PyPI](https://img.shields.io/pypi/v/splitgrid.svg)](https://pypi.org/project/splitgrid/)
39
+
38
40
  Asymmetric **split-grid** serialization for rectangular numeric and mixed-type grids.
39
41
 
40
42
  This package was **pulled out of [WriterAgent](https://github.com/KeithCu/writeragent)** (LibreOffice Writer/Calc/Draw AI extension). It is the host flatten + child unpack codec that lived in `plugin.scripting.payload_codec`, plus the optional Cython flatten accelerator from `native/writeragent_vec`.
@@ -137,6 +139,20 @@ make verify # deal contracts + hypothesis round-trips, no CrossHair
137
139
 
138
140
  Default pytest **does not require** the compiled extension. When `splitgrid.pack` is built, `tests/test_cython_parity.py` compares Cython and Python flatten components on the same grids.
139
141
 
142
+ ## Bench
143
+
144
+ Requires NumPy (and the optional Cython extension if you want the accelerated pack row). From a source checkout:
145
+
146
+ ```bash
147
+ python scripts/bench_serialization.py --direction both
148
+ python scripts/bench_serialization.py --child-only
149
+ python scripts/bench_unpacking_opt.py
150
+ python scripts/profile_pack.py
151
+ python scripts/profile_nones.py
152
+ python scripts/run_serialization_ab.py --all
153
+ make bench
154
+ ```
155
+
140
156
  ## Public API
141
157
 
142
158
  ```python
@@ -1,5 +1,7 @@
1
1
  # SplitGrid
2
2
 
3
+ [![PyPI](https://img.shields.io/pypi/v/splitgrid.svg)](https://pypi.org/project/splitgrid/)
4
+
3
5
  Asymmetric **split-grid** serialization for rectangular numeric and mixed-type grids.
4
6
 
5
7
  This package was **pulled out of [WriterAgent](https://github.com/KeithCu/writeragent)** (LibreOffice Writer/Calc/Draw AI extension). It is the host flatten + child unpack codec that lived in `plugin.scripting.payload_codec`, plus the optional Cython flatten accelerator from `native/writeragent_vec`.
@@ -102,6 +104,20 @@ make verify # deal contracts + hypothesis round-trips, no CrossHair
102
104
 
103
105
  Default pytest **does not require** the compiled extension. When `splitgrid.pack` is built, `tests/test_cython_parity.py` compares Cython and Python flatten components on the same grids.
104
106
 
107
+ ## Bench
108
+
109
+ Requires NumPy (and the optional Cython extension if you want the accelerated pack row). From a source checkout:
110
+
111
+ ```bash
112
+ python scripts/bench_serialization.py --direction both
113
+ python scripts/bench_serialization.py --child-only
114
+ python scripts/bench_unpacking_opt.py
115
+ python scripts/profile_pack.py
116
+ python scripts/profile_nones.py
117
+ python scripts/run_serialization_ab.py --all
118
+ make bench
119
+ ```
120
+
105
121
  ## Public API
106
122
 
107
123
  ```python
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "splitgrid"
7
- version = "0.1.1"
7
+ version = "0.1.2"
8
8
  description = "Asymmetric split-grid serialization: host stdlib flatten + optional Cython, child NumPy unpack"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -55,7 +55,7 @@ from splitgrid.codec import (
55
55
  wire_cell_count,
56
56
  )
57
57
 
58
- __version__ = "0.1.1"
58
+ __version__ = "0.1.2"
59
59
 
60
60
 
61
61
  def __getattr__(name: str):
@@ -813,6 +813,10 @@ def _flatten_update_column_state(column_states: list[int], c: int, val: Any) ->
813
813
  column_states[c] = 2
814
814
  elif tname.startswith("float"):
815
815
  column_states[c] = 3
816
+ else:
817
+ # Decimal/Fraction/etc. already survived float(val). Default to float,
818
+ # matching Cython _update_column_state — not int (state 0).
819
+ column_states[c] = 3
816
820
 
817
821
 
818
822
  def _flatten_append_cell_slow(
@@ -1421,7 +1425,16 @@ def _child_unpack_single_data(wire: Any) -> Any:
1421
1425
  else:
1422
1426
  grid = list(unpacked)
1423
1427
  if is_numeric_grid(grid):
1424
- arr = np.array(grid, dtype=np.float64)
1428
+ # is_numeric_coercible treats whitespace/"" as Calc blanks, but
1429
+ # np.float64 cannot convert those strings (ValueError). Keep the list.
1430
+ try:
1431
+ arr = np.array(grid, dtype=np.float64)
1432
+ except ValueError:
1433
+ log.debug(
1434
+ "splitgrid child_unpack json_list as-is (non-floatable blanks) %s",
1435
+ describe_wire_value(unpacked),
1436
+ )
1437
+ return grid
1425
1438
  log.debug(
1426
1439
  "splitgrid child_unpack json_list -> ndarray shape=%s",
1427
1440
  arr.shape,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: splitgrid
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Asymmetric split-grid serialization: host stdlib flatten + optional Cython, child NumPy unpack
5
5
  Author-email: Keith Cu <keithcu@gmail.com>
6
6
  License: GPL-3.0-or-later
@@ -35,6 +35,8 @@ Dynamic: license-file
35
35
 
36
36
  # SplitGrid
37
37
 
38
+ [![PyPI](https://img.shields.io/pypi/v/splitgrid.svg)](https://pypi.org/project/splitgrid/)
39
+
38
40
  Asymmetric **split-grid** serialization for rectangular numeric and mixed-type grids.
39
41
 
40
42
  This package was **pulled out of [WriterAgent](https://github.com/KeithCu/writeragent)** (LibreOffice Writer/Calc/Draw AI extension). It is the host flatten + child unpack codec that lived in `plugin.scripting.payload_codec`, plus the optional Cython flatten accelerator from `native/writeragent_vec`.
@@ -137,6 +139,20 @@ make verify # deal contracts + hypothesis round-trips, no CrossHair
137
139
 
138
140
  Default pytest **does not require** the compiled extension. When `splitgrid.pack` is built, `tests/test_cython_parity.py` compares Cython and Python flatten components on the same grids.
139
141
 
142
+ ## Bench
143
+
144
+ Requires NumPy (and the optional Cython extension if you want the accelerated pack row). From a source checkout:
145
+
146
+ ```bash
147
+ python scripts/bench_serialization.py --direction both
148
+ python scripts/bench_serialization.py --child-only
149
+ python scripts/bench_unpacking_opt.py
150
+ python scripts/profile_pack.py
151
+ python scripts/profile_nones.py
152
+ python scripts/run_serialization_ab.py --all
153
+ make bench
154
+ ```
155
+
140
156
  ## Public API
141
157
 
142
158
  ```python
@@ -15,6 +15,7 @@ from __future__ import annotations
15
15
 
16
16
  import ast
17
17
  import math
18
+ from decimal import Decimal
18
19
  from pathlib import Path
19
20
  from unittest.mock import patch
20
21
 
@@ -41,6 +42,7 @@ from splitgrid.codec import (
41
42
  should_use_binary_envelope,
42
43
  wire_cell_count,
43
44
  )
45
+ from tests.serialization_ab_support import cython_accelerator_context
44
46
  from tests.payload_codec_test_support import (
45
47
  MIXED_LABEL_GRID,
46
48
  MIXED_WITH_ZIP,
@@ -512,6 +514,43 @@ def test_mixed_grid_preserves_non_numeric_string() -> None:
512
514
  assert out[0][1] == "hello"
513
515
 
514
516
 
517
+ def test_whitespace_only_cell_does_not_crash_child_unpack() -> None:
518
+ """Pasted ' ' is numeric-coercible for Calc but np.float64 cannot convert it."""
519
+ pytest.importorskip("numpy")
520
+ grid = [[1.0, " ", 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [9.0, 10.0, 11.0, 12.0]]
521
+ out = child_unpack_data(host_pack_data(grid, force="always"))
522
+ assert isinstance(out, list)
523
+ assert out[0][1] == " "
524
+
525
+
526
+ def test_empty_string_mixed_split_grid_does_not_crash_child_unpack() -> None:
527
+ """Bare '' on mixed split_grid must not raise (Calc usually maps '' to None first)."""
528
+ pytest.importorskip("numpy")
529
+ grid = [[1.0, "", 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [9.0, 10.0, 11.0, 12.0]]
530
+ out = child_unpack_data(host_pack_data(grid, force="always"))
531
+ assert isinstance(out, list)
532
+ assert out[0][1] == ""
533
+
534
+
535
+ def test_mixed_grid_real_nan_becomes_none_on_child() -> None:
536
+ """Documented: mixed-grid ingress has no blank-vs-NaN wire bit."""
537
+ pytest.importorskip("numpy")
538
+ grid = [[1.0, float("nan")], ["label", 4.0]]
539
+ out = child_unpack_data(host_pack_data(grid, force="always"))
540
+ assert out[0][1] is None
541
+ assert out[1][0] == "label"
542
+
543
+
544
+ def test_decimal_split_grid_stays_float_not_truncated_int() -> None:
545
+ """stdlib flatten must label Decimal columns float (Cython already did)."""
546
+ pytest.importorskip("numpy")
547
+ grid = [[Decimal("1.5"), Decimal("2.25")], [Decimal("3.0"), Decimal("4.75")]]
548
+ with cython_accelerator_context(enabled=False):
549
+ out = child_unpack_data(host_pack_data(grid, force="always"))
550
+ assert out[0][0] == pytest.approx(1.5)
551
+ assert out[0][1] == pytest.approx(2.25)
552
+
553
+
515
554
  def test_bool_cells_round_trip_in_numeric_grid() -> None:
516
555
  """Calc booleans in an all-numeric grid become 0.0/1.0 in child ndarray (float64 lane)."""
517
556
  np = pytest.importorskip("numpy")
File without changes
File without changes
File without changes
File without changes