Fix spurious printing of forecast/scores objects during :=#1163
Fix spurious printing of forecast/scores objects during :=#1163nikosbosse wants to merge 2 commits into
Conversation
Leverage data.table's shouldPrint() mechanism to suppress autoprinting when := modifies forecast or scores objects in place. Also skip validation in [.forecast during := operations since the validation was triggering the autoprint side-effect. Key changes: - print.forecast: check shouldPrint() early and return invisible if FALSE - print.scores: new method with same shouldPrint() check - [.forecast: detect in-place := modifications and skip validation - Bump data.table dependency to >= 1.17.0 (contains upstream fix) Closes #1161 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1163 +/- ##
=======================================
Coverage 97.98% 97.99%
=======================================
Files 37 37
Lines 1984 1992 +8
=======================================
+ Hits 1944 1952 +8
Misses 40 40 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
CLAUDE (and verified by Nikos): Here's a before/after comparison showing the fix in action: Before (main): ex <- data.table::copy(example_quantile)
ex[, model := paste(model, "a")]
#> Forecast type: quantile
#> Forecast unit:
#> location, target_end_date, target_type, location_name, forecast_date, model,
#> and horizon
#>
#> Key: <location, target_end_date, target_type>
#> location target_end_date target_type observed location_name
#> <char> <Date> <char> <num> <char>
#> 1: DE 2021-01-02 Cases 127300 Germany
#> 2: DE 2021-01-02 Deaths 4534 Germany
#> 3: DE 2021-01-09 Cases 154922 Germany
#> 4: DE 2021-01-09 Deaths 6117 Germany
#> 5: DE 2021-01-16 Cases 110183 Germany
#> ---
#> 20541: IT 2021-07-24 Deaths 78 Italy
#> 20542: IT 2021-07-24 Deaths 78 Italy
#> 20543: IT 2021-07-24 Deaths 78 Italy
#> 20544: IT 2021-07-24 Deaths 78 Italy
#> 20545: IT 2021-07-24 Deaths 78 Italy
#> ... (full table unexpectedly printed)The entire 20,545-row forecast object is printed every time a column is modified via After (fix branch): ex <- data.table::copy(example_quantile)
ex[, model := paste(model, "a")]
# (no output — matches the behavior of := on a plain data.table)
print(ex) # explicit print still works as expected
#> Forecast type: quantile
#> Forecast unit:
#> location, target_end_date, target_type, location_name, forecast_date, model,
#> and horizon
#>
#> location target_end_date target_type observed ...
#> 1: DE 2021-01-02 Cases 127300 ...
#> ---
#> 20541: IT 2021-07-24 Deaths 78 ...The same fix applies to |
Use expect_gt() instead of expect_true(x > 0) and fixed = TRUE for static regex patterns in grepl(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Let me know when ready for review. |
|
Ready for review! |
|
|
||
| # Detect in-place modification via `:=`. When `:=` is used, data.table | ||
| # modifies x in place so x and out are identical. We distinguish from x[] | ||
| # (force-print) by checking ...length(): x[] has ...length() == 1, while |
There was a problem hiding this comment.
Why is not validating in place modification in this PR?
seabbs
left a comment
There was a problem hiding this comment.
utils::getFromNamespace("shouldPrint",
this seems like all we need. I don't know why we have the validation turned off for := in this PR?
Does print.scores need to exist if it just next method itself into data.table?
I don't think we want to do this? |
CLAUDE:
Summary
forecastandscoresobjects print output every time a column is changed #935 by leveraging data.table'sshouldPrint()mechanism to suppress autoprinting when:=modifies forecast or scores objects in placeprint.scores()method with the same autoprint suppression[.forecastduring:=operations (the validation was consuming data.table's autoprint suppression flag and triggering the printing side-effect)>= 1.16.0to>= 1.17.0(which contains the upstream fix in Rdatatable/data.table#6631)See #1161 for detailed root cause analysis.
How it works
The fix has two layers:
print.forecast()andprint.scores(): Check data.table's internalshouldPrint(x)at the top of the method. When:=is used, data.table sets a flag to suppress autoprinting. If the flag indicates suppression, returninvisible(x)immediately without printing any output (including the forecast header).[.forecast(): Detect in-place modifications (:=) by checkingidentical(x, out) && ...length() > 1and skip validation. Previously, the validation call inside[.forecastwould consume theshouldPrintflag beforeprint.forecastcould check it.Breaking change
[.forecastno longer validates during:=operations. Users who relied on the warning when:=broke a forecast object's contract (e.g., changingpredictedto character) will need to callassert_forecast()explicitly. The$<-,[[<-, and[<-assignment methods still validate.Test plan
:=produces no output for all forecast types (binary, quantile, point, sample_continuous, sample_discrete):=on scores objects produces no output:=operations produce no outputprint()still works after:=x[]force-print still works[.forecastvalidates subsets regardless of size (30-row hack removed)🤖 Generated with Claude Code