-
Notifications
You must be signed in to change notification settings - Fork 421
Fix caching in ShapeBuilder. #1192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughRefactored the ShapeBuilder caching mechanism to use per-instance caches instead of mutable default parameters. Changed five methods to accept Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20–30 minutes
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
python/ShapeTools.py(5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
python/ShapeTools.py (1)
python/Datacard.py (1)
shape(242-250)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: LCG_108 - ROOT 6.36.02
- GitHub Check: CMSSW_14_1_0_pre4 - ROOT 6.30.07
- GitHub Check: CMSSW_14_0_0_pre1 - ROOT 6.26.11
- GitHub Check: dev3/latest - ROOT LCG master
- GitHub Check: LCG_102 - ROOT 6.26.04
- GitHub Check: LCG_106 - ROOT 6.32.02
- GitHub Check: CMSSW_11_3_4 - ROOT 6.22.09
- GitHub Check: Compile (py3.12, root6.34.4)
- GitHub Check: Compile (py3.10, root6.32.2)
- GitHub Check: Compile (py3.10, root6.26.4)
🔇 Additional comments (5)
python/ShapeTools.py (5)
74-77: LGTM! Per-instance caches correctly fix the mutable default argument anti-pattern.Initializing caches as instance attributes ensures proper isolation between
ShapeBuilderinstances, preventing the cross-contamination issue described in the PR.
662-664: LGTM! Correct cache initialization pattern.Using
Noneas the default and initializing to the instance cache avoids the mutable default argument issue while maintaining API flexibility.
855-857: LGTM! Consistent cache initialization pattern.
1216-1218: LGTM! Consistent cache initialization pattern.
1255-1257: LGTM! Consistent cache initialization pattern.
| def getData(self, channel, process, syst="", _cache=None): | ||
| return self.shape2Data(self.getShape(channel, process, syst), channel, process) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused _cache parameter in getData.
The _cache parameter is declared but never used in the method body. It's not passed to either getShape or shape2Data. This appears to be dead code.
Either remove the unused parameter or pass it to the delegated methods:
Option 1 - Remove unused parameter:
- def getData(self, channel, process, syst="", _cache=None):
+ def getData(self, channel, process, syst=""):
return self.shape2Data(self.getShape(channel, process, syst), channel, process)Option 2 - Pass cache to shape2Data (if caching control is intended):
def getData(self, channel, process, syst="", _cache=None):
- return self.shape2Data(self.getShape(channel, process, syst), channel, process)
+ return self.shape2Data(self.getShape(channel, process, syst), channel, process, _cache=_cache)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def getData(self, channel, process, syst="", _cache=None): | |
| return self.shape2Data(self.getShape(channel, process, syst), channel, process) | |
| def getData(self, channel, process, syst=""): | |
| return self.shape2Data(self.getShape(channel, process, syst), channel, process) |
🤖 Prompt for AI Agents
In python/ShapeTools.py around lines 852-853, the method getData declares an
unused _cache parameter; either remove _cache from the signature and update any
callers accordingly, or forward it to the delegated calls (pass _cache into
getShape and/or shape2Data as required by their signatures) so the cache is
actually used; pick the option consistent with existing caching design and
update call sites and docstring/comments to match.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1192 +/- ##
=======================================
Coverage 20.67% 20.67%
=======================================
Files 195 195
Lines 26173 26173
Branches 3927 3927
=======================================
Hits 5412 5412
Misses 20761 20761 🚀 New features to boost your workflow:
|
This PR fixes a dangerous anti-pattern in the ShapeBuilder.
getShape,getPdf,shape2Dataandshape2Pdfuse cache dictionaries that are initialized as keyword argument defaults. Mutable defaults are global singletons, resulting in the caches being involuntarily shared between instances (that don't even have to exist at the same time).This might have already caused issues in the HH tools where ShapeBuilder instances were used for datacard parsing.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.