Skip to content

Commit 5519b19

Browse files
committed
Merge branch 'master' into forder_segfault
2 parents 26cb165 + e25ea80 commit 5519b19

File tree

137 files changed

+19775
-5635
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

137 files changed

+19775
-5635
lines changed

.ci/.lintr.R

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ linters = c(dt_linters, all_linters(
99
packages = "lintr", # TODO(lintr->3.2.0): Remove this.
1010
# eq_assignment_linter(),
1111
brace_linter(allow_single_line = TRUE),
12+
implicit_integer_linter(allow_colon = TRUE),
1213
# TODO(michaelchirico): Activate these incrementally. These are the
1314
# parameterizations that match our style guide.
1415
# implicit_assignment_linter(allow_lazy = TRUE, allow_scoped = TRUE),
15-
# implicit_integer_linter(allow_colon = TRUE),
1616
# system_time_linter = undesirable_function_linter(c(
1717
# system.time = "Only run timings in benchmark.Rraw"
1818
# )),
@@ -26,7 +26,8 @@ linters = c(dt_linters, all_linters(
2626
# setwd = NULL
2727
# )),
2828
undesirable_operator_linter(),
29-
# TODO(lintr#2441): Use upstream implementation.
29+
# TODO(lintr#2765): Use upstream implementation.
30+
# assignment_linter(operator = "="),
3031
assignment_linter = NULL,
3132
absolute_path_linter = NULL, # too many false positives
3233
# TODO(lintr#2442): Use this once x[ , j, by] is supported.
@@ -70,43 +71,39 @@ linters = c(dt_linters, all_linters(
7071
))
7172
rm(dt_linters)
7273

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

.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

.ci/atime/tests.R

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,20 @@ test.list <- atime::atime_test_list(
231231
},
232232
expr = data.table:::melt(DT, measure.vars = measure.vars),
233233
Slow = "fd24a3105953f7785ea7414678ed8e04524e6955", # Parent of the merge commit (https://github.com/Rdatatable/data.table/commit/ed72e398df76a0fcfd134a4ad92356690e4210ea) of the PR (https://github.com/Rdatatable/data.table/pull/5054) that fixes the issue
234-
Fast = "ed72e398df76a0fcfd134a4ad92356690e4210ea"), # Merge commit of the PR (https://github.com/Rdatatable/data.table/pull/5054) that fixes the issue
234+
Fast = "ed72e398df76a0fcfd134a4ad92356690e4210ea"), # Merge commit of the PR (https://github.com/Rdatatable/data.table/pull/5054) that fixes the issue # Test case created directly using the atime code below (not adapted from any other benchmark), based on the issue/fix PR https://github.com/Rdatatable/data.table/pull/5054#issue-930603663 "melt should be more efficient when there are missing input columns."
235+
236+
# Test case created from @tdhock's comment https://github.com/Rdatatable/data.table/pull/6393#issuecomment-2327396833, in turn adapted from @philippechataignon's comment https://github.com/Rdatatable/data.table/pull/6393#issuecomment-2326714012
237+
"fwrite refactored in #6393" = atime::atime_test(
238+
setup = {
239+
set.seed(1)
240+
NC = 10L
241+
L <- data.table(i=1:N)
242+
L[, paste0("V", 1:NC) := replicate(NC, rnorm(N), simplify=FALSE)]
243+
out.csv <- tempfile()
244+
},
245+
expr = data.table::fwrite(L, out.csv, compress="gzip"),
246+
Before = "f339aa64c426a9cd7cf2fcb13d91fc4ed353cd31", # Parent of the first commit https://github.com/Rdatatable/data.table/commit/fcc10d73a20837d0f1ad3278ee9168473afa5ff1 in the PR https://github.com/Rdatatable/data.table/pull/6393/commits with major change to fwrite with gzip.
247+
PR = "3630413ae493a5a61b06c50e80d166924d2ef89a"), # Close-to-last merge commit in the PR.
235248

236249
tests=extra.test.list)
237250
# nolint end: undesirable_operator_linter.

.ci/linters/c/alloc_linter.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
# 2. Check the next line for a check like 'if (!x || !y)'
55
alloc_linter = function(c_obj) {
66
lines = c_obj$lines
7-
# Be a bit more precise to avoid mentions in comments
8-
alloc_lines = grep(R"{=\s*([(]\w+\s*[*][)])?[mc]alloc[(]}", lines)
7+
# Be a bit more precise to avoid mentions in comments, and allow
8+
# malloc(0) to be used for convenience (e.g. #6757)
9+
alloc_lines = grep(R"{=\s*([(]\w+\s*[*][)])?[mc]alloc[(][^0]}", lines)
910
if (!length(alloc_lines)) return()
1011
# int *tmp=(int*)malloc(...); or just int tmp=malloc(...);
1112
alloc_keys = lines[alloc_lines] |>

.ci/linters/c/cocci_linter.R

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
cocci_linter = if (!nzchar(Sys.which("spatch"))) function(...) {} else function(c_obj) {
2+
bad <- FALSE
3+
for (spfile in list.files(".ci/linters/cocci", full.names = TRUE)) {
4+
# Coccinelle parser gets confused sometimes, so ignore stderr and the exit code
5+
out = suppressWarnings(system2(
6+
"spatch",
7+
shQuote(c(
8+
"--sp-file", spfile, c_obj$path, "--recursive-includes",
9+
"-I", R.home("include"), "-I", "src"
10+
)),
11+
stdout = TRUE, stderr = FALSE
12+
))
13+
if (length(out) > 0) {
14+
cat(sprintf("In file '%s', Coccinelle patch '%s' recommends the following changes:\n", c_obj$path, spfile))
15+
writeLines(out)
16+
bad <- TRUE
17+
}
18+
}
19+
if (bad) stop("Please apply the changes above or fix the linter")
20+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@@
2+
type T;
3+
T* E;
4+
@@
5+
- (T*)
6+
E

.ci/linters/md/heading_id_linter.R

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
any_mismatch = FALSE
2+
3+
# ensure that ids are limited to alphanumerics and dashes
4+
# (in particular, dots and underscores break the links)
5+
check_header_ids = function(md) {
6+
# A bit surprisingly, some headings don't start with a letter.
7+
# We're interested in those that set an id to link to, i.e., end with {#id}.
8+
heading_captures = regmatches(md, regexec("^#+ \\S.*[{]#([^}]*)[}]$", md))
9+
lines_with_id = which(lengths(heading_captures) > 0)
10+
ids = vapply(heading_captures[lines_with_id], `[`, '', 2)
11+
# ids must start with a letter and consist of alphanumerics or dashes.
12+
good_ids = grepl('^[A-Za-z][A-Za-z0-9-]*$', ids)
13+
for (line in lines_with_id[!good_ids]) cat(sprintf(
14+
"On line %d, bad heading id '%s':\n%s\n",
15+
line, heading_captures[[line]][2], heading_captures[[line]][1]
16+
))
17+
!all(good_ids)
18+
}
19+
20+
any_error = FALSE
21+
for (vignette in list.files('vignettes', pattern = "[.]Rmd$", recursive = TRUE, full.name = TRUE)) {
22+
cat(sprintf("Checking vignette file %s...\n", vignette))
23+
rmd_lines = readLines(vignette)
24+
any_error = check_header_ids(rmd_lines) || any_error
25+
}
26+
if (any_error) stop("Please fix the vignette issues above.")

.dev/CRAN_Release.cmd

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,22 @@
33
###############################################
44

55
# 1) Update messages for new release
6-
## (a) Update C template file: src/data.table.pot
7-
## ideally, we are including _() wrapping in
8-
## new PRs throughout dev cycle, and this step
9-
## becomes about tying up loose ends
10-
## Check the output here for translatable messages
11-
xgettext -o /dev/stdout ./*.c \
12-
--keyword=Rprintf --keyword=error --keyword=warning --keyword=STOP --keyword=DTWARN --keyword=Error --keyword=DTPRINT --keyword=snprintf:3
13-
14-
## (b) Update R template file: src/R-data.table.pot
15-
## NB: this relies on R >= 4.0 to remove a bug in update_pkg_po
16-
Rscript -e "tools::update_pkg_po('.')"
6+
dt_custom_translators = list(
7+
R = 'catf:fmt|1',
8+
# TODO(MichaelChirico/potools#318): restore snprintf:3 here too
9+
src = c('STOP:1', 'DTWARN:1', 'DTPRINT:1')
10+
)
11+
message_db =
12+
potools::get_message_data(custom_translation_functions = dt_custom_translators)
13+
potools::check_cracked_messages(message_db)
14+
potools::check_untranslated_cat(message_db)
15+
potools::check_untranslated_src(message_db)
16+
17+
## (b) Update R template files (po/*.pot)
18+
potools::po_extract(custom_translation_functions = dt_custom_translators)
1719

1820
# 2) Open a PR with the new templates & contact the translators
19-
# * zh_CN: @hongyuanjia
20-
# * pt_BR: @rffontenelle
21-
# * es: @rikivillalba
21+
# using @Rdatatable/<lang>, e.g. @Rdatatable/chinese
2222
## Translators to submit commits with translations to this PR
2323
## [or perhaps, if we get several languages, each to open
2424
## its own PR and merge to main translation PR]
@@ -114,12 +114,6 @@ grep -P "\t" ./src/*.c
114114
grep -n "[^A-Za-z0-9]T[^A-Za-z0-9]" ./inst/tests/tests.Rraw
115115
grep -n "[^A-Za-z0-9]F[^A-Za-z0-9]" ./inst/tests/tests.Rraw
116116

117-
# All integers internally should have L suffix to avoid lots of one-item coercions
118-
# Where 0 numeric is intended we should perhaps use 0.0 for clarity and make the grep easier
119-
# 1) tolerance=0 usages in setops.R are valid numeric 0, as are anything in strings
120-
# 2) leave the rollends default using roll>=0 though; comments in PR #3803
121-
grep -Enr "^[^#]*(?:\[|==|>|<|>=|<=|,|\(|\+)\s*[-]?[0-9]+[^0-9L:.e]" R | grep -Ev "stop|warning|tolerance"
122-
123117
# Never use ifelse. fifelse for vectors when necessary (nothing yet)
124118
grep -Enr "\bifelse" R
125119

@@ -135,10 +129,6 @@ grep -Fn "tryCatch" ./inst/tests/*.Rraw
135129
# All % in *.Rd should be escaped otherwise text gets silently chopped
136130
grep -n "[^\]%" ./man/*.Rd
137131

138-
# if (a & b) is either invalid or inefficient (ditto for replace & with |);
139-
# if(any(a [&|] b)) is appropriate b/c of collapsing the logical vector to scalar
140-
grep -nr "^[^#]*if[^&#]*[^&#\"][&][^&]" R | grep -Ev "if\s*[(](?:any|all)"
141-
142132
# seal leak potential where two unprotected API calls are passed to the same
143133
# function call, usually involving install() or mkChar()
144134
# Greppable thanks to single lines and wide screens

.dev/lsan.supp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
leak:libfontconfig.so
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
FROM docker.io/rhub/r-minimal:devel
2+
3+
RUN apk update \
4+
&& apk add --no-cache \
5+
gcc git musl-dev openmp pkgconf tzdata zlib-dev \
6+
&& echo 'options("repos"="https://cloud.r-project.org")' >> /usr/local/lib/R/etc/Rprofile.site
7+
8+
ENV TZDIR=/usr/share/zoneinfo
9+
10+
COPY DESCRIPTION .
11+
12+
RUN Rscript -e ' \
13+
read.dcf("DESCRIPTION", c("Imports", "Suggests")) |> \
14+
tools:::.split_dependencies() |> \
15+
names() |> \
16+
setdiff(tools:::.get_standard_package_names()$base) |> \
17+
install.packages(repos="https://cloud.r-project.org") \
18+
'
19+
20+
# setup cc()
21+
WORKDIR /root
22+
COPY .devcontainer/.Rprofile .

0 commit comments

Comments
 (0)