Skip to content

Commit 659c849

Browse files
committed
Phase 13.9.Fix1b: Fix ROOT path serialization for registered_functions
Previous commit (189b768) only fixed JSON path (export_schema_v2/apply_schema). ROOT path (_serialize_schema/_deserialize_schema) was missing registered_functions. Fixed: _serialize_schema, _deserialize_schema, _restore_schema, read_tree. Added export_tree/read_tree roundtrip invariance test that catches this. Code duplication between JSON and ROOT serialization paths identified as technical debt — both should use single serialize/deserialize. 9 tests (was 8), 1440 passed, 6 failed (pre-existing).
1 parent 189b768 commit 659c849

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

UTILS/dfextensions/AliasDataFrame/AliasDataFrame.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@ def _serialize_schema(schema):
354354
serialized_spec[key] = value
355355
result["columns"][name] = serialized_spec
356356

357+
# Phase 13.9.Fix1: Include registered_functions if present
358+
if "registered_functions" in schema:
359+
result["registered_functions"] = schema["registered_functions"]
360+
357361
return result
358362

359363

@@ -434,6 +438,10 @@ def _deserialize_schema(serialized):
434438
deserialized_spec[key] = value
435439
result["columns"][name] = deserialized_spec
436440

441+
# Phase 13.9.Fix1: Restore registered_functions if present
442+
if "registered_functions" in serialized:
443+
result["registered_functions"] = serialized["registered_functions"]
444+
437445
return result
438446

439447

@@ -1285,6 +1293,12 @@ def _restore_schema(self, serialized_schema):
12851293

12861294
# Restore subframes metadata (not actual subframe objects)
12871295
self._schema["subframes"] = serialized_schema.get("subframes", {})
1296+
1297+
# Phase 13.9.Fix1: Restore registered_functions schema
1298+
# NOTE: Reconstruction is deferred — subframes must be loaded first.
1299+
# Call _reconstruct_registered_functions() after subframes are registered.
1300+
if "registered_functions" in serialized_schema:
1301+
self._schema["registered_functions"] = serialized_schema["registered_functions"]
12881302

12891303
def update_schema(self, update, validate=True, apply=True, errors="raise"):
12901304
"""
@@ -5182,6 +5196,10 @@ def read_branch(branch_name):
51825196
f"Failed to load subframe '{sf_name}' from {filename}: {e}"
51835197
) from e
51845198

5199+
# Phase 13.9.Fix1: Reconstruct registered functions after subframes loaded
5200+
if adf._schema.get('registered_functions'):
5201+
adf._reconstruct_registered_functions()
5202+
51855203
return adf
51865204

51875205
# =========================================================================

UTILS/dfextensions/AliasDataFrame/tests/test_polynomial_persistence.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,42 @@ def test_invariance_before_after_schema_roundtrip(self, adf_with_polynomial, tmp
179179

180180
np.testing.assert_allclose(before, after, atol=1e-10,
181181
err_msg="Polynomial values differ after schema roundtrip")
182+
183+
@pytest.mark.invariance
184+
def test_invariance_export_tree_read_tree_roundtrip(self, adf_with_polynomial, tmp_path):
185+
"""Full chain: register polynomial → export_tree → read_tree → polynomial works."""
186+
adf, _, _ = adf_with_polynomial
187+
188+
# Materialize and get reference values
189+
adf.materialize_alias('correction')
190+
before = adf.df['correction'].values.copy()
191+
192+
# Verify schema has registered_functions before export
193+
assert 'poly' in adf._schema.get('registered_functions', {}), \
194+
"registered_functions missing from schema before export"
195+
196+
# Export to ROOT file
197+
root_path = str(tmp_path / 'test_poly_persistence.root')
198+
adf.export_tree(root_path)
199+
200+
# Read back — polynomials should auto-reconstruct
201+
adf2 = AliasDataFrame.read_tree(root_path)
202+
203+
# Verify schema was restored
204+
assert 'registered_functions' in adf2._schema, \
205+
"registered_functions missing from schema after read_tree"
206+
assert 'poly' in adf2._schema['registered_functions'], \
207+
"poly not in registered_functions after read_tree"
208+
209+
# Verify function was reconstructed
210+
assert hasattr(adf2, '_registered_functions'), \
211+
"_registered_functions attribute missing after read_tree"
212+
assert 'poly' in adf2._registered_functions, \
213+
"poly not reconstructed in _registered_functions after read_tree"
214+
215+
# Verify alias works — materialize and compare
216+
adf2.materialize_alias('correction')
217+
after = adf2.df['correction'].values.copy()
218+
219+
np.testing.assert_allclose(before, after, atol=1e-10,
220+
err_msg="Polynomial values differ after export_tree/read_tree roundtrip")

0 commit comments

Comments
 (0)