From 2e7c33f1bf74e1c4620c99b03786feacbeab6773 Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Fri, 2 Jan 2026 11:27:59 -0800 Subject: [PATCH 1/4] Unify messages in R --- R/as.data.table.R | 8 ++++---- R/data.table.R | 16 ++++++++-------- R/duplicated.R | 2 +- R/fcast.R | 12 +++++++----- R/fmelt.R | 2 +- R/foverlaps.R | 8 ++++---- R/frank.R | 2 +- R/frollapply.R | 10 +++++----- R/groupingsets.R | 6 +++--- R/helpers.R | 4 ++-- R/merge.R | 8 ++++---- R/setkey.R | 4 ++-- 12 files changed, 42 insertions(+), 40 deletions(-) diff --git a/R/as.data.table.R b/R/as.data.table.R index 5b4dea6975..1894235462 100644 --- a/R/as.data.table.R +++ b/R/as.data.table.R @@ -89,10 +89,10 @@ as.data.table.array = function(x, keep.rownames=FALSE, key=NULL, sorted=TRUE, va stopf("as.data.table.array method should only be called for arrays with 3+ dimensions; use the matrix method for 2-dimensional arrays") if (!is.character(value.name) || length(value.name)!=1L || is.na(value.name) || !nzchar(value.name)) stopf("Argument 'value.name' must be scalar character, non-NA and at least one character") - if (!is.logical(sorted) || length(sorted)!=1L || is.na(sorted)) - stopf("Argument 'sorted' must be scalar logical and non-NA") - if (!is.logical(na.rm) || length(na.rm)!=1L || is.na(na.rm)) - stopf("Argument 'na.rm' must be scalar logical and non-NA") + if (!isTRUEorFALSE(sorted)) + stopf("'%s' must be TRUE or FALSE", "sorted") + if (!isTRUEorFALSE(na.rm)) + stopf("'%s' must be TRUE or FALSE", "na.rm") if (!missing(sorted) && !is.null(key)) stopf("Please provide either 'key' or 'sorted', but not both.") diff --git a/R/data.table.R b/R/data.table.R index 27c985e44c..dc5c61cbed 100644 --- a/R/data.table.R +++ b/R/data.table.R @@ -244,7 +244,7 @@ replace_dot_alias = function(e) { if ((isTRUE(which)||is.na(which)) && !missing(j)) stopf("which==%s (meaning return row numbers) but j is also supplied. Either you need row numbers or the result of j, but only one type of result can be returned.", which) if (is.null(nomatch) && is.na(which)) stopf("which=NA with nomatch=0|NULL would always return an empty vector. Please change or remove either which or nomatch.") if (!with && missing(j)) stopf("j must be provided when with=FALSE") - if (!missing(by) && !isTRUEorFALSE(showProgress)) stopf("%s must be TRUE or FALSE", "showProgress") + if (!missing(by) && !isTRUEorFALSE(showProgress)) stopf("'%s' must be TRUE or FALSE", "showProgress") irows = NULL # Meaning all rows. We avoid creating 1:nrow(x) for efficiency. notjoin = FALSE rightcols = leftcols = integer() @@ -1509,8 +1509,8 @@ replace_dot_alias = function(e) { ########################################################################### o__ = integer() - if (".N" %chin% ansvars) stopf("The column '.N' can't be grouped because it conflicts with the special .N variable. Try setnames(DT,'.N','N') first.") - if (".I" %chin% ansvars) stopf("The column '.I' can't be grouped because it conflicts with the special .I variable. Try setnames(DT,'.I','I') first.") + if (".N" %chin% ansvars) stopf("The column '.%1$s' can't be grouped because it conflicts with the special .%1$s variable. Try setnames(DT,'.%1$s','%1$s') first.", "N") + if (".I" %chin% ansvars) stopf("The column '.%1$s' can't be grouped because it conflicts with the special .%1$s variable. Try setnames(DT,'.%1$s','%1$s') first.", "I") SDenv$.iSD = NULL # null.data.table() SDenv$.xSD = NULL # null.data.table() - introducing for FR #2693 and Gabor's post on fixing for FAQ 2.8 @@ -2530,7 +2530,7 @@ Ops.data.table = function(e1, e2 = NULL) } split.data.table = function(x, f, drop = FALSE, by, sorted = FALSE, keep.by = TRUE, flatten = TRUE, ..., verbose = getOption("datatable.verbose")) { - if (!is.data.table(x)) internal_error("x argument to split.data.table must be a data.table") # nocov + if (!is.data.table(x)) internal_error("'%s' argument to split.data.table must be a data.table") # nocov stopifnot(is.logical(drop), is.logical(sorted), is.logical(keep.by), is.logical(flatten)) # split data.frame way, using `f` and not `by` argument if (!missing(f)) { @@ -3110,10 +3110,10 @@ rowid = function(..., prefix=NULL) { rowidv = function(x, cols=seq_along(x), prefix=NULL) { if (!is.null(prefix) && (!is.character(prefix) || length(prefix) != 1L)) - stopf("'prefix' must be NULL or a character vector of length 1.") + stopf("'prefix' must be NULL or a character vector of length 1") if (is.atomic(x)) { if (!missing(cols) && !is.null(cols)) - stopf("x is a single vector, non-NULL 'cols' doesn't make sense.") + stopf("x is a single vector, non-NULL 'cols' doesn't make sense") cols = 1L x = as_list(x) } else if (!length(cols)) { @@ -3135,10 +3135,10 @@ rleid = function(..., prefix=NULL) { rleidv = function(x, cols=seq_along(x), prefix=NULL) { if (!is.null(prefix) && (!is.character(prefix) || length(prefix) != 1L)) - stopf("'prefix' must be NULL or a character vector of length 1.") + stopf("'prefix' must be NULL or a character vector of length 1") if (is.atomic(x)) { if (!missing(cols) && !is.null(cols)) - stopf("x is a single vector, non-NULL 'cols' doesn't make sense.") + stopf("x is a single vector, non-NULL 'cols' doesn't make sense") cols = 1L x = as_list(x) } else if (!length(cols)) { diff --git a/R/duplicated.R b/R/duplicated.R index e1a04c9822..5e06007e0f 100644 --- a/R/duplicated.R +++ b/R/duplicated.R @@ -4,7 +4,7 @@ duplicated.data.table = function(x, incomparables=FALSE, fromLast=FALSE, by=seq_ .NotYetUsed("incomparables != FALSE") } if (nrow(x) == 0L || ncol(x) == 0L) return(logical(0L)) # fix for bug #28 - if (is.na(fromLast) || !is.logical(fromLast)) stopf("'fromLast' must be TRUE or FALSE") + if (is.na(fromLast) || !is.logical(fromLast)) stopf("'%s' must be TRUE or FALSE", "fromLast") if (!length(by)) by = NULL #4594 query = .duplicated.helper(x, by) diff --git a/R/fcast.R b/R/fcast.R index 35ab4eaae8..1bcc2916fb 100644 --- a/R/fcast.R +++ b/R/fcast.R @@ -122,13 +122,15 @@ aggregate_funs = function(funs, vals, sep="_", ...) { } dcast.data.table = function(data, formula, fun.aggregate = NULL, sep = "_", ..., margins = NULL, subset = NULL, fill = NULL, drop = TRUE, value.var = guess(data), verbose = getOption("datatable.verbose"), value.var.in.dots = FALSE, value.var.in.LHSdots = value.var.in.dots, value.var.in.RHSdots = value.var.in.dots) { - if (!is.data.table(data)) stopf("'data' must be a data.table.") + if (!is.data.table(data)) stopf("'%s' must be a data.table", "data") drop = as.logical(rep_len(drop, 2L)) - if (anyNA(drop)) stopf("'drop' must be logical TRUE/FALSE") + if (anyNA(drop)) stopf("'drop' must be logical vector with no missing entries") if (!isTRUEorFALSE(value.var.in.dots)) - stopf("Argument 'value.var.in.dots' should be logical TRUE/FALSE") - if (!isTRUEorFALSE(value.var.in.LHSdots) || !isTRUEorFALSE(value.var.in.RHSdots)) - stopf("Arguments 'value.var.in.LHSdots', 'value.var.in.RHSdots' should be logical TRUE/FALSE") + stopf("'%s' must be TRUE or FALSE", "value.var.in.dots") + if (!isTRUEorFALSE(value.var.in.LHSdots)) + stopf("'%s' must be TRUE or FALSE", "value.var.in.LHSdots") + if (!isTRUEorFALSE(value.var.in.RHSdots)) + stopf("'%s' must be TRUE or FALSE", "value.var.in.RHSdots") # #2980 if explicitly providing fun.aggregate=length but not a value.var, # just use the last column (as guess(data) would do) because length will be # the same on all columns diff --git a/R/fmelt.R b/R/fmelt.R index c6f435578b..e0596f73fc 100644 --- a/R/fmelt.R +++ b/R/fmelt.R @@ -181,7 +181,7 @@ measurev = function(fun.list, sep="_", pattern, cols, multiple.keyword="value.na melt.data.table = function(data, id.vars, measure.vars, variable.name = "variable", value.name = "value", ..., na.rm = FALSE, variable.factor = TRUE, value.factor = FALSE, verbose = getOption("datatable.verbose")) { - if (!is.data.table(data)) stopf("'data' must be a data.table") + if (!is.data.table(data)) stopf("'%s' must be a data.table", "data") for(type.vars in c("id.vars","measure.vars")){ sub.lang <- substitute({ if (missing(VAR)) VAR=NULL diff --git a/R/foverlaps.R b/R/foverlaps.R index 7bbaf0dc13..8c3d4be777 100644 --- a/R/foverlaps.R +++ b/R/foverlaps.R @@ -9,8 +9,8 @@ foverlaps = function(x, y, by.x=key(x) %||% key(y), by.y=key(y), maxgap=0L, mino stopf("maxgap must be a non-negative integer value of length 1") if (!length(minoverlap) || length(minoverlap) != 1L || is.na(minoverlap) || minoverlap < 1L) stopf("minoverlap must be a positive integer value of length 1") - if (!length(which) || length(which) != 1L || is.na(which)) - stopf("which must be a logical vector of length 1. Either TRUE/FALSE") + if (!isTRUEorFALSE(which)) + stopf("'%s' must be TRUE or FALSE", "which") if (!length(nomatch) || length(nomatch) != 1L || (!is.na(nomatch) && nomatch!=0L)) stopf("nomatch must either be NA or NULL") type = match.arg(type) @@ -33,9 +33,9 @@ foverlaps = function(x, y, by.x=key(x) %||% key(y), by.y=key(y), maxgap=0L, mino by.y = names(y)[by.y] } if (!is.character(by.x)) - stopf("A non-empty vector of column names or numbers is required for by.x") + stopf("A non-empty vector of column names or numbers is required for '%s'", "by.x") if (!is.character(by.y)) - stopf("A non-empty vector of column names or numbers is required for by.y") + stopf("A non-empty vector of column names or numbers is required for '%s'", "by.y") if (!identical(by.y, key(y)[seq_along(by.y)])) stopf("The first %d columns of y's key must be identical to the columns specified in by.y.", length(by.y)) if (anyNA(chmatch(by.x, names(x)))) diff --git a/R/frank.R b/R/frank.R index 419f5ea414..63e3be8321 100644 --- a/R/frank.R +++ b/R/frank.R @@ -20,7 +20,7 @@ frankv = function(x, cols=seq_along(x), order=1L, na.last=TRUE, ties.method=c("a } else { cols = colnamesInt(x, cols, check_dups=TRUE) if (!length(cols)) - stopf("x is a list, 'cols' can not be 0-length") + stopf("x is a list, 'cols' cannot be 0-length.") } # need to unlock for #4429 x = .shallow(x, cols, unlock = TRUE) # shallow copy even if list.. diff --git a/R/frollapply.R b/R/frollapply.R index a8a214ff13..7c2433cc98 100644 --- a/R/frollapply.R +++ b/R/frollapply.R @@ -133,15 +133,15 @@ frollapply = function(X, N, FUN, ..., by.column=TRUE, fill=NA, align=c("right"," stopf("'n' is deprecated in frollapply, use 'N' instead") } if (!isTRUEorFALSE(by.column)) - stopf("'by.column' must be TRUE or FALSE") + stopf("'%s' must be TRUE or FALSE", "by.column") if (!isTRUEorFALSE(adaptive)) - stopf("'adaptive' must be TRUE or FALSE") + stopf("'%s' must be TRUE or FALSE", "adaptive") if (!isTRUEorFALSE(partial)) - stopf("'partial' must be TRUE or FALSE") + stopf("'%s' must be TRUE or FALSE", "partial") if (!isTRUEorFALSE(give.names)) - stopf("'give.names' must be TRUE or FALSE") + stopf("'%s' must be TRUE or FALSE", "give.names") if (!isTRUEorFALSE(simplify) && !is.function(simplify)) - stopf("'simplify' must be TRUE or FALSE or a function") + stopf("'%s' must be TRUE or FALSE or a function") align = match.arg(align) FUN = match.fun(FUN) diff --git a/R/groupingsets.R b/R/groupingsets.R index f5fc2101f1..dec10316e6 100644 --- a/R/groupingsets.R +++ b/R/groupingsets.R @@ -4,7 +4,7 @@ rollup = function(x, ...) { rollup.data.table = function(x, j, by, .SDcols, id = FALSE, label = NULL, ...) { # input data type basic validation if (!is.data.table(x)) - stopf("Argument 'x' must be a data.table object", class="dt_invalid_input_error") + stopf("'%s' must be a data.table", "x", class="dt_invalid_input_error") if (!is.character(by)) stopf("Argument 'by' must be a character vector of column names used in grouping.") if (!is.logical(id)) @@ -22,7 +22,7 @@ cube = function(x, ...) { cube.data.table = function(x, j, by, .SDcols, id = FALSE, label = NULL, ...) { # input data type basic validation if (!is.data.table(x)) - stopf("Argument 'x' must be a data.table object", class="dt_invalid_input_error") + stopf("'%s' must be a data.table", "x", class="dt_invalid_input_error") if (!is.character(by)) stopf("Argument 'by' must be a character vector of column names used in grouping.") if (!is.logical(id)) @@ -44,7 +44,7 @@ groupingsets = function(x, ...) { groupingsets.data.table = function(x, j, by, sets, .SDcols, id = FALSE, jj, label = NULL, enclos = parent.frame(), ...) { # input data type basic validation if (!is.data.table(x)) - stopf("Argument 'x' must be a data.table object") + stopf("'%s' must be a data.table", "x") if (ncol(x) < 1L) stopf("Argument 'x' is a 0-column data.table; no measure to apply grouping over.") if (anyDuplicated(names(x)) > 0L) diff --git a/R/helpers.R b/R/helpers.R index 213b0c057e..284a129bb2 100644 --- a/R/helpers.R +++ b/R/helpers.R @@ -3,9 +3,9 @@ # convert char to factor retaining order #4837 fctr = function(x, levels=unique(x), ..., sort=FALSE, rev=FALSE) { if (!isTRUEorFALSE(sort)) - stopf("argument 'sort' must be TRUE or FALSE") + stopf("'%s' must be TRUE or FALSE", "sort") if (!isTRUEorFALSE(rev)) - stopf("argument 'rev' must be TRUE or FALSE") + stopf("'%s' must be TRUE or FALSE", "rev") if (sort) levels = sort(levels) if (rev) levels = frev(levels) factor(x, levels=levels, ...) diff --git a/R/merge.R b/R/merge.R index 2484cd9a0f..23156a43d0 100644 --- a/R/merge.R +++ b/R/merge.R @@ -1,9 +1,9 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FALSE, all.x = all, all.y = all, sort = TRUE, suffixes = c(".x", ".y"), no.dups = TRUE, allow.cartesian=getOption("datatable.allow.cartesian"), incomparables=NULL, ...) { - if (!sort %in% c(TRUE, FALSE)) - stopf("Argument 'sort' should be logical TRUE/FALSE") - if (!no.dups %in% c(TRUE, FALSE)) - stopf("Argument 'no.dups' should be logical TRUE/FALSE") + if (!isTRUEorFALSE(sort)) + stopf("'%s' must be TRUE or FALSE", "sort") + if (!isTRUEorFALSE(no.dups)) + stopf("'%s' must be TRUE or FALSE", "no.dups") class_x = class(x) if (!is.data.table(y)) { y = as.data.table(y) diff --git a/R/setkey.R b/R/setkey.R index 4ba5be4d71..afaf06293e 100644 --- a/R/setkey.R +++ b/R/setkey.R @@ -32,7 +32,7 @@ setkeyv = function(x, cols, verbose=getOption("datatable.verbose"), physical=TRU on.exit(options(oldverbose)) } if (!is.data.table(x)) stopf("x is not a data.table") - if (!is.character(cols)) stopf("cols is not a character vector. Please see further information in ?setkey.") + if (!is.character(cols)) stopf("cols is not a character vector. Please see further information in ?%s.", "setkey") if (physical && .Call(C_islocked, x)) stopf("Setting a physical key on .SD is reserved for possible future use; to modify the original data's order by group. Try setindex() instead. Or, set*(copy(.SD)) as a (slow) last resort.") if (!length(cols)) { warningf("cols is a character vector of zero length. Removed the key, but use NULL instead, or wrap with suppressWarnings() to avoid this warning.") @@ -257,7 +257,7 @@ setorderv = function(x, cols = colnames(x), order=1L, na.last=FALSE) if (!is.data.frame(x)) stopf("x must be a data.frame or data.table") na.last = as.logical(na.last) if (is.na(na.last) || !length(na.last)) stopf('na.last must be logical TRUE/FALSE') - if (!is.character(cols)) stopf("cols is not a character vector. Please see further information in ?setorder.") + if (!is.character(cols)) stopf("cols is not a character vector. Please see further information in ?%s.", "setorder") if (!length(cols)) { warningf("cols is a character vector of zero length. Use NULL instead, or wrap with suppressWarnings() to avoid this warning.") return(x) From d840b88f1760226bcd8a6bb9def322ec135c3cbf Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Fri, 2 Jan 2026 11:40:46 -0800 Subject: [PATCH 2/4] Unify messages in C --- src/assign.c | 10 +++++----- src/between.c | 4 ++-- src/fastmean.c | 4 ++-- src/fifelse.c | 14 +++++++------- src/fmelt.c | 12 ++++++------ src/frollR.c | 4 ++-- src/fsort.c | 2 +- src/gsumm.c | 12 ++++++------ src/nafill.c | 2 +- src/openmp-utils.c | 2 +- src/rbindlist.c | 8 ++++---- src/transpose.c | 6 +++--- src/uniqlist.c | 2 +- src/utils.c | 6 +++--- 14 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/assign.c b/src/assign.c index 849cb08f2a..ab95de7c18 100644 --- a/src/assign.c +++ b/src/assign.c @@ -180,7 +180,7 @@ SEXP alloccol(SEXP dt, R_len_t n, Rboolean verbose) SEXP names, klass; // klass not class at request of pydatatable because class is reserved word in C++, PR #3129 R_len_t l, tl; if (isNull(dt)) error(_("alloccol has been passed a NULL dt")); - if (TYPEOF(dt) != VECSXP) error(_("dt passed to alloccol isn't type VECSXP")); + if (TYPEOF(dt) != VECSXP) error(_("dt passed to %s isn't type VECSXP"), "alloccol"); klass = getAttrib(dt, R_ClassSymbol); if (isNull(klass)) error(_("dt passed to alloccol has no class attribute. Please report result of traceback() to data.table issue tracker.")); l = LENGTH(dt); @@ -222,7 +222,7 @@ int checkOverAlloc(SEXP x) SEXP alloccolwrapper(SEXP dt, SEXP overAllocArg, SEXP verbose) { if (!IS_TRUE_OR_FALSE(verbose)) - error(_("%s must be TRUE or FALSE"), "verbose"); + error(_("'%s' must be TRUE or FALSE"), "verbose"); int overAlloc = checkOverAlloc(overAllocArg); SEXP ans = PROTECT(alloccol(dt, length(dt)+overAlloc, LOGICAL(verbose)[0])); @@ -271,7 +271,7 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values) const char *c1, *tc1, *tc2; int *buf, indexNo; if (isNull(dt)) error(_("assign has been passed a NULL dt")); - if (TYPEOF(dt) != VECSXP) error(_("dt passed to assign isn't type VECSXP")); + if (TYPEOF(dt) != VECSXP) error(_("dt passed to %s isn't type VECSXP"), "assign"); if (islocked(dt)) error(_(".SD is locked. Updating .SD by reference using := or set are reserved for future use. Use := in j directly. Or use copy(.SD) as a (slow) last resort, until shallow() is exported.")); @@ -1190,9 +1190,9 @@ SEXP allocNAVectorLike(SEXP x, R_len_t n) { SEXP setcharvec(SEXP x, SEXP which, SEXP newx) { int w; - if (!isString(x)) error(_("x must be a character vector")); + if (!isString(x)) error(_("'%s' must be a character vector"), "x"); if (!isInteger(which)) error(_("'which' must be an integer vector")); - if (!isString(newx)) error(_("'new' must be a character vector")); + if (!isString(newx)) error(_("'%s' must be a character vector"), "new"); if (LENGTH(newx)!=LENGTH(which)) error(_("'new' is length %d. Should be the same as length of 'which' (%d)"),LENGTH(newx),LENGTH(which)); for (int i=0; i2) { tmp = CADDR(args); - if (!isLogical(tmp) || LENGTH(tmp)!=1 || LOGICAL(tmp)[0]==NA_LOGICAL) - error(_("%s should be TRUE or FALSE"), "narm"); // # nocov ; [.data.table should construct the .External call correctly + if (!IS_TRUE_OR_FALSE(tmp)) + error(_("'%s' must be TRUE or FALSE"), "narm"); // # nocov ; [.data.table should construct the .External call correctly narm=LOGICAL_RO(tmp)[0]; } PROTECT(ans = allocNAVector(REALSXP, 1)); diff --git a/src/fifelse.c b/src/fifelse.c index 2c1055372e..d59fb4c60e 100644 --- a/src/fifelse.c +++ b/src/fifelse.c @@ -60,34 +60,34 @@ SEXP fifelseR(SEXP l, SEXP a, SEXP b, SEXP na) { if (!na_a && !na_b) { if (!R_compute_identical(PROTECT(getAttrib(a,R_ClassSymbol)), PROTECT(getAttrib(b,R_ClassSymbol)), 0)) - error(_("'yes' has different class than 'no'. Please make sure that both arguments have the same class.")); + error(_("'%s' has different class than '%s'. Please make sure that both arguments have the same class."), "yes", "no"); UNPROTECT(2); } if (!na_a && !na_n) { if (!R_compute_identical(PROTECT(getAttrib(a,R_ClassSymbol)), PROTECT(getAttrib(na,R_ClassSymbol)), 0)) - error(_("'yes' has different class than 'na'. Please make sure that both arguments have the same class.")); + error(_("'%s' has different class than '%s'. Please make sure that both arguments have the same class."), "yes", "na"); UNPROTECT(2); } if (!na_b && !na_n) { if (!R_compute_identical(PROTECT(getAttrib(b,R_ClassSymbol)), PROTECT(getAttrib(na,R_ClassSymbol)), 0)) - error(_("'no' has different class than 'na'. Please make sure that both arguments have the same class.")); + error(_("'%s' has different class than '%s'. Please make sure that both arguments have the same class."), "no", "na"); UNPROTECT(2); } if (isFactor(a) || isFactor(b)) { if (!na_a && !na_b) { if (!R_compute_identical(PROTECT(getAttrib(a,R_LevelsSymbol)), PROTECT(getAttrib(b,R_LevelsSymbol)), 0)) - error(_("'yes' and 'no' are both type factor but their levels are different.")); + error(_("'%s' and '%s' are both type factor but their levels are different."), "yes", "no"); UNPROTECT(2); } if (!na_a && !na_n) { if (!R_compute_identical(PROTECT(getAttrib(a,R_LevelsSymbol)), PROTECT(getAttrib(na,R_LevelsSymbol)), 0)) - error(_("'yes' and 'na' are both type factor but their levels are different.")); + error(_("'%s' and '%s' are both type factor but their levels are different."), "yes", "na"); UNPROTECT(2); } if (!na_b && !na_n) { if (!R_compute_identical(PROTECT(getAttrib(b,R_LevelsSymbol)), PROTECT(getAttrib(na,R_LevelsSymbol)), 0)) - error(_("'no' and 'na' are both type factor but their levels are different.")); + error(_("'%s' and '%s' are both type factor but their levels are different."), "no", "na"); UNPROTECT(2); } } @@ -404,7 +404,7 @@ SEXP fcaseR(SEXP rho, SEXP args) { } } break; default: - error(_("Type '%s' is not supported."), type2char(TYPEOF(ans))); + error(_("Type '%s' is not supported"), type2char(TYPEOF(ans))); } if (l==0) { break; // stop early as nothing left to do diff --git a/src/fmelt.c b/src/fmelt.c index d6843c3ace..7523e802fa 100644 --- a/src/fmelt.c +++ b/src/fmelt.c @@ -787,12 +787,12 @@ SEXP fmelt(SEXP DT, SEXP id, SEXP measure, SEXP varfactor, SEXP valfactor, SEXP Rboolean narm=FALSE, verbose=FALSE; if (!isNewList(DT)) error(_("Input is not of type VECSXP, expected a data.table, data.frame or list")); - if (!isLogical(valfactor)) error(_("Argument 'value.factor' should be logical TRUE/FALSE")); - if (!isLogical(varfactor)) error(_("Argument 'variable.factor' should be logical TRUE/FALSE")); - if (!isLogical(narmArg)) error(_("Argument 'na.rm' should be logical TRUE/FALSE.")); - if (!isString(varnames)) error(_("Argument 'variable.name' must be a character vector")); - if (!isString(valnames)) error(_("Argument 'value.name' must be a character vector")); - if (!isLogical(verboseArg)) error(_("Argument 'verbose' should be logical TRUE/FALSE")); + if (!IS_TRUE_OR_FALSE(valfactor)) error(_("'%s' must be TRUE or FALSE"), "value.factor"); + if (!IS_TRUE_OR_FALSE(varfactor)) error(_("'%s' must be TRUE or FALSE"), "variable.factor"); + if (!IS_TRUE_OR_FALSE(narmArg)) error(_("'%s' must be TRUE or FALSE"), "na.rm"); + if (!isString(varnames)) error(_("'%s' must be a character vector"), "variable.name"); + if (!isString(valnames)) error(_("'%s' must be a character vector"), "value.name"); + if (!IS_TRUE_OR_FALSE(verboseArg)) error(_("'%s' must be TRUE or FALSE"), "verbose"); if (LOGICAL(verboseArg)[0] == TRUE) verbose = TRUE; int ncol = LENGTH(DT); if (!ncol) { diff --git a/src/frollR.c b/src/frollR.c index afb70c3f15..ea145eace0 100644 --- a/src/frollR.c +++ b/src/frollR.c @@ -94,7 +94,7 @@ SEXP frollfunR(SEXP fun, SEXP xobj, SEXP kobj, SEXP fill, SEXP algo, SEXP align, error(_("n must be non 0 length")); if (!IS_TRUE_OR_FALSE(adaptive)) - error(_("%s must be TRUE or FALSE"), "adaptive"); + error(_("'%s' must be TRUE or FALSE"), "adaptive"); bool badaptive = LOGICAL(adaptive)[0]; SEXP k = PROTECT(coerceK(kobj, badaptive)); protecti++; @@ -109,7 +109,7 @@ SEXP frollfunR(SEXP fun, SEXP xobj, SEXP kobj, SEXP fill, SEXP algo, SEXP align, } if (!IS_TRUE_OR_FALSE(narm)) - error(_("%s must be TRUE or FALSE"), "na.rm"); + error(_("'%s' must be TRUE or FALSE"), "na.rm"); if (!isLogical(hasnf) || length(hasnf)!=1) error(_("has.nf must be TRUE, FALSE or NA")); diff --git a/src/fsort.c b/src/fsort.c index c43d69eee2..f79bf72d07 100644 --- a/src/fsort.c +++ b/src/fsort.c @@ -114,7 +114,7 @@ SEXP fsort(SEXP x, SEXP verboseArg) { double t[10]; t[0] = wallclock(); if (!IS_TRUE_OR_FALSE(verboseArg)) - error(_("%s must be TRUE or FALSE"), "verbose"); + error(_("'%s' must be TRUE or FALSE"), "verbose"); int verbose = LOGICAL(verboseArg)[0]; if (!isNumeric(x)) error(_("x must be a vector of type double currently")); // TODO: not only detect if already sorted, but if it is, just return x to save the duplicate diff --git a/src/gsumm.c b/src/gsumm.c index 5970f59194..6ab1f6501b 100644 --- a/src/gsumm.c +++ b/src/gsumm.c @@ -348,7 +348,7 @@ void *gather(SEXP x, bool *anyNA) SEXP gsum(SEXP x, SEXP narmArg) { if (!IS_TRUE_OR_FALSE(narmArg)) - error(_("%s must be TRUE or FALSE"), "na.rm"); + error(_("'%s' must be TRUE or FALSE"), "na.rm"); const bool narm = LOGICAL(narmArg)[0]; if (inherits(x, "factor")) error(_("%s is not meaningful for factors."), "sum"); @@ -584,7 +584,7 @@ SEXP gmean(SEXP x, SEXP narmArg) if (inherits(x, "factor")) error(_("%s is not meaningful for factors."), "mean"); if (!IS_TRUE_OR_FALSE(narmArg)) - error(_("%s must be TRUE or FALSE"), "na.rm"); + error(_("'%s' must be TRUE or FALSE"), "na.rm"); const bool narm = LOGICAL(narmArg)[0]; const int n = (irowslen == -1) ? length(x) : irowslen; double started = wallclock(); @@ -730,7 +730,7 @@ SEXP gmean(SEXP x, SEXP narmArg) static SEXP gminmax(SEXP x, SEXP narm, const bool min) { if (!IS_TRUE_OR_FALSE(narm)) - error(_("%s must be TRUE or FALSE"), "na.rm"); + error(_("'%s' must be TRUE or FALSE"), "na.rm"); if (!isVectorAtomic(x)) error(_("GForce min/max can only be applied to columns, not .SD or similar. To find min/max of all items in a list such as .SD, either add the prefix base::min(.SD) or turn off GForce optimization using options(datatable.optimize=1). More likely, you may be looking for 'DT[,lapply(.SD,min),by=,.SDcols=]'")); if (inherits(x, "factor") && !inherits(x, "ordered")) error(_("%s is not meaningful for factors."), min?"min":"max"); @@ -868,7 +868,7 @@ SEXP gmax(SEXP x, SEXP narm) // gmedian, always returns numeric type (to avoid as.numeric() wrap..) SEXP gmedian(SEXP x, SEXP narmArg) { if (!IS_TRUE_OR_FALSE(narmArg)) - error(_("%s must be TRUE or FALSE"), "na.rm"); + error(_("'%s' must be TRUE or FALSE"), "na.rm"); if (!isVectorAtomic(x)) error(_("GForce median can only be applied to columns, not .SD or similar. To find median of all items in a list such as .SD, either add the prefix stats::median(.SD) or turn off GForce optimization using options(datatable.optimize=1). More likely, you may be looking for 'DT[,lapply(.SD,median),by=,.SDcols=]'")); if (inherits(x, "factor")) error(_("%s is not meaningful for factors."), "median"); @@ -1023,7 +1023,7 @@ SEXP gnthvalue(SEXP x, SEXP nArg) { static SEXP gvarsd1(SEXP x, SEXP narmArg, bool isSD) { if (!IS_TRUE_OR_FALSE(narmArg)) - error(_("%s must be TRUE or FALSE"), "na.rm"); + error(_("'%s' must be TRUE or FALSE"), "na.rm"); if (!isVectorAtomic(x)) error(_("GForce var/sd can only be applied to columns, not .SD or similar. For the full covariance matrix of all items in a list such as .SD, either add the prefix stats::var(.SD) (or stats::sd(.SD)) or turn off GForce optimization using options(datatable.optimize=1). Alternatively, if you only need the diagonal elements, 'DT[,lapply(.SD,var),by=,.SDcols=]' is the optimized way to do this.")); if (inherits(x, "factor")) error(_("%s is not meaningful for factors."), isSD ? "sd" : "var"); @@ -1115,7 +1115,7 @@ SEXP gsd(SEXP x, SEXP narm) { SEXP gprod(SEXP x, SEXP narmArg) { if (!IS_TRUE_OR_FALSE(narmArg)) - error(_("%s must be TRUE or FALSE"), "na.rm"); + error(_("'%s' must be TRUE or FALSE"), "na.rm"); const bool narm=LOGICAL(narmArg)[0]; if (!isVectorAtomic(x)) error(_("GForce prod can only be applied to columns, not .SD or similar. To multiply all items in a list such as .SD, either add the prefix base::prod(.SD) or turn off GForce optimization using options(datatable.optimize=1). More likely, you may be looking for 'DT[,lapply(.SD,prod),by=,.SDcols=]'")); diff --git a/src/nafill.c b/src/nafill.c index 4187523c58..c782335e85 100644 --- a/src/nafill.c +++ b/src/nafill.c @@ -105,7 +105,7 @@ SEXP nafillR(SEXP obj, SEXP type, SEXP fill, SEXP nan_is_na_arg, SEXP inplace, S bool binplace = LOGICAL(inplace)[0]; if (!IS_TRUE_OR_FALSE(nan_is_na_arg)) - error(_("%s must be TRUE or FALSE"), "nan_is_na"); // # nocov + error(_("'%s' must be TRUE or FALSE"), "nan_is_na"); // # nocov bool nan_is_na = LOGICAL(nan_is_na_arg)[0]; SEXP x = R_NilValue; diff --git a/src/openmp-utils.c b/src/openmp-utils.c index d6df568ae6..f7a63f40b1 100644 --- a/src/openmp-utils.c +++ b/src/openmp-utils.c @@ -94,7 +94,7 @@ SEXP getDTthreads_C(SEXP n, SEXP throttle) SEXP getDTthreads_R(SEXP verbose) { if(!IS_TRUE_OR_FALSE(verbose)) - error(_("%s must be TRUE or FALSE"), "verbose"); + error(_("'%s' must be TRUE or FALSE"), "verbose"); if (LOGICAL(verbose)[0]) { #ifndef _OPENMP Rprintf(_("This installation of data.table has not been compiled with OpenMP support.\n")); diff --git a/src/rbindlist.c b/src/rbindlist.c index 764558c184..a752be6d39 100644 --- a/src/rbindlist.c +++ b/src/rbindlist.c @@ -4,12 +4,12 @@ SEXP rbindlist(SEXP l, SEXP usenamesArg, SEXP fillArg, SEXP idcolArg, SEXP ignoreattrArg) { - if (!isLogical(fillArg) || LENGTH(fillArg) != 1 || LOGICAL(fillArg)[0] == NA_LOGICAL) - error(_("%s should be TRUE or FALSE"), "fill"); + if (!IS_TRUE_OR_FALSE(fillArg)) + error(_("'%s' must be TRUE or FALSE"), "fill"); if (!isLogical(usenamesArg) || LENGTH(usenamesArg)!=1) error(_("use.names= should be TRUE, FALSE, or not used (\"check\" by default)")); // R levels converts "check" to NA - if (!isLogical(ignoreattrArg) || LENGTH(ignoreattrArg)!=1 || LOGICAL(ignoreattrArg)[0] == NA_LOGICAL) - error(_("%s should be TRUE or FALSE"), "ignore.attr"); + if (!IS_TRUE_OR_FALSE(ignoreattrArg)) + error(_("'%s' must be TRUE or FALSE"), "ignore.attr"); if (!length(l)) return(l); if (TYPEOF(l) != VECSXP) error(_("Input to rbindlist must be a list. This list can contain data.tables, data.frames or plain lists.")); int usenames = LOGICAL(usenamesArg)[0]; diff --git a/src/transpose.c b/src/transpose.c index 939ca5d792..93d9206134 100644 --- a/src/transpose.c +++ b/src/transpose.c @@ -9,8 +9,8 @@ SEXP transpose(SEXP l, SEXP fill, SEXP ignoreArg, SEXP keepNamesArg, SEXP listCo error(_("l must be a list.")); if (!length(l)) return(copyAsPlain(l)); - if (!isLogical(ignoreArg) || LOGICAL_RO(ignoreArg)[0] == NA_LOGICAL) - error(_("ignore.empty should be logical TRUE/FALSE.")); + if (!IS_TRUE_OR_FALSE(ignoreArg)) + error(_("'%s' must be TRUE or FALSE"), "ignore.empty"); const bool ignore = LOGICAL_RO(ignoreArg)[0]; if (!(isNull(keepNamesArg) || (isString(keepNamesArg) && LENGTH(keepNamesArg) == 1))) error(_("keep.names should be either NULL, or the name of the first column of the result in which to place the names of the input")); @@ -19,7 +19,7 @@ SEXP transpose(SEXP l, SEXP fill, SEXP ignoreArg, SEXP keepNamesArg, SEXP listCo error(_("fill must be a length 1 vector, such as the default NA")); const R_len_t ln = LENGTH(l); if (!IS_TRUE_OR_FALSE(listColsArg)) - error(_("list.cols should be logical TRUE/FALSE.")); + error(_("'%s' must be TRUE or FALSE"), "list.cols"); const bool listCol = LOGICAL_RO(listColsArg)[0]; // preprocessing diff --git a/src/uniqlist.c b/src/uniqlist.c index 333d6bc69d..e64f650174 100644 --- a/src/uniqlist.c +++ b/src/uniqlist.c @@ -355,7 +355,7 @@ SEXP uniqueNlogical(SEXP x, SEXP narmArg) { // single pass; short-circuit and return as soon as all 3 values are found if (!isLogical(x)) error(_("x is not a logical vector")); if (!IS_TRUE_OR_FALSE(narmArg)) - error(_("%s must be TRUE or FALSE"), "na.rm"); + error(_("'%s' must be TRUE or FALSE"), "na.rm"); bool narm = LOGICAL(narmArg)[0]==1; const R_xlen_t n = xlength(x); if (n==0) diff --git a/src/utils.c b/src/utils.c index e11bc09d57..cbfddb492d 100644 --- a/src/utils.c +++ b/src/utils.c @@ -120,9 +120,9 @@ SEXP colnamesInt(SEXP x, SEXP cols, SEXP check_dups, SEXP skip_absent) { if (!isNewList(x)) error(_("'x' argument must be data.table compatible")); if (!IS_TRUE_OR_FALSE(check_dups)) - error(_("%s must be TRUE or FALSE"), "check_dups"); + error(_("'%s' must be TRUE or FALSE"), "check_dups"); if (!IS_TRUE_OR_FALSE(skip_absent)) - error(_("%s must be TRUE or FALSE"), "skip_absent"); + error(_("'%s' must be TRUE or FALSE"), "skip_absent"); int protecti = 0; R_len_t nx = length(x); R_len_t nc = length(cols); @@ -538,7 +538,7 @@ SEXP frev(SEXP x, SEXP copyArg) { if (INHERITS(x, char_dataframe)) error(_("'x' should not be data.frame or data.table.")); if (!IS_TRUE_OR_FALSE(copyArg)) - error(_("%s must be TRUE or FALSE."), "copy"); // # nocov + error(_("'%s' must be TRUE or FALSE."), "copy"); // # nocov bool copy = LOGICAL(copyArg)[0]; R_xlen_t n = xlength(x); int nprotect = 0; From 8ae777f8233af3954d7b57a6eaa584b7abcfb6a4 Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Fri, 2 Jan 2026 13:04:07 -0800 Subject: [PATCH 3/4] match tests to new messages --- R/frollapply.R | 2 +- inst/tests/froll.Rraw | 4 ++-- inst/tests/nafill.Rraw | 2 +- inst/tests/tests.Rraw | 51 +++++++++++++++++++++--------------------- 4 files changed, 30 insertions(+), 29 deletions(-) diff --git a/R/frollapply.R b/R/frollapply.R index 7c2433cc98..9c1b0c26d7 100644 --- a/R/frollapply.R +++ b/R/frollapply.R @@ -141,7 +141,7 @@ frollapply = function(X, N, FUN, ..., by.column=TRUE, fill=NA, align=c("right"," if (!isTRUEorFALSE(give.names)) stopf("'%s' must be TRUE or FALSE", "give.names") if (!isTRUEorFALSE(simplify) && !is.function(simplify)) - stopf("'%s' must be TRUE or FALSE or a function") + stopf("'%s' must be TRUE or FALSE or a function", "simplify") align = match.arg(align) FUN = match.fun(FUN) diff --git a/inst/tests/froll.Rraw b/inst/tests/froll.Rraw index 22e50682e8..66f6e6427e 100644 --- a/inst/tests/froll.Rraw +++ b/inst/tests/froll.Rraw @@ -423,9 +423,9 @@ test(6000.118, frollmean(1:5, as.factor("a")), error="'n' must be an integer") #### is.list(n) test(6000.119, frollmean(1:5, list(1:5)), error="'n' must be an integer, list is accepted for adaptive TRUE") #### adaptive=NA -test(6000.1192, frollmean(1:5, 2, adaptive=NA), error="adaptive must be TRUE or FALSE") +test(6000.1192, frollmean(1:5, 2, adaptive=NA), error="'adaptive' must be TRUE or FALSE") #### na.rm=NA -test(6000.1193, frollmean(1:5, 2, na.rm=NA), error="na.rm must be TRUE or FALSE") +test(6000.1193, frollmean(1:5, 2, na.rm=NA), error="'na.rm' must be TRUE or FALSE") #### has.nf=1 test(6000.1194, frollmean(1:5, 2, has.nf=1), error="has.nf must be TRUE, FALSE or NA") #### has.nf=FALSE na.rm=TRUE diff --git a/inst/tests/nafill.Rraw b/inst/tests/nafill.Rraw index 16f84fa16f..1a8634e2b9 100644 --- a/inst/tests/nafill.Rraw +++ b/inst/tests/nafill.Rraw @@ -149,7 +149,7 @@ test(4.26, colnamesInt(dt, c(1, 4), skip_absent=TRUE), c(1L,0L)) test(4.27, colnamesInt(dt, c("a", NA), skip_absent=TRUE), c(1L,0L)) test(4.28, colnamesInt(dt, c(1L, 0L), skip_absent=TRUE), error="received non-existing column*.*0") test(4.29, colnamesInt(dt, c(1, -5), skip_absent=TRUE), error="received non-existing column*.*-5") -test(4.30, colnamesInt(dt, c(1, 4), skip_absent=NULL), error="skip_absent must be TRUE or FALSE") +test(4.30, colnamesInt(dt, c(1, 4), skip_absent=NULL), error="'skip_absent' must be TRUE or FALSE") test(4.31, colnamesInt(dt, c(1L, 1000L), skip_absent=TRUE), c(1L,0L)) cols=c(1L,100L) test(4.32, colnamesInt(dt, cols, skip_absent=TRUE), c(1L, 0L)) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 8cad916e3b..7a9ddc4341 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -3708,8 +3708,9 @@ test(1100, dt1[dt2,roll=-Inf,rollends=c(FALSE,TRUE)]$ind, INT(NA,NA,1,2,2,2,2,2, # issue 5824 - tests for "value.var.in.dots", "value.var.in.LHSdots", "value.var.in.RHSdots" arguments of dcast DT = data.table(index = c("a","b"), x = 1:2) - test(1102.181, dcast(DT, ... ~ index, fun.aggregate = length, value.var.in.dots = NA), error = "Argument 'value.var.in.dots' should be logical TRUE/FALSE") - test(1102.182, dcast(DT, ... ~ index, fun.aggregate = length, value.var.in.LHSdots = NA), error = "Arguments 'value.var.in.LHSdots', 'value.var.in.RHSdots' should be logical TRUE/FALSE") + test(1102.1810, dcast(DT, ... ~ index, fun.aggregate = length, value.var.in.dots = NA), error = "'value.var.in.dots' must be TRUE or FALSE") + test(1102.1821, dcast(DT, ... ~ index, fun.aggregate = length, value.var.in.LHSdots = NA), error = "'value.var.in.LHSdots' must be TRUE or FALSE") + test(1102.1822, dcast(DT, ... ~ index, fun.aggregate = length, value.var.in.RHSdots = NA), error = "'value.var.in.RHSdots' must be TRUE or FALSE") test(1102.183, dcast(DT, ... ~ index, fun.aggregate = length, value.var.in.dots = TRUE), data.table(x = 1:2, a = 1:0, b = 0:1, key = "x")) test(1102.184, dcast(DT, ... ~ index, fun.aggregate = length, value.var = "index", value.var.in.dots = TRUE), data.table(index = c("a","b"), x = 1:2, a = 1:0, b = 0:1, key = c("index", "x"))) test(1102.185, dcast(DT, ... + index ~ index, fun.aggregate = length, value.var = "index", value.var.in.dots = TRUE), data.table(index = c("a","b"), x = 1:2, a = 1:0, b = 0:1, key = c("index", "x"))) @@ -7032,7 +7033,7 @@ test(1477.08, transpose(1:5), error="l must be a list") test(1477.09, transpose(list(as.complex(c(1, 1+5i)))), error="Unsupported column type") test(1477.10, transpose(list(x~y)), error="Item 1 of list input is") test(1477.11, transpose(as.list(1:5), fill=1:2), error="fill must be a length 1 vector") -test(1477.12, transpose(as.list(1:5), ignore.empty=NA), error="ignore.empty should be logical TRUE/FALSE") +test(1477.12, transpose(as.list(1:5), ignore.empty=NA), error="'ignore.empty' must be TRUE or FALSE") test(1477.13, transpose(list()), list()) # return list columns #5639 la = list(as.list(1:3), list("a","b","c")) @@ -7045,7 +7046,7 @@ test(1477.18, transpose(list(list(1L,"a"), list(2L), list(3L,"c")), list.cols=TR test(1477.19, transpose(list(1:2, c("a","b","c")), list.cols=TRUE, fill=3L), lb) test(1477.20, transpose(list(factor(letters[1:3])), list.cols=TRUE), list(list("a"), list("b"), list("c"))) test(1477.21, transpose(list(factor(letters[1:3])), list.cols=FALSE), list("a", "b", "c")) -test(1477.22, transpose(la, list.cols=NA), error="list.cols should be logical TRUE/FALSE.") +test(1477.22, transpose(la, list.cols=NA), error="'list.cols' must be TRUE or FALSE") # #480 `setDT` and 'lapply' ll = list(data.frame(a=1), data.frame(x=1, y=2), NULL, list()) @@ -11881,8 +11882,8 @@ test(1774.13, as.data.table(x), error = "Argument 'value.name' should not overla ## unsupported usage of as.data.table.array test(1774.14, as.data.table.array(as.matrix(x)), error="method should only be called for arrays with 3+") test(1774.15, as.data.table(x, value.name=NA), error="'value.name' must be scalar") -test(1774.16, as.data.table(x, sorted='a'), error="'sorted' must be scalar") -test(1774.17, as.data.table(x, na.rm='a'), error="'na.rm' must be scalar") +test(1774.16, as.data.table(x, sorted='a'), error="'sorted' must be TRUE or FALSE") +test(1774.17, as.data.table(x, na.rm='a'), error="'na.rm' must be TRUE or FALSE") # verify print.keys works DT1 <- data.table(a = 1:3, key = "a") @@ -12817,7 +12818,7 @@ test(1888.5, fsort(x), base::sort(x, na.last = FALSE), x = runif(1e3) test(1888.6, y<-fsort(x,verbose=TRUE), output="nth=.*Top 20 MSB counts") test(1888.7, !base::is.unsorted(y)) -test(1888.8, fsort(x,verbose=1), error="verbose must be TRUE or FALSE") +test(1888.8, fsort(x,verbose=1), error="'verbose' must be TRUE or FALSE") test(1888.9, fsort(c(1L, 2L, 3L, 4L), internal = TRUE), c(1L, 2L, 3L, 4L)) rm(x, y) @@ -13608,9 +13609,9 @@ test(1962.011, uniqlist(list()), list(0L)) DT1 = data.table(a = 1:3, V = 'a') DT2 = data.table(a = 2:4, V = 'b') test(1962.012, merge(DT1, DT2, sort = 1+3i), - error = 'should be logical TRUE/FALSE') + error = "'sort' must be TRUE or FALSE") test(1962.013, merge(DT1, DT2, no.dups = 1+3i), - error = 'should be logical TRUE/FALSE') + error = "'no.dups' must be TRUE or FALSE") setDF(DT2) test(1962.014, merge(DT1, DT2), data.table(a = integer(0), V = character(0))) @@ -13641,7 +13642,7 @@ test(1962.023, frankv(x, na.last = c(TRUE, FALSE)), test(1962.024, frankv(x, cols = 'y'), error = 'x is a single vector') test(1962.025, frankv(list(x), cols = integer(0L)), - error = "x is a list, 'cols' can not be 0-length") + error = "x is a list, 'cols' cannot be 0-length") f = frankv(list(x), ties.method = 'random') test(1962.026, length(f) == 9L && identical(f[c(3:4, 6L, 8:9)], c(3L, 7L, 4L, 9L, 8L)) && @@ -13764,11 +13765,11 @@ DT = data.table( ) setDF(DT) test(1962.068, rollup(DT), error=base_messages$missing_dispatch_method) -test(1962.069, rollup.data.table(DT), error = 'must be a data.table object') +test(1962.069, rollup.data.table(DT), error = 'must be a data.table') test(1962.070, cube(DT), error=base_messages$missing_dispatch_method) -test(1962.071, cube.data.table(DT), error = 'must be a data.table object') +test(1962.071, cube.data.table(DT), error = 'must be a data.table') test(1962.072, groupingsets(DT), error=base_messages$missing_dispatch_method) -test(1962.073, groupingsets.data.table(DT), error = 'must be a data.table object') +test(1962.073, groupingsets.data.table(DT), error = 'must be a data.table') setDT(DT) test(1962.074, rollup(DT, by = 3L), error = "'by' must be a character vector") test(1962.075, rollup(DT, by = 'color', id = 3L), error = "'id' must be a logical scalar") @@ -13800,7 +13801,7 @@ setDF(DT) test(1962.085, dcast.data.table(DT), error = 'must be a data.table') setDT(DT) test(1962.086, dcast(DT, a ~ a, drop = NA), - error = 'must be logical TRUE/FALSE') + error = "'drop' must be TRUE or FALSE") DT = data.table(a = c(1, 1, 2, 2), b = list(1, 2, 3, 4), c = c(4, 4, 2, 2)) test(1962.087, dcast(DT, a ~ b, value.var = 'b'), error = 'Columns specified in formula can not be of type list') @@ -13960,11 +13961,11 @@ test(1967.09, foverlaps(x, y, minoverlap = NA), test(1967.10, foverlaps(x, y, minoverlap = -5), error = 'minoverlap must be a positive integer') test(1967.11, foverlaps(x, y, which = integer(0L)), - error = 'which must be a logical vector') + error = "'which' must be TRUE or FALSE") test(1967.12, foverlaps(x, y, which = c(3, 4)), - error = 'which must be a logical vector') + error = "'which' must be TRUE or FALSE") test(1967.13, foverlaps(x, y, which = NA), - error = 'which must be a logical vector') + error = "'which' must be TRUE or FALSE") test(1967.14, foverlaps(x, y, nomatch = integer(0L)), error = 'nomatch must either be NA or NULL') test(1967.15, foverlaps(x, y, nomatch = c(3, 4)), @@ -13984,9 +13985,9 @@ test(1967.22, foverlaps(x, y, by.y = c(-1L, 0L)), test(1967.23, foverlaps(x, y, by.y = c(1L, 100L)), error = "Invalid numeric value for 'by.y'") test(1967.24, foverlaps(x, y, by.x = c(1 + 3i, 2 - 1i)), - error = 'non-empty vector of column names or numbers is required for by.x') + error = "non-empty vector of column names or numbers is required for 'by.x'") test(1967.25, foverlaps(x, y, by.y = c(1 + 3i, 2 - 1i)), - error = 'non-empty vector of column names or numbers is required for by.y') + error = "non-empty vector of column names or numbers is required for 'by.y'") test(1967.26, foverlaps(x, y, by.x = c('start', 'END')), error = "Elements listed in 'by.x' must be valid names") test(1967.27, foverlaps(x, y, by.x = c('start', 'start')), @@ -14572,7 +14573,7 @@ test(2002.12, rbind(DT1, DT2, idcol='id'), data.table(id=integer(), a=logica #rbindlist coverage test(2003.1, rbindlist(list(), use.names=1), error="use.names= should be TRUE, FALSE, or not used [(]\"check\" by default[)]") -test(2003.2, rbindlist(list(), fill=1), error="fill should be TRUE or FALSE") +test(2003.2, rbindlist(list(), fill=1), error="'fill' must be TRUE or FALSE") test(2003.3, rbindlist(list(data.table(a=1:2), data.table(b=3:4)), fill=TRUE, use.names=FALSE), data.table(a=c(1:4))) test(2003.4, rbindlist(list(data.table(a=1:2,c=5:6), data.table(b=3:4)), fill=TRUE, use.names=FALSE), @@ -14591,7 +14592,7 @@ test(2003.82, rbind(y, x, fill=TRUE, use.names=TRUE), ans[2:1,]) test(2003.83, rbind(x, y, fill=TRUE, use.names=FALSE), ans) test(2003.84, rbind(y, x, fill=TRUE, use.names=FALSE), ans[2:1,]) # rbindlist ignore attributes #3911 -test(2003.85, rbindlist(list(), ignore.attr=1), error="ignore.attr should be TRUE or FALSE") +test(2003.85, rbindlist(list(), ignore.attr=1), error="'ignore.attr' must be TRUE or FALSE") # chmatch coverage for two different non-ascii encodings matching; issues mentioned in comments in chmatch.c #69 #2538 #111 x1 = "fa\xE7ile" @@ -15025,8 +15026,8 @@ test(2037.2, names(DT), 'a') test(2037.3, foo(DT), output="data.table internal attributes", notOutput="data.table internal attributes.*data.table internal attributes") # `between` invalid args, and verbose #3516 -test(2038.01, between(1:5, 2, 4, incbounds=423), error="incbounds must be TRUE or FALSE") -test(2038.02, between(1:5, 2, 4, incbounds=NA), error="incbounds must be TRUE or FALSE") +test(2038.01, between(1:5, 2, 4, incbounds=423), error="'incbounds' must be TRUE or FALSE") +test(2038.02, between(1:5, 2, 4, incbounds=NA), error="'incbounds' must be TRUE or FALSE") old = options(datatable.verbose=TRUE) test(2038.03, between(1:5, 2L, 4L), output="between parallel processing of integer took") test(2038.04, between(1:5, rep(2L,5L), rep(4L, 5L)), output="between parallel processing of integer took") @@ -16173,7 +16174,7 @@ if (test_bit64) { test(2082.07, between(letters[1:2], c("foo","bar"), c("bar")), c(FALSE,FALSE)) test(2082.08, between(letters[1:2], c("foo","bar"), c("bar"), check=TRUE), error="Item 1 of lower ('foo') is greater than item 1 of upper ('bar')") test(2082.09, between(as.raw(1:5), as.raw(3), as.raw(2), check=TRUE), error="Some lower>upper for this non-numeric and non-character type") -test(2082.10, between(1:3, 2, 4, check=NA), error="check must be TRUE or FALSE") +test(2082.10, between(1:3, 2, 4, check=NA), error="'check' must be TRUE or FALSE") # partial instantiation of integer64 column was creating NA_REAL, not INT64_MIN if (test_bit64) { @@ -18006,7 +18007,7 @@ funs = c("sum", "mean", "min", "max", "median", "var", "sd", "prod") testnum = 0L for (fun in funs) { testnum = testnum + 1L - test(2220.0 + testnum*0.01, EVAL("DT[,",fun,"(i, na.rm='a'), g]"), error="na.rm must be TRUE or FALSE", context=sprintf("fun=%s [na.rm='a']", fun)) + test(2220.0 + testnum*0.01, EVAL("DT[,",fun,"(i, na.rm='a'), g]"), error="'na.rm' must be TRUE or FALSE", context=sprintf("fun=%s [na.rm='a']", fun)) testnum = testnum + 1L test(2220.0 + testnum*0.01, EVAL("DT[,",fun,"(f), g]"), error=sprintf("%s is not meaningful for factors.", fun), context=sprintf("fun=%s [factor]", fun)) } From 9590ba002dc4c5361d933c3d0926e7fd96d086bc Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Fri, 2 Jan 2026 13:10:58 -0800 Subject: [PATCH 4/4] last re-fix --- inst/tests/tests.Rraw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 7a9ddc4341..62abb89307 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -13801,7 +13801,7 @@ setDF(DT) test(1962.085, dcast.data.table(DT), error = 'must be a data.table') setDT(DT) test(1962.086, dcast(DT, a ~ a, drop = NA), - error = "'drop' must be TRUE or FALSE") + error = "'drop' must be logical vector with no missing entries") DT = data.table(a = c(1, 1, 2, 2), b = list(1, 2, 3, 4), c = c(4, 4, 2, 2)) test(1962.087, dcast(DT, a ~ b, value.var = 'b'), error = 'Columns specified in formula can not be of type list')