diff --git a/NEWS.md b/NEWS.md index 5505c4cbc..7ec502902 100644 --- a/NEWS.md +++ b/NEWS.md @@ -14,6 +14,8 @@ # 2: ``` +2. `cedta()` now returns `FALSE` if `.datatable.aware = FALSE` is set in the calling environment, [#5654](https://github.com/Rdatatable/data.table/issues/5654). + ## NOTES 1. `transform` method for data.table sped up substantially when creating new columns on large tables. Thanks to @OfekShilon for the report and PR. The implemented solution was proposed by @ColeMiller1. diff --git a/R/cedta.R b/R/cedta.R index 51dc0e9dd..c5b32e740 100644 --- a/R/cedta.R +++ b/R/cedta.R @@ -22,6 +22,10 @@ cedta.pkgEvalsUserCode = c("gWidgetsWWW","statET","FastRWeb","slidify","rmarkdow # package authors could set it using assignInNamespace and then not revert its value properly which would # cause subsequent calls from other packages to fail. +# .datatable.aware = TRUE or .datatable.aware = FALSE can also be set directly in the calling frame, +# e.g. at the start of a particular function to make it data.table-aware in an otherwise unaware package +# or vice versa. + # nocov start: very hard to reach this within our test suite -- the call stack within a call generated by e.g. knitr # for loop, not any(vapply_1b(.)), to allow early exit .any_eval_calls_in_stack <- function() { @@ -39,8 +43,8 @@ cedta.pkgEvalsUserCode = c("gWidgetsWWW","statET","FastRWeb","slidify","rmarkdow cedta = function(n=2L) { # Calling Environment Data Table Aware env = parent.frame(n) - if (isTRUE(env$.datatable.aware)) { # dtplyr 184 - return(TRUE) + if (isTRUEorFALSE(env$.datatable.aware)) { # dtplyr#184, #5654 + return(env$.datatable.aware) } ns = topenv(env) if (!isNamespace(ns)) { diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index a5a7708bc..7e64bdc1a 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -18268,3 +18268,13 @@ test(2244.2, DT[, let(a=1, )], error="let.*Did you forget a trailing comma\\?") test(2244.3, DT[, `:=`(a=1, , b=2)], error="`:=`.*\\[2\\]") test(2244.4, DT[, let(a=1, , b=2)], error="let.*\\[2\\]") test(2244.5, DT[, `:=`(a=1, , b=2, )], error="[2, 4]") + +# allow specifying datatable-unaware behavior, #5654 / #5655 +dt = data.table(foo = 1:3, bar = 4:6) +.datatable.aware = TRUE +test(2245.1, dt[1], data.table(foo = 1L, bar = 4L)) # Single index should be interpreted as row +.datatable.aware = FALSE +# selfrefok() fails on unaware-indexed datatables; the copy() here sidesteps that issue. +test(2245.2, copy(dt[1]), data.table(foo = 1:3)) # Revert to data.frame syntax: Interpret index as column +rm(.datatable.aware) +test(2245.3, dt[1], data.table(foo = 1L, bar = 4L)) # Default in this environment should be datatable-aware