Fix clone() to update parent references on cloned children#443
Merged
MaxGhenis merged 2 commits intoPolicyEngine:masterfrom Mar 10, 2026
Merged
Fix clone() to update parent references on cloned children#443MaxGhenis merged 2 commits intoPolicyEngine:masterfrom
MaxGhenis merged 2 commits intoPolicyEngine:masterfrom
Conversation
After cloning a ParameterNode, each child's `parent` still pointed to the original tree. This meant parameter.update() called clear_parent_cache() on the original parent, not the clone, leaving stale cached values in the cloned tree. This caused silent null returns for NJ reform calculations on the API, where clone() + parameter.update() is used instead of Reform.from_dict(). Fixes PolicyEngine#442 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
clear_parent_cache only cleared self._at_instant_cache inside the `if self.parent is not None` block, so root nodes (parent=None) never had their cache cleared. Move the clear() before the conditional so all nodes in the chain are invalidated. Confirmed: test_clone_update_invalidates_cloned_cache fails without this fix and passes with it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
30e2c4f to
d6d691b
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #443 +/- ##
==========================================
+ Coverage 82.51% 82.92% +0.40%
==========================================
Files 202 202
Lines 10634 10660 +26
Branches 1069 1071 +2
==========================================
+ Hits 8775 8840 +65
+ Misses 1583 1536 -47
- Partials 276 284 +8 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ParameterNode.clone()to setchild.parent = cloneafter cloning childrenParameterScale.clone()to setbracket.parent = cloneafter cloning bracketsAfter cloning, each child's
parentstill pointed to the original tree. This meantparameter.update()calledclear_parent_cache()on the original parent instead of the clone, leaving stale cached values in the cloned tree.This is the root cause of silent null returns for NJ reform calculations on the API, where
clone()+parameter.update()is used instead ofReform.from_dict().Fixes #442
Test plan
test_clone_parent_references— verifies cloned children reference the cloned parenttest_clone_scale_parent_references— verifies cloned scale brackets reference the cloned scaletest_clone_update_invalidates_cloned_cache— verifiesparameter.update()on a cloned tree invalidates the clone's cache (not the original's)🤖 Generated with Claude Code