Skip to content

Commit

Permalink
Fixes for translatable messages in R code (#6533)
Browse files Browse the repository at this point in the history
* between(): use "POSIXct" class name

"POSIX" is ambiguous and doesn't name a class

* Correct R syntax suggested by [.data.table

* Fix the PR17478 error message

R version with the fix found out using:
svn cat -r r76717 https://svn.r-project.org/R/branches/R-3-6-branch/VERSION

* Suggest Sys.setLanguage('en') for error messages

FIXME: formatting of the very long string could be improved

* duplicated() accepts singular data.(table|frame)

* melt(): s/libraries/packages/

* setdiff_: do not translate R code

* [.data.table: vector *of* length %d

* Fix tests for contents of error messages

* Grammar fix for message

* whitespace style

* partial revert: space for new sentence within **** region

* add a TODO since this issue is eventually fixed

* use domain=NA over #notranslate

---------

Co-authored-by: Michael Chirico <[email protected]>
  • Loading branch information
aitap and MichaelChirico authored Sep 24, 2024
1 parent 298bb1a commit 6abbaaf
Show file tree
Hide file tree
Showing 8 changed files with 20 additions and 15 deletions.
6 changes: 3 additions & 3 deletions R/between.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ between = function(x, lower, upper, incbounds=TRUE, NAbounds=TRUE, check=FALSE)
if (is.logical(upper)) upper = as.integer(upper) # typically NA (which is logical type)
is.px = function(x) inherits(x, "POSIXct")
is.i64 = function(x) inherits(x, "integer64") # this is true for nanotime too
# POSIX special handling to auto coerce character
# POSIXct special handling to auto coerce character
if (is.px(x) && (is.character(lower) || is.character(upper))) {
tz = attr(x, "tzone", exact=TRUE)
if (is.null(tz)) tz = ""
if (is.character(lower)) lower = tryCatch(as.POSIXct(lower, tz=tz), error=function(e)stopf(
"'between' function the 'x' argument is a POSIX class while '%s' was not, coercion to POSIX failed with: %s", 'lower', e$message))
"The 'x' argument of the 'between' function is POSIXct while '%s' was not, coercion to POSIXct failed with: %s", 'lower', conditionMessage(e)))
if (is.character(upper)) upper = tryCatch(as.POSIXct(upper, tz=tz), error=function(e)stopf(
"'between' function the 'x' argument is a POSIX class while '%s' was not, coercion to POSIX failed with: %s", 'upper', e$message))
"The 'x' argument of the 'between' function is POSIXct while '%s' was not, coercion to POSIXct failed with: %s", 'upper', conditionMessage(e)))
stopifnot(is.px(x), is.px(lower), is.px(upper)) # nocov # internal
}
# POSIX check timezone match
Expand Down
6 changes: 3 additions & 3 deletions R/data.table.R
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ replace_dot_alias = function(e) {
root = root_name(jsub)
} else if (length(jsub) > 2L && jsub[[2L]] %iscall% ":=") {
#2142 -- j can be {} and have length 1
stopf("You have wrapped := with {} which is ok but then := must be the only thing inside {}. You have something else inside {} as well. Consider placing the {} on the RHS of := instead; e.g. DT[,someCol:={tmpVar1<-...;tmpVar2<-...;tmpVar1*tmpVar2}")
stopf("You have wrapped := with {} which is ok but then := must be the only thing inside {}. You have something else inside {} as well. Consider placing the {} on the RHS of := instead; e.g. DT[,someCol:={tmpVar1<-...;tmpVar2<-...;tmpVar1*tmpVar2}]")
}
}
if (root=="eval" && !any(all.vars(jsub[[2L]]) %chin% names_x)) {
Expand Down Expand Up @@ -409,7 +409,7 @@ replace_dot_alias = function(e) {
"'%s' is not found in calling scope and it is not a column name either",
as.character(isub)
) else gettextf(
"'%s' is not found in calling scope, but it is a column of type %s. If you wish to select rows where that column contains TRUE, or perhaps that column contains row numbers of itself to select, try DT[(col)], DT[DT$col], or DT[col==TRUE} is particularly clear and is optimized",
"'%s' is not found in calling scope, but it is a column of type %s. If you wish to select rows where that column contains TRUE, or perhaps that column contains row numbers of itself to select, try DT[(col)], DT[DT$col], or DT[col==TRUE] is particularly clear and is optimized",
as.character(isub), typeof(col)
)
stopf("%s. When the first argument inside DT[...] is a single symbol (e.g. DT[var]), data.table looks for var in calling scope.", msg)
Expand Down Expand Up @@ -1040,7 +1040,7 @@ replace_dot_alias = function(e) {
if (anyNA(.SDcols))
stopf(".SDcols missing at the following indices: %s", brackify(which(is.na(.SDcols))))
if (is.logical(.SDcols)) {
if (length(.SDcols)!=length(x)) stopf(".SDcols is a logical vector length %d but there are %d columns", length(.SDcols), length(x))
if (length(.SDcols)!=length(x)) stopf(".SDcols is a logical vector of length %d but there are %d columns", length(.SDcols), length(x))
ansvals = which_(.SDcols, !negate_sdcols)
ansvars = sdvars = names_x[ansvals]
} else if (is.numeric(.SDcols)) {
Expand Down
2 changes: 1 addition & 1 deletion R/duplicated.R
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ anyDuplicated.data.table = function(x, incomparables=FALSE, fromLast=FALSE, by=s
uniqueN = function(x, by = if (is.list(x)) seq_along(x) else NULL, na.rm=FALSE) { # na.rm, #1455
if (is.null(x)) return(0L)
if (!is.atomic(x) && !is.data.frame(x))
stopf("x must be an atomic vector or data.frames/data.tables")
stopf("x must be an atomic vector or a data.frame/data.table")
if (is.atomic(x)) {
if (is.logical(x)) return(.Call(CuniqueNlogical, x, na.rm=na.rm))
x = as_list(x)
Expand Down
2 changes: 1 addition & 1 deletion R/fmelt.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ melt.default = function(data, ..., na.rm = FALSE, value.name = "value") {
data_name = deparse(substitute(data))
ns = tryCatch(getNamespace("reshape2"), error=function(e)
stopf("The %1$s generic in data.table has been passed a %2$s, but data.table::%1$s currently only has a method for data.tables. Please confirm your input is a data.table, with setDT(%3$s) or as.data.table(%3$s). If you intend to use a method from reshape2, try installing that package first, but do note that reshape2 is superseded and is no longer actively developed.", "melt", class1(data), data_name))
warningf("The %1$s generic in data.table has been passed a %2$s and will attempt to redirect to the relevant reshape2 method; please note that reshape2 is superseded and is no longer actively developed, and this redirection is now deprecated. To continue using melt methods from reshape2 while both libraries are attached, e.g. melt.list, you can prepend the namespace, i.e. reshape2::%1$s(%3$s). In the next version, this warning will become an error.", "melt", class1(data), data_name)
warningf("The %1$s generic in data.table has been passed a %2$s and will attempt to redirect to the relevant reshape2 method; please note that reshape2 is superseded and is no longer actively developed, and this redirection is now deprecated. To continue using melt methods from reshape2 while both packages are attached, e.g. melt.list, you can prepend the namespace, i.e. reshape2::%1$s(%3$s). In the next version, this warning will become an error.", "melt", class1(data), data_name)
ns$melt(data, ..., na.rm=na.rm, value.name=value.name)
# nocov end
}
Expand Down
8 changes: 6 additions & 2 deletions R/onAttach.R
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@
else
packageStartupMessagef("data.table %s using %d threads (see ?getDTthreads). ", v, nth, appendLF=FALSE)
packageStartupMessagef("Latest news: r-datatable.com")
if (gettext("TRANSLATION CHECK") != "TRANSLATION CHECK")
packageStartupMessagef("**********\nRunning data.table in English; package support is available in English only. When searching for online help, be sure to also check for the English error message. This can be obtained by looking at the po/R-<locale>.po and po/<locale>.po files in the package source, where the native language and English error messages can be found side-by-side\n**********")
if (gettext("TRANSLATION CHECK") != "TRANSLATION CHECK") {
packageStartupMessagef(
"**********\nRunning data.table in English; package support is available in English only. When searching for online help, be sure to also check for the English error message. This can be obtained by looking at the po/R-<locale>.po and po/<locale>.po files in the package source, where the native language and English error messages can be found side-by-side.%s\n**********",
if (exists('Sys.setLanguage', envir=baseenv())) " You can also try calling Sys.setLanguage('en') prior to reproducing the error message." else ""
)
}
if (dev && (Sys.Date() - as.Date(d))>28L)
packageStartupMessagef("**********\nThis development version of data.table was built more than 4 weeks ago. Please update: data.table::update_dev_pkg()\n**********")
if (!.Call(ChasOpenMP)) {
Expand Down
3 changes: 2 additions & 1 deletion R/onLoad.R
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
if (dllV != RV) {
dll = if (.Platform$OS.type=="windows") "dll" else "so"
# https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17478
stopf("The data_table.%s version (%s) does not match the package (%s). Please close all R sessions to release the old %s and reinstall data.table in a fresh R session. The root cause is that R's package installer can in some unconfirmed circumstances leave a package in a state that is apparently functional but where new R code is calling old C code silently: https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17478. Once a package is in this mismatch state it may produce wrong results silently until you next upgrade the package. Please help by adding precise circumstances to 17478 to move the status to confirmed. This mismatch between R and C code can happen with any package not just data.table. It is just that data.table has added this check.", dll, dllV, RV, toupper(dll))
# TODO(R>=4.0.0): Remove or adjust this message once we're sure all users are unaffected
stopf("The data_table.%s version (%s) does not match the package (%s). Please close all R sessions to release the old %s and reinstall data.table in a fresh R session. Prior to R version 3.6.0 patched, R's package installer could leave a package in an apparently functional state where new R code was calling old C code silently: https://bugs.r-project.org/bugzilla/show_bug.cgi?id=17478. Once a package is in this mismatch state it may produce wrong results silently until you next upgrade the package. This mismatch between R and C code can happen with any package not just data.table. It is just that data.table has added this check.", dll, dllV, RV, toupper(dll))
}
builtPath = system.file("Meta", "package.rds", package="data.table")
if (builtPath != "" && !identical(session_r_version>="4.0.0", (build_r_version <- readRDS(builtPath)$Built$R)>="4.0.0")) {
Expand Down
2 changes: 1 addition & 1 deletion R/setops.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ setdiff_ = function(x, y, by.x=seq_along(x), by.y=seq_along(y), use.names=FALSE)
by.x = colnamesInt(x, by.x, check_dups=TRUE)
if (!nrow(y)) return(unique(x, by=by.x))
by.y = colnamesInt(y, by.y, check_dups=TRUE)
if (length(by.x) != length(by.y)) stopf("length(by.x) != length(by.y)")
if (length(by.x) != length(by.y)) stopf("length(by.x) != length(by.y)", domain=NA)
# factor in x should've factor/character in y, and vice-versa
for (a in seq_along(by.x)) {
lc = by.y[a]
Expand Down
6 changes: 3 additions & 3 deletions inst/tests/tests.Rraw
Original file line number Diff line number Diff line change
Expand Up @@ -7539,7 +7539,7 @@ test(1538.2, !is.unsorted(tables(order.col="NROW")$NROW), output="Total:")

# uniqueN not support list-of-list: reverted #1224
d1 <- data.table(a = 1:4, l = list(list(letters[1:2]),list(Sys.time()),list(1:10),list(letters[1:2])))
test(1539, d1[,uniqueN(l)], error = "x must be an atomic vector or data.frames/data.tables")
test(1539, d1[,uniqueN(l)], error = "x must be an atomic vector or a data.frame/data.table")

# feature #1130 - joins without setting keys
# can't test which=TRUE with DT1.copy's results..
Expand Down Expand Up @@ -14920,10 +14920,10 @@ options(old)

# exceptions in char to POSIX coercion
dn = 'aa2016-09-18 08:00:00'
test(2038.14, between(x, dn, up), error="coercion to POSIX failed")
test(2038.14, between(x, dn, up), error="coercion to POSIXct failed")
dn = '2016-09-18 08:00:00'
up = 'bb2016-09-18 09:00:00'
test(2038.15, between(x, dn, up), error="coercion to POSIX failed")
test(2038.15, between(x, dn, up), error="coercion to POSIXct failed")

# exceptions due to timezone mismatch
x = as.POSIXct("2016-09-18 07:00:00", tz="UTC") + 0:10*60*15
Expand Down

0 comments on commit 6abbaaf

Please sign in to comment.