Skip to content

Commit a1819e1

Browse files
committed
Merge branch 'master' into litedown
2 parents 4bacd15 + 9fe1b8d commit a1819e1

24 files changed

+140
-73
lines changed

.ci/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@ Test jobs:
1212
- `test-lin-rel-cran` - `--as-cran` on Linux, strict test for final status of `R CMD check`.
1313
- `test-lin-dev-gcc-strict-cran` - `--as-cran` on Linux, `r-devel` built with `-enable-strict-barrier --disable-long-double`, test for compilation warnings, test for new NOTEs/WARNINGs from `R CMD check`.
1414
- `test-lin-dev-clang-cran` - same as `gcc-strict` job but R built with `clang` and no `--enable-strict-barrier --disable-long-double` flags.
15-
- `test-lin-310-cran` - R 3.1.0 on Linux, stated R dependency version.
15+
- `test-lin-ancient-cran` - Stated R dependency version (currently 3.3.0) on Linux.
16+
- `test-lin-dev-san` - `r-devel` on Linux built with `clang -fsanitize=address,undefined` (including LeakSanitizer), test for sanitizer output in tests and examples.
1617
- `test-win-rel` - `r-release` on Windows.
1718
- `test-win-dev` - `r-devel` on Windows.
1819
- `test-win-old` - `r-oldrel` on Windows.
19-
- `test-mac-rel` - macOS build not yet available, see [#3326](https://github.com/Rdatatable/data.table/issues/3326) for status
20+
- `test-mac-rel` - `r-release` on macOS.
21+
- `test-mac-old` - `r-oldrel` on macOS.
22+
23+
The CI steps for the tests are [required](https://github.com/Rdatatable/data.table/blob/55eb0f160b169398d51f138131c14a66c86e5dc9/.ci/publish.R#L162-L168) to be named according to the pattern `test-(lin|win|mac)-<R version>[-<suffix>]*`, where `<R version>` is `rel`, `dev`, `old`, `ancient`, or three digits comprising an R version (e.g. `362` corresponding to R-3.6.2).
2024

2125
Tests jobs are allowed to fail, summary and logs of test jobs are later published at _CRAN-like checks_ page, see artifacts below.
2226

.dev/lsan.supp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
leak:libfontconfig.so

.gitlab-ci.yml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,24 @@ test-lin-ancient-cran:
212212
# Restore checking vignettes if upgrading our R dependency means knitr can be installed.
213213
- R CMD check --no-manual --no-build-vignettes --ignore-vignettes $(ls -1t data.table_*.tar.gz | head -n 1)
214214

215+
# run the main checks with Address(+Leak),UBSanitizer enabled
216+
test-lin-dev-san:
217+
<<: *test-lin
218+
image: registry.gitlab.com/rdatatable/dockerfiles/r-devel-clang-san
219+
variables:
220+
# must be set for most of the process because there are pseudo-leaks everywhere
221+
ASAN_OPTIONS: "detect_leaks=0"
222+
# fontconfig is known to leak; add more suppressions as discovered
223+
LSAN_OPTIONS: "suppressions=$CI_PROJECT_DIR/.dev/lsan.supp"
224+
UBSAN_OPTIONS: "print_stacktrace=1"
225+
script:
226+
- *install-deps
227+
- |
228+
res1=0; ASAN_OPTIONS=detect_leaks=1 R CMD check --no-manual $(ls -1t data.table_*.tar.gz | head -n 1) || res1=$?
229+
res2=0; perl -nle '(print, $a=1) if /: runtime error: |ERROR: LeakSanitizer/../SUMMARY.*Sanitizer/ }{ exit $a' data.table.Rcheck/**/*.Rout* || res2=$?
230+
# fail if R CMD check had failed or if sanitizer output found
231+
if [ $res1 -ne 0 ] || [ $res2 -ne 0 ]; then exit 1; fi
232+
215233
.test-win-template: &test-win
216234
<<: *test
217235
tags:
@@ -311,7 +329,7 @@ integration:
311329
- saas-linux-medium-amd64
312330
only:
313331
- master
314-
needs: ["mirror-packages","build","test-lin-rel","test-lin-rel-cran","test-lin-dev-gcc-strict-cran","test-lin-dev-clang-cran","test-lin-rel-vanilla","test-lin-ancient-cran","test-win-rel","test-win-dev" ,"test-win-old","test-mac-rel","test-mac-old"]
332+
needs: ["mirror-packages","build","test-lin-rel","test-lin-rel-cran","test-lin-dev-gcc-strict-cran","test-lin-dev-clang-cran","test-lin-rel-vanilla","test-lin-ancient-cran","test-lin-dev-san","test-win-rel","test-win-dev" ,"test-win-old","test-mac-rel","test-mac-old"]
315333
script:
316334
- R --version
317335
- *install-deps ## markdown pkg not present in r-pkgdown image

NEWS.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,23 @@
1212

1313
2. `fwrite(compress="gzip")` once again produces a gzip header when the column names are missing or disabled, [@6852](https://github.com/Rdatatable/data.table/issues/6852). Thanks @maxscheiber for the report and @aitap for the fix.
1414

15+
3. `fread(keepLeadingZeros=TRUE)` now correctly parses dates with components with leading zeros as dates instead of strings, [#6851](https://github.com/Rdatatable/data.table/issues/6851). Thanks @TurnaevEvgeny for the report and @ben-schwen for the fix.
16+
17+
4. `as.data.table()` now properly handles keys: specifying keys sets them, omitting keys preserves existing ones, and setting `key=NULL` clears them, [#6859](https://github.com/Rdatatable/data.table/issues/6859). Thanks @brookslogan for the report and @Mukulyadav2004 for the fix.
18+
19+
5. `as.data.table()` on `x` avoids an infinite loop if the output of the corresponding `as.data.frame()` method has the same class as the input, [#6874](https://github.com/Rdatatable/data.table/issues/6874). Concretely, we had `class(x) = c('foo', 'data.frame')` and `class(as.data.frame(x)) = c('foo', 'data.frame')`, so `as.data.frame.foo` wound up getting called repeatedly. Thanks @matschmitz for the report and @ben-schwen for the fix.
20+
1521
## NOTES
1622

1723
1. Continued work to remove non-API C functions, [#6180](https://github.com/Rdatatable/data.table/issues/6180). Thanks Ivan Krylov for the PRs and for writing a clear and concise guide about the R API: https://aitap.codeberg.page/R-api/.
1824

25+
2. The following in-progress deprecations have proceeded:
26+
27+
+ Argument `logicalAsInt` to `fwrite()` has been removed.
28+
+ Argument `autostart` to `fread()` has been removed.
29+
+ Argument `in.place` to `droplevels` has been removed.
30+
+ It's now an error to set `datatable.nomatch`, which has been warning since 1.15.0.
31+
1932
# data.table [v1.17.0](https://github.com/Rdatatable/data.table/milestone/34) (20 Feb 2025)
2033

2134
## POTENTIALLY BREAKING CHANGES

R/as.data.table.R

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,13 @@ as.data.table.list = function(x,
214214
}
215215

216216
as.data.table.data.frame = function(x, keep.rownames=FALSE, key=NULL, ...) {
217-
if (is.data.table(x)) return(as.data.table.data.table(x)) # S3 is weird, #6739. Also # nocov; this is tested in 2302.{2,3}, not sure why it doesn't show up in coverage.
218-
if (!identical(class(x), "data.frame")) return(as.data.table(as.data.frame(x)))
217+
if (is.data.table(x)) return(as.data.table.data.table(x, key=key)) # S3 is weird, #6739. Also # nocov; this is tested in 2302.{2,3}, not sure why it doesn't show up in coverage.
218+
if (!identical(class(x), "data.frame")) {
219+
class_orig = class(x)
220+
x = as.data.frame(x)
221+
if (identical(class(x), class_orig)) setattr(x, "class", "data.frame") # cater for cases when as.data.frame can generate a loop #6874
222+
return(as.data.table.data.frame(x, keep.rownames=keep.rownames, key=key, ...))
223+
}
219224
if (!isFALSE(keep.rownames)) {
220225
# can specify col name to keep.rownames, #575; if it's the same as key,
221226
# kludge it to 'rn' since we only apply the new name afterwards, #4468
@@ -228,7 +233,7 @@ as.data.table.data.frame = function(x, keep.rownames=FALSE, key=NULL, ...) {
228233
if (any(cols_with_dims(x))) {
229234
# a data.frame with a column that is data.frame needs to be expanded; test 2013.4
230235
# x may be a class with [[ method that behaves differently, so as.list first for default [[, #4526
231-
return(as.data.table.list(as.list(x), keep.rownames=keep.rownames, ...))
236+
return(as.data.table.list(as.list(x), keep.rownames=keep.rownames, key = key,...))
232237
}
233238
ans = copy(x) # TO DO: change this deep copy to be shallow.
234239
setattr(ans, "row.names", .set_row_names(nrow(x)))
@@ -245,13 +250,14 @@ as.data.table.data.frame = function(x, keep.rownames=FALSE, key=NULL, ...) {
245250
ans
246251
}
247252

248-
as.data.table.data.table = function(x, ...) {
253+
as.data.table.data.table = function(x, ..., key=NULL) {
249254
# as.data.table always returns a copy, automatically takes care of #473
250255
if (any(cols_with_dims(x))) { # for test 2089.2
251-
return(as.data.table.list(x, ...))
256+
return(as.data.table.list(x, key = key, ...))
252257
}
253258
x = copy(x) # #1681
254259
# fix for #1078 and #1128, see .resetclass() for explanation.
255260
setattr(x, 'class', .resetclass(x, "data.table"))
261+
if (!missing(key)) setkeyv(x, key)
256262
x
257263
}

R/data.table.R

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ replace_dot_alias = function(e) {
448448
if (is.data.frame(i)) {
449449
if (missing(on)) {
450450
if (!haskey(x)) {
451-
stopf("When i is a data.table (or character vector), the columns to join by must be specified using 'on=' argument (see ?data.table), by keying x (i.e. sorted, and, marked as sorted, see ?setkey), or by sharing column names between x and i (i.e., a natural join). Keyed joins might have further speed benefits on very large data due to x being sorted in RAM.")
451+
stopf("When i is a data.table (or character vector), the columns to join by must be specified using the 'on=' argument (see ?data.table); by keying x (i.e., x is sorted and marked as such, see ?setkey); or by using 'on = .NATURAL' to indicate using the shared column names between x and i (i.e., a natural join). Keyed joins might have further speed benefits on very large data due to x being sorted in RAM.")
452452
}
453453
} else if (identical(substitute(on), as.name(".NATURAL"))) {
454454
naturaljoin = TRUE
@@ -686,10 +686,7 @@ replace_dot_alias = function(e) {
686686
if (is.null(jsub)) return(NULL)
687687

688688
if (!with) {
689-
if (jsub %iscall% ":=") {
690-
# TODO(>=1.18.0): Simplify this error
691-
stopf("with=FALSE together with := was deprecated in v1.9.4 released Oct 2014; this has been warning since v1.15.0. Please wrap the LHS of := with parentheses; e.g., DT[,(myVar):=sum(b),by=a] to assign to column name(s) held in variable myVar. See ?':=' for other examples.")
692-
}
689+
if (jsub %iscall% ":=") stopf("`:=` is only supported under with=TRUE, see ?`:=`.")
693690
# missingby was already checked above before dealing with i
694691
if (jsub %iscall% c("!", "-") && length(jsub)==2L) { # length 2 to only match unary, #2109
695692
notj = TRUE

R/fdroplevels.R

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ fdroplevels = function(x, exclude = if (anyNA(levels(x))) NULL else NA, ...) {
88
ans
99
}
1010

11-
droplevels.data.table = function(x, except=NULL, exclude, in.place=NULL, ...){
12-
if (!is.null(in.place)) stopf("droplevels() with in.place=TRUE is deprecated. Use setdroplevels() instead.")
11+
droplevels.data.table = function(x, except=NULL, exclude, ...){
1312
x = copy(x)
1413
if (missing(exclude)) exclude = NULL
1514
setdroplevels(x, except, exclude)[]

R/fread.R

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ showProgress=getOption("datatable.showProgress",interactive()), data.table=getOp
77
nThread=getDTthreads(verbose), logical01=getOption("datatable.logical01",FALSE),
88
logicalYN=getOption("datatable.logicalYN", FALSE),
99
keepLeadingZeros=getOption("datatable.keepLeadingZeros",FALSE),
10-
yaml=FALSE, autostart=NULL, tmpdir=tempdir(), tz="UTC")
10+
yaml=FALSE, tmpdir=tempdir(), tz="UTC")
1111
{
1212
if (missing(input)+is.null(file)+is.null(text)+is.null(cmd) < 3L) stopf("Used more than one of the arguments input=, file=, text= and cmd=.")
1313
input_has_vars = length(all.vars(substitute(input)))>0L # see news for v1.11.6
@@ -124,7 +124,6 @@ yaml=FALSE, autostart=NULL, tmpdir=tempdir(), tz="UTC")
124124

125125
input = file
126126
}
127-
if (!is.null(autostart)) stopf("'autostart' is deprecated. Consider skip='string' or skip=n. This argument will be removed in the next release.");
128127
if (is.logical(colClasses)) {
129128
if (!allNA(colClasses)) stopf("colClasses is type 'logical' which is ok if all NA but it has some TRUE or FALSE values in it which is not allowed. Please consider the drop= or select= argument instead. See ?fread.")
130129
colClasses = NULL

R/fwrite.R

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ fwrite = function(x, file="", append=FALSE, quote="auto",
33
sep2=c("","|",""), eol=if (.Platform$OS.type=="windows") "\r\n" else "\n",
44
na="", dec=".", row.names=FALSE, col.names=TRUE,
55
qmethod=c("double","escape"),
6-
logical01=getOption("datatable.logical01", FALSE), # due to change to TRUE; see NEWS
7-
logicalAsInt=NULL,
6+
logical01=getOption("datatable.logical01", FALSE),
87
scipen=getOption('scipen', 0L),
98
dateTimeAs = c("ISO","squash","epoch","write.csv"),
109
buffMB=8L, nThread=getDTthreads(verbose),
@@ -23,9 +22,6 @@ fwrite = function(x, file="", append=FALSE, quote="auto",
2322
compress = match.arg(compress)
2423
dateTimeAs = match.arg(dateTimeAs)
2524
dateTimeAs = chmatch(dateTimeAs, c("ISO", "squash", "epoch", "write.csv")) - 1L
26-
if (!is.null(logicalAsInt)) {
27-
stopf("logicalAsInt has been renamed logical01 for consistency with fread.")
28-
}
2925
scipen = if (is.numeric(scipen)) as.integer(scipen) else 0L
3026
buffMB = as.integer(buffMB)
3127
nThread = as.integer(nThread)

R/onLoad.R

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
# nocov start
22

3-
.pkg.store = new.env()
4-
.pkg.store$.unsafe.done = FALSE
53
.unsafe.opt = function() {
6-
if (.pkg.store$.unsafe.done) return(invisible())
7-
val = getOption("datatable.nomatch")
8-
if (is.null(val)) return(invisible()) # not defined (it hasn't been defined in .onLoad since v1.12.4)
9-
warningf("Option 'datatable.nomatch' is defined but is now ignored. Please see note 11 in v1.12.4 NEWS (Oct 2019), and note 14 in v1.14.2.")
10-
# leave this as warning for a long time
11-
.pkg.store$.unsafe.done = TRUE
12-
invisible()
4+
if (!is.null(getOption("datatable.nomatch")))
5+
stopf("Option 'datatable.nomatch' is defined but is now ignored. Please see note 11 in v1.12.4 NEWS (Oct 2019), and note 14 in v1.14.2.")
136
}
147

158
.Last.updated = vector("integer", 1L) # exported variable; number of rows updated by the last := or set(), #1885

0 commit comments

Comments
 (0)