From a8ff6e2931ec64d374b4bc67a5cbece48219231a Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Tue, 24 Jun 2025 08:50:55 -0700 Subject: [PATCH 01/11] only warn once about '...' contents --- R/merge.R | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/R/merge.R b/R/merge.R index 4d7245983e..eeb6f436ec 100644 --- a/R/merge.R +++ b/R/merge.R @@ -63,12 +63,19 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL } # warn about unused arguments #2587 - if (length(list(...))) { - ell = as.list(substitute(list(...)))[-1L] - for (n in setdiff(names(ell), "")) warningf("Unknown argument '%s' has been passed.", n) - unnamed_n = length(ell) - sum(nzchar(names(ell))) - if (unnamed_n) - warningf("Passed %d unknown and unnamed arguments.", unnamed_n) + # TODO(R >= 3.5.0): use ...length() + if (n_dots <- length(dots <- list(...))) { + if (is.null(nm <- names(dots))) { + warningf("%d unnamed arguments wound up in '...' and will be ignored.", n_dots) + } else { + named_idx <- nzchar(nm) + if (all(named_idx)) { + warningf("merge.data.table() received %d unknown keyword arguments which will be ignored: %s", n_dots, brackify(nm)) + } else { + n_named <- sum(named_idx) + warningf("merge.data.table() received %d unnamed arguments in '...' and %d unknown keyword arguments, all of which will be ignored: %s", n_dots - n_named, n_named, brackify(nm[named_idx])) + } + } } # with i. prefix in v1.9.3, this goes away. Left here for now ... ## sidestep the auto-increment column number feature-leading-to-bug by From 840c471633e65bc85b1648faf709b9f21f79673b Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Tue, 24 Jun 2025 09:02:49 -0700 Subject: [PATCH 02/11] pluralization mess --- R/merge.R | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/R/merge.R b/R/merge.R index eeb6f436ec..1417a71431 100644 --- a/R/merge.R +++ b/R/merge.R @@ -66,14 +66,24 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL # TODO(R >= 3.5.0): use ...length() if (n_dots <- length(dots <- list(...))) { if (is.null(nm <- names(dots))) { - warningf("%d unnamed arguments wound up in '...' and will be ignored.", n_dots) + warningf(ngettext(n_dots, "%d unnamed argument wound up in '...' and will be ignored.", + "%d unnamed arguments wound up in '...' and will be ignored."), + n_dots) } else { - named_idx <- nzchar(nm) + named_idx = nzchar(nm) if (all(named_idx)) { - warningf("merge.data.table() received %d unknown keyword arguments which will be ignored: %s", n_dots, brackify(nm)) + warningf(ngettext(n_dots, "merge.data.table() received %d unknown keyword argument which will be ignored: %s" + "merge.data.table() received %d unknown keyword arguments which will be ignored: %s"), + n_dots, brackify(nm)) } else { - n_named <- sum(named_idx) - warningf("merge.data.table() received %d unnamed arguments in '...' and %d unknown keyword arguments, all of which will be ignored: %s", n_dots - n_named, n_named, brackify(nm[named_idx])) + n_named = sum(named_idx) + n_unnamed = n_dots - n_named + warningf(ngettext(n_named, + ngettext(n_unnamed, "merge.data.table() received %d unnamed argument in '...' and %d unknown keyword argument, all of which will be ignored: %s", + "merge.data.table() received %d unnamed arguments in '...' and %d unknown keyword argument, all of which will be ignored: %s"), + ngettext(n_unnamed, "merge.data.table() received %d unnamed argument in '...' and %d unknown keyword arguments, all of which will be ignored: %s", + "merge.data.table() received %d unnamed arguments in '...' and %d unknown keyword arguments, all of which will be ignored: %s")), + n_unnamed, n_named, brackify(nm[named_idx])) } } } From a0643df9107a060a7bbb750c5078d02b6f15ad29 Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Tue, 24 Jun 2025 09:04:06 -0700 Subject: [PATCH 03/11] fix old tests --- inst/tests/tests.Rraw | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index d5801b923e..e68c0fd03d 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -17986,9 +17986,9 @@ test(2230.2, setDF(merge(DT, y, by="k2", incomparables=c(NA,4))), merge(x, y, test(2230.3, setDF(merge(DT, y, by="k2", incomparables=c(4,5))), merge(x, y, by="k2", incomparables=c(4,5))) test(2230.4, setDF(merge(DT, y, by="k2", incomparables=c(1, NA, 4, 5))), merge(x, y, by="k2", incomparables=c(1,NA,4,5))) test(2230.5, setDF(merge(DT, y, by="k2", incomparables=c(NA, 3, 4, 5))), merge(x, y, by="k2", incomparables=c(NA,3,4,5))) -test(2230.6, merge(DT, y, by="k2", unk=1), merge(DT, y, by="k2"), warning="Unknown argument 'unk' has been passed.") +test(2230.6, merge(DT, y, by="k2", unk=1), merge(DT, y, by="k2"), warning="1 unknown keyword argument which will be ignored: [unk]") test(2230.7, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, 1L), - merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "Passed 1 unknown and unnamed arguments.")) + merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "1 unnamed arguments wound up in '...' and will be ignored.")) # weighted.mean GForce optimized, #3977 old = options(datatable.optimize=1L) From e33bb530e475d27cbd79c49bc3637a8f42ebd14e Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Tue, 24 Jun 2025 09:08:35 -0700 Subject: [PATCH 04/11] new tests --- inst/tests/tests.Rraw | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index e68c0fd03d..96d58f9f89 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -17981,14 +17981,26 @@ test(2229.6, fread(testDir("multi-file.zip")), error="Compressed files containin x = data.frame(k1 = c(NA,NA,3,4,5), k2 = c(1,NA,NA,4,5), data = 1:5) y = data.frame(k1 = c(NA,2,NA,4,5), k2 = c(NA,NA,3,4,5), data = 1:5) DT = as.data.table(x) -test(2230.1, setDF(merge(DT, y, by="k2", incomparables=NA)), merge(x, y, by="k2", incomparables=NA)) -test(2230.2, setDF(merge(DT, y, by="k2", incomparables=c(NA,4))), merge(x, y, by="k2", incomparables=c(NA,4))) -test(2230.3, setDF(merge(DT, y, by="k2", incomparables=c(4,5))), merge(x, y, by="k2", incomparables=c(4,5))) -test(2230.4, setDF(merge(DT, y, by="k2", incomparables=c(1, NA, 4, 5))), merge(x, y, by="k2", incomparables=c(1,NA,4,5))) -test(2230.5, setDF(merge(DT, y, by="k2", incomparables=c(NA, 3, 4, 5))), merge(x, y, by="k2", incomparables=c(NA,3,4,5))) -test(2230.6, merge(DT, y, by="k2", unk=1), merge(DT, y, by="k2"), warning="1 unknown keyword argument which will be ignored: [unk]") -test(2230.7, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, 1L), - merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "1 unnamed arguments wound up in '...' and will be ignored.")) +test(2230.01, setDF(merge(DT, y, by="k2", incomparables=NA)), merge(x, y, by="k2", incomparables=NA)) +test(2230.02, setDF(merge(DT, y, by="k2", incomparables=c(NA,4))), merge(x, y, by="k2", incomparables=c(NA,4))) +test(2230.03, setDF(merge(DT, y, by="k2", incomparables=c(4,5))), merge(x, y, by="k2", incomparables=c(4,5))) +test(2230.04, setDF(merge(DT, y, by="k2", incomparables=c(1, NA, 4, 5))), merge(x, y, by="k2", incomparables=c(1,NA,4,5))) +test(2230.05, setDF(merge(DT, y, by="k2", incomparables=c(NA, 3, 4, 5))), merge(x, y, by="k2", incomparables=c(NA,3,4,5))) +test(2230.06, merge(DT, y, by="k2", unk=1), merge(DT, y, by="k2"), warning="1 unknown keyword argument which will be ignored: [unk]") +test(2230.07, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, 1L), + merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "1 unnamed argument wound up in '...' and will be ignored.")) +test(2230.08, merge(DT, y, by="k2", unk1=1, unk2=2), merge(DT, y, by="k2"), warning="2 unknown keyword arguments which will be ignored: [unk1, unk2]") +test(2230.09, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, 1L, 2L), + merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "2 unnamed arguments wound up in '...' and will be ignored.")) +test(2230.10, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, unk=1L, 2L), + merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "1 unnamed argument .*1 unknown keyword argument,.*\\[unk\\]")) +test(2230.11, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, unk1=1L, unk2=2L, 3L), + merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "1 unnamed argument .*2 unknown keyword arguments.*\\[unk1, unk2\\]")) +test(2230.12, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, unk=1L, 2L, 3L), + merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "2 unnamed arguments.*1 unknown keyword argument,.*\\[unk\\]")) +test(2230.13, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, unk1=1L, unk2=2L, 3L, 4L), + merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "2 unnamed arguments.*2 unknown keyword arguments.*\\[unk1, unk2\\]")) + # weighted.mean GForce optimized, #3977 old = options(datatable.optimize=1L) From a7379a3fa1725c07d2d5e4af5bfae6d2af2fe651 Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Tue, 24 Jun 2025 09:19:36 -0700 Subject: [PATCH 05/11] break up double-ngettext --- R/merge.R | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/R/merge.R b/R/merge.R index 1417a71431..cde095d1ad 100644 --- a/R/merge.R +++ b/R/merge.R @@ -66,8 +66,8 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL # TODO(R >= 3.5.0): use ...length() if (n_dots <- length(dots <- list(...))) { if (is.null(nm <- names(dots))) { - warningf(ngettext(n_dots, "%d unnamed argument wound up in '...' and will be ignored.", - "%d unnamed arguments wound up in '...' and will be ignored."), + warningf(ngettext(n_dots, "merge.data.table() received %d unnamed argument in '...' which will be ignored.", + "merge.data.table() received %d unnamed arguments in '...' which will be ignored."), n_dots) } else { named_idx = nzchar(nm) @@ -76,14 +76,9 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL "merge.data.table() received %d unknown keyword arguments which will be ignored: %s"), n_dots, brackify(nm)) } else { - n_named = sum(named_idx) - n_unnamed = n_dots - n_named - warningf(ngettext(n_named, - ngettext(n_unnamed, "merge.data.table() received %d unnamed argument in '...' and %d unknown keyword argument, all of which will be ignored: %s", - "merge.data.table() received %d unnamed arguments in '...' and %d unknown keyword argument, all of which will be ignored: %s"), - ngettext(n_unnamed, "merge.data.table() received %d unnamed argument in '...' and %d unknown keyword arguments, all of which will be ignored: %s", - "merge.data.table() received %d unnamed arguments in '...' and %d unknown keyword arguments, all of which will be ignored: %s")), - n_unnamed, n_named, brackify(nm[named_idx])) + unnamed_clause <- ngettext(n_unnamed, "%d unnamed argumentin '...'", "%d unnamed arguments in '...'") + named_clause <- ngettext(n_named, "%d unknown keyword argument", "%d unknown keyword argument") + warningf("merge.data.table() received %s and %s, all of which will be ignored: %s", unnamed_clause, named_clause, brackify(nm[named_idx])) } } } From d2ed3029ab0a18435e002fc1fbc09cfddce3d34d Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Tue, 24 Jun 2025 09:23:31 -0700 Subject: [PATCH 06/11] missing ',' --- R/merge.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/merge.R b/R/merge.R index cde095d1ad..f7774ff0b7 100644 --- a/R/merge.R +++ b/R/merge.R @@ -72,7 +72,7 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL } else { named_idx = nzchar(nm) if (all(named_idx)) { - warningf(ngettext(n_dots, "merge.data.table() received %d unknown keyword argument which will be ignored: %s" + warningf(ngettext(n_dots, "merge.data.table() received %d unknown keyword argument which will be ignored: %s", "merge.data.table() received %d unknown keyword arguments which will be ignored: %s"), n_dots, brackify(nm)) } else { From 185a783477e9062ff5da28197858eca7ea4a0986 Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Tue, 24 Jun 2025 09:29:33 -0700 Subject: [PATCH 07/11] fix vestige --- R/merge.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/merge.R b/R/merge.R index f7774ff0b7..d50cd3a1f7 100644 --- a/R/merge.R +++ b/R/merge.R @@ -76,7 +76,7 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL "merge.data.table() received %d unknown keyword arguments which will be ignored: %s"), n_dots, brackify(nm)) } else { - unnamed_clause <- ngettext(n_unnamed, "%d unnamed argumentin '...'", "%d unnamed arguments in '...'") + unnamed_clause <- ngettext(n_dots - n_named, "%d unnamed argumentin '...'", "%d unnamed arguments in '...'") named_clause <- ngettext(n_named, "%d unknown keyword argument", "%d unknown keyword argument") warningf("merge.data.table() received %s and %s, all of which will be ignored: %s", unnamed_clause, named_clause, brackify(nm[named_idx])) } From fe1eab0e21a5cf912be15b99c2f496d7680f889f Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Tue, 24 Jun 2025 09:37:44 -0700 Subject: [PATCH 08/11] also missing n_named --- R/merge.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/merge.R b/R/merge.R index d50cd3a1f7..42cddac215 100644 --- a/R/merge.R +++ b/R/merge.R @@ -76,6 +76,7 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL "merge.data.table() received %d unknown keyword arguments which will be ignored: %s"), n_dots, brackify(nm)) } else { + n_named <- sum(named_idx) unnamed_clause <- ngettext(n_dots - n_named, "%d unnamed argumentin '...'", "%d unnamed arguments in '...'") named_clause <- ngettext(n_named, "%d unknown keyword argument", "%d unknown keyword argument") warningf("merge.data.table() received %s and %s, all of which will be ignored: %s", unnamed_clause, named_clause, brackify(nm[named_idx])) From b50f5d0165ddae67399851c325ba065fa3ea0d31 Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Tue, 24 Jun 2025 09:44:25 -0700 Subject: [PATCH 09/11] sprintf() to fill out; fix some tests --- R/merge.R | 4 ++-- inst/tests/tests.Rraw | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/R/merge.R b/R/merge.R index 42cddac215..832b1bc76a 100644 --- a/R/merge.R +++ b/R/merge.R @@ -77,8 +77,8 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL n_dots, brackify(nm)) } else { n_named <- sum(named_idx) - unnamed_clause <- ngettext(n_dots - n_named, "%d unnamed argumentin '...'", "%d unnamed arguments in '...'") - named_clause <- ngettext(n_named, "%d unknown keyword argument", "%d unknown keyword argument") + unnamed_clause <- sprintf(ngettext(n_dots - n_named, "%d unnamed argument in '...'", "%d unnamed arguments in '...'"), n_dots - n_named) + named_clause <- sprintf(ngettext(n_named, "%d unknown keyword argument", "%d unknown keyword argument"), n_named) warningf("merge.data.table() received %s and %s, all of which will be ignored: %s", unnamed_clause, named_clause, brackify(nm[named_idx])) } } diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 96d58f9f89..47df1e53bd 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -17988,10 +17988,10 @@ test(2230.04, setDF(merge(DT, y, by="k2", incomparables=c(1, NA, 4, 5))), merge( test(2230.05, setDF(merge(DT, y, by="k2", incomparables=c(NA, 3, 4, 5))), merge(x, y, by="k2", incomparables=c(NA,3,4,5))) test(2230.06, merge(DT, y, by="k2", unk=1), merge(DT, y, by="k2"), warning="1 unknown keyword argument which will be ignored: [unk]") test(2230.07, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, 1L), - merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "1 unnamed argument wound up in '...' and will be ignored.")) + merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "1 unnamed argument in '...' which will be ignored.")) test(2230.08, merge(DT, y, by="k2", unk1=1, unk2=2), merge(DT, y, by="k2"), warning="2 unknown keyword arguments which will be ignored: [unk1, unk2]") test(2230.09, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, 1L, 2L), - merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "2 unnamed arguments wound up in '...' and will be ignored.")) + merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "2 unnamed arguments in '...' which will be ignored.")) test(2230.10, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, unk=1L, 2L), merge(DT, y, by="k2"), warning=c("Supplied both `by` and `by.x`/`by.y`. `by` argument will be ignored.", "1 unnamed argument .*1 unknown keyword argument,.*\\[unk\\]")) test(2230.11, merge(DT, y, by="k2", NULL, NULL, FALSE, FALSE, FALSE, TRUE, c(".x", ".y"), TRUE, getOption("datatable.allow.cartesian"), NULL, unk1=1L, unk2=2L, 3L), From 514d96367a972db04e1552509f298d953df22c6b Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Tue, 24 Jun 2025 09:49:17 -0700 Subject: [PATCH 10/11] missing 's' --- R/merge.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/merge.R b/R/merge.R index 832b1bc76a..11d698c682 100644 --- a/R/merge.R +++ b/R/merge.R @@ -78,7 +78,7 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL } else { n_named <- sum(named_idx) unnamed_clause <- sprintf(ngettext(n_dots - n_named, "%d unnamed argument in '...'", "%d unnamed arguments in '...'"), n_dots - n_named) - named_clause <- sprintf(ngettext(n_named, "%d unknown keyword argument", "%d unknown keyword argument"), n_named) + named_clause <- sprintf(ngettext(n_named, "%d unknown keyword argument", "%d unknown keyword arguments"), n_named) warningf("merge.data.table() received %s and %s, all of which will be ignored: %s", unnamed_clause, named_clause, brackify(nm[named_idx])) } } From 6913d5c8f33c3f56dba35098d637ac2098fe3469 Mon Sep 17 00:00:00 2001 From: Michael Chirico Date: Tue, 24 Jun 2025 09:55:13 -0700 Subject: [PATCH 11/11] push logic into helper to tidy up merge body --- R/merge.R | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/R/merge.R b/R/merge.R index 11d698c682..c67f6e266a 100644 --- a/R/merge.R +++ b/R/merge.R @@ -63,26 +63,8 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL } # warn about unused arguments #2587 - # TODO(R >= 3.5.0): use ...length() - if (n_dots <- length(dots <- list(...))) { - if (is.null(nm <- names(dots))) { - warningf(ngettext(n_dots, "merge.data.table() received %d unnamed argument in '...' which will be ignored.", - "merge.data.table() received %d unnamed arguments in '...' which will be ignored."), - n_dots) - } else { - named_idx = nzchar(nm) - if (all(named_idx)) { - warningf(ngettext(n_dots, "merge.data.table() received %d unknown keyword argument which will be ignored: %s", - "merge.data.table() received %d unknown keyword arguments which will be ignored: %s"), - n_dots, brackify(nm)) - } else { - n_named <- sum(named_idx) - unnamed_clause <- sprintf(ngettext(n_dots - n_named, "%d unnamed argument in '...'", "%d unnamed arguments in '...'"), n_dots - n_named) - named_clause <- sprintf(ngettext(n_named, "%d unknown keyword argument", "%d unknown keyword arguments"), n_named) - warningf("merge.data.table() received %s and %s, all of which will be ignored: %s", unnamed_clause, named_clause, brackify(nm[named_idx])) - } - } - } + .maybe_warn_merge_dots(...) + # with i. prefix in v1.9.3, this goes away. Left here for now ... ## sidestep the auto-increment column number feature-leading-to-bug by ## ensuring no names end in ".1", see unit test @@ -138,3 +120,28 @@ merge.data.table = function(x, y, by = NULL, by.x = NULL, by.y = NULL, all = FAL setattr(dt, "class", class_x) dt } + +.maybe_warn_merge_dots <- function(...) { + # TODO(R >= 3.5.0): use ...length() + n_dots <- length(dots <- list(...)) + if (!n_dots) return(invisible()) + + nm <- names(dots) + if (is.null(nm)) { + warningf(ngettext(n_dots, "merge.data.table() received %d unnamed argument in '...' which will be ignored.", + "merge.data.table() received %d unnamed arguments in '...' which will be ignored."), + n_dots) + } else { + named_idx = nzchar(nm) + if (all(named_idx)) { + warningf(ngettext(n_dots, "merge.data.table() received %d unknown keyword argument which will be ignored: %s", + "merge.data.table() received %d unknown keyword arguments which will be ignored: %s"), + n_dots, brackify(nm)) + } else { + n_named <- sum(named_idx) + unnamed_clause <- sprintf(ngettext(n_dots - n_named, "%d unnamed argument in '...'", "%d unnamed arguments in '...'"), n_dots - n_named) + named_clause <- sprintf(ngettext(n_named, "%d unknown keyword argument", "%d unknown keyword arguments"), n_named) + warningf("merge.data.table() received %s and %s, all of which will be ignored: %s", unnamed_clause, named_clause, brackify(nm[named_idx])) + } + } +}