Skip to content

Commit f4121a0

Browse files
authored
Merge branch 'master' into issue1945
2 parents c98ba08 + 55eb0f1 commit f4121a0

22 files changed

+152
-110
lines changed

.ci/.lintr.R

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -71,45 +71,39 @@ linters = c(dt_linters, all_linters(
7171
))
7272
rm(dt_linters)
7373

74-
# TODO(lintr#2172): Glob with lintr itself.
75-
exclusions = c(local({
76-
exclusion_for_dir <- function(dir, exclusions) {
77-
files = file.path("..", list.files(dir, pattern = "\\.(R|Rmd|Rraw)$", full.names=TRUE))
78-
stats::setNames(rep(list(exclusions), length(files)), files)
79-
}
80-
c(
81-
exclusion_for_dir("tests", list(
82-
quotes_linter = Inf,
83-
# TODO(michaelchirico): Enforce these and re-activate them one-by-one.
84-
implicit_integer_linter = Inf,
85-
infix_spaces_linter = Inf,
86-
undesirable_function_linter = Inf
87-
)),
88-
exclusion_for_dir(c("vignettes", "vignettes/fr", "vignettes/ru"), list(
89-
# assignment_linter = Inf,
90-
implicit_integer_linter = Inf,
91-
quotes_linter = Inf,
92-
sample_int_linter = Inf
93-
# strings_as_factors_linter = Inf
94-
# system_time_linter = Inf
95-
)),
96-
exclusion_for_dir("inst/tests", list(
97-
library_call_linter = Inf,
98-
numeric_leading_zero_linter = Inf,
99-
undesirable_operator_linter = Inf, # For ':::', possibly we could be more careful to only exclude ':::'.
100-
# TODO(michaelchirico): Enforce these and re-activate them one-by-one.
101-
comparison_negation_linter = Inf,
102-
condition_call_linter = Inf,
103-
duplicate_argument_linter = Inf,
104-
equals_na_linter = Inf,
105-
missing_argument_linter = Inf,
106-
paste_linter = Inf,
107-
rep_len_linter = Inf,
108-
sample_int_linter = Inf,
109-
seq_linter = Inf,
110-
unnecessary_lambda_linter = Inf
111-
))
74+
exclusions = list(
75+
`../tests` = list(
76+
quotes_linter = Inf,
77+
# TODO(michaelchirico): Enforce these and re-activate them one-by-one.
78+
implicit_integer_linter = Inf,
79+
infix_spaces_linter = Inf,
80+
undesirable_function_linter = Inf
81+
),
82+
`../vignettes*` = list(
83+
# assignment_linter = Inf,
84+
implicit_integer_linter = Inf,
85+
quotes_linter = Inf,
86+
sample_int_linter = Inf
87+
# strings_as_factors_linter = Inf
88+
# system_time_linter = Inf
89+
),
90+
`../inst/tests` = list(
91+
library_call_linter = Inf,
92+
numeric_leading_zero_linter = Inf,
93+
undesirable_operator_linter = Inf, # For ':::', possibly we could be more careful to only exclude ':::'.
94+
# TODO(michaelchirico): Enforce these and re-activate them one-by-one.
95+
comparison_negation_linter = Inf,
96+
condition_call_linter = Inf,
97+
duplicate_argument_linter = Inf,
98+
equals_na_linter = Inf,
99+
missing_argument_linter = Inf,
100+
paste_linter = Inf,
101+
rep_len_linter = Inf,
102+
sample_int_linter = Inf,
103+
seq_linter = Inf,
104+
unnecessary_lambda_linter = Inf
105+
),
106+
`../inst/tests/froll.Rraw` = list(
107+
dt_test_literal_linter = Inf # TODO(michaelchirico): Fix these once #5898, #5692, #5682, #5576, #5575, #5441 are merged.
112108
)
113-
}),
114-
list(`../inst/tests/froll.Rraw` = list(dt_test_literal_linter = Inf)) # TODO(michaelchirico): Fix these once #5898, #5692, #5682, #5576, #5575, #5441 are merged.
115109
)

.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: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,21 @@
1010

1111
1. Custom binary operators from the `lubridate` package now work with objects of class `IDate` as with a `Date` subclass, [#6839](https://github.com/Rdatatable/data.table/issues/6839). Thanks @emallickhossain for the report and @aitap for the fix.
1212

13+
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.
14+
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+
## NOTES
18+
19+
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/.
20+
21+
2. The following in-progress deprecations have proceeded:
22+
23+
+ Argument `logicalAsInt` to `fwrite()` has been removed.
24+
+ Argument `autostart` to `fread()` has been removed.
25+
+ Argument `in.place` to `droplevels` has been removed.
26+
+ It's now an error to set `datatable.nomatch`, which has been warning since 1.15.0.
27+
1328
# data.table [v1.17.0](https://github.com/Rdatatable/data.table/milestone/34) (20 Feb 2025)
1429

1530
## POTENTIALLY BREAKING CHANGES

R/IDateTime.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ as.IDate.POSIXct = function(x, tz = attr(x, "tzone", exact=TRUE), ...) {
4040
if (is_utc(tz))
4141
(setattr(as.integer(as.numeric(x) %/% 86400L), "class", c("IDate", "Date"))) # %/% returns new object so can use setattr() on it; wrap with () to return visibly
4242
else
43-
as.IDate(as.Date(x, tz = if (is.null(tz)) '' else tz, ...))
43+
as.IDate(as.Date(x, tz = tz %||% '', ...))
4444
}
4545

4646
as.IDate.IDate = function(x, ...) x
@@ -147,7 +147,7 @@ as.ITime.default = function(x, ...) {
147147

148148
as.ITime.POSIXct = function(x, tz = attr(x, "tzone", exact=TRUE), ...) {
149149
if (is_utc(tz)) as.ITime(unclass(x), ...)
150-
else as.ITime(as.POSIXlt(x, tz = if (is.null(tz)) '' else tz, ...), ...)
150+
else as.ITime(as.POSIXlt(x, tz = tz %||% '', ...), ...)
151151
}
152152

153153
as.ITime.numeric = function(x, ms = 'truncate', ...) {

R/between.R

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ between = function(x, lower, upper, incbounds=TRUE, NAbounds=TRUE, check=FALSE)
1818
# POSIX check timezone match
1919
if (is.px(x) && is.px(lower) && is.px(upper)) {
2020
tzs = sapply(list(x,lower,upper), function(x) {
21-
tt = attr(x,"tzone",exact=TRUE)
22-
if (is.null(tt)) "" else tt
21+
attr(x, "tzone", exact=TRUE) %||% ""
2322
})
2423
# lower/upper should be more tightly linked than x/lower, so error
2524
# if the former don't match but only inform if they latter don't

R/data.table.R

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ replace_dot_alias = function(e) {
640640
# Doing this once here, helps speed later when repeatedly subsetting each column. R's [irows] would do this for each
641641
# column when irows contains negatives.
642642
}
643-
if (which) return( if (is.null(irows)) seq_len(nrow(x)) else irows )
643+
if (which) return(irows %||% seq_len(nrow(x)))
644644
} else { # missing(i)
645645
i = NULL
646646
}
@@ -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
@@ -757,7 +754,7 @@ replace_dot_alias = function(e) {
757754
if (".I" %in% bysubl) { #1732
758755
if (!is.symbol(bysub) && (length(bysubl)!=2L || !is.symbol(bysubl[[2L]]) || !(bysubl[[1L]] %chin% c(".","c","list"))))
759756
stopf("'by' contains .I but only the following are currently supported: by=.I, by=.(.I), by=c(.I), by=list(.I)")
760-
bysub = if (is.null(irows)) seq_len(nrow(x)) else irows
757+
bysub = irows %||% seq_len(nrow(x))
761758
bysuborig = as.symbol("I")
762759
}
763760
if (is.name(bysub) && !(bysub %chin% names_x)) { # TO DO: names(x),names(i),and i. and x. prefixes
@@ -1724,7 +1721,7 @@ replace_dot_alias = function(e) {
17241721
jl__ = as.list(jsubl[[i_]])[-1L] # just keep the '.' from list(.)
17251722
if (isTRUE(nzchar(names(jsubl)[i_]))) {
17261723
# Fix for #2311, prepend named list arguments of c() to that list's names. See tests 2283.*
1727-
njl__ = if (is.null(names(jl__))) rep("", length(jl__)) else names(jl__)
1724+
njl__ = names(jl__) %||% rep("", length(jl__))
17281725
njl__nonblank = nzchar(names(jl__))
17291726
if (length(jl__) > 1L) {
17301727
jn__ = paste0(names(jsubl)[i_], seq_along(jl__))
@@ -1733,7 +1730,7 @@ replace_dot_alias = function(e) {
17331730
}
17341731
jn__[njl__nonblank] = paste(names(jsubl)[i_], njl__[njl__nonblank], sep=".")
17351732
} else {
1736-
jn__ = if (is.null(names(jl__))) rep("", length(jl__)) else names(jl__)
1733+
jn__ = names(jl__) %||% rep("", length(jl__))
17371734
}
17381735
idx = unlist(lapply(jl__, function(x) is.name(x) && x == ".I"))
17391736
if (any(idx))
@@ -2164,7 +2161,7 @@ as.matrix.data.table = function(x, rownames=NULL, rownames.value=NULL, ...) {
21642161
# retain highest type of input for empty output, #4762
21652162
if (length(X)!=0L)
21662163
internal_error("length(X)==%d but a dimension is zero", length(X)) # nocov
2167-
return(array(if (is.null(X)) NA else X, dim = dm, dimnames = list(rownames.value, cn)))
2164+
return(array(X %||% NA, dim=dm, dimnames=list(rownames.value, cn)))
21682165
}
21692166
dim(X) = c(n, length(X)/n)
21702167
dimnames(X) = list(rownames.value, unlist(collabs, use.names = FALSE))

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/foverlaps.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
foverlaps = function(x, y, by.x=if (!is.null(key(x))) key(x) else key(y), by.y=key(y), maxgap=0L, minoverlap=1L, type=c("any", "within", "start", "end", "equal"), mult=c("all", "first", "last"), nomatch=NA, which=FALSE, verbose=getOption("datatable.verbose")) {
1+
foverlaps = function(x, y, by.x=key(x) %||% key(y), by.y=key(y), maxgap=0L, minoverlap=1L, type=c("any", "within", "start", "end", "equal"), mult=c("all", "first", "last"), nomatch=NA, which=FALSE, verbose=getOption("datatable.verbose")) {
22

33
if (!is.data.table(y) || !is.data.table(x)) stopf("y and x must both be data.tables. Use `setDT()` to convert list/data.frames to data.tables by reference or as.data.table() to convert to data.tables by copying.")
44
maxgap = as.integer(maxgap); minoverlap = as.integer(minoverlap)
@@ -78,7 +78,7 @@ foverlaps = function(x, y, by.x=if (!is.null(key(x))) key(x) else key(y), by.y=k
7878
stopf("Some interval cols are of type POSIXct while others are not. Please ensure all interval cols are (or are not) of POSIXct type")
7979
}
8080
# #1143, mismatched timezone
81-
getTZ = function(x) if (is.null(tz <- attr(x, "tzone", exact=TRUE))) "" else tz # "" == NULL AFAICT
81+
getTZ = function(x) attr(x, "tzone", exact=TRUE) %||% "" # "" == NULL AFAICT
8282
tzone_chk = c(getTZ(xval1), getTZ(xval2), getTZ(yval1), getTZ(yval2))
8383
if (length(unique(tzone_chk)) > 1L) {
8484
warningf("POSIXct interval cols have mixed timezones. Overlaps are performed on the internal numerical representation of POSIXct objects (always in UTC epoch time), therefore printed values may give the impression that values don't overlap but their internal representations do Please ensure that POSIXct type interval cols have identical 'tzone' attributes to avoid confusion.")

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

0 commit comments

Comments
 (0)