From 8c47c153323a687276631c5fc202350015d4134a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 16 Aug 2026 14:19:09 +0000 Subject: [PATCH] fix: An empty argument slot with a name is not an ambiguous argument ```r as_adjacency_matrix(make_ring(4), a = ) ``` returns a 4x4 matrix on 2.3.3 and errors on the dev version with "Argument `a` matches multiple arguments of `as_adjacency_matrix()`". #2812 made the migration blocks handle empty slots by asking `base::missing()` inside `.old_signature()`, which is right and is what fixed the four #2646 revdeps. But two guards run *before* that closure is called, and both read argument names without looking at the values: * `.arg_ambiguous`, from `names(substitute(...()))`, rejects an abbreviation that could mean two different arguments; * `.arg_forbidden`, from `names(sys.call())`, rejects a tag that is a prefix of both a head formal and a recoverable one. An empty slot supplies nothing, so it cannot be ambiguous between two arguments and cannot conflict with a formal -- the old signature would have matched it by position and left the formal missing. Both guards now drop empty slots first. The empty slot is the empty symbol, which is a symbol whose name is the empty string; `Filter()` keeps the test to one expression, which matters because the block is `# fmt: skip` and every line of it is already long. Tests cover the shape on both fixtures that carry a guard -- `migration_fixture_shadow` for `.arg_ambiguous`, `migration_fixture_prefix` for `.arg_forbidden` -- which the empty-slot tests added by #2812 never touched, and assert that a *value* in the same slot is still rejected. One more test pins #2646's two reproducers verbatim against real migrated functions rather than the fixture. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01D1xpHRV7yVfgtJg4vp9P7z --- R/adjacency.R | 8 +-- R/centrality.R | 2 +- R/cliques.R | 4 +- R/community.R | 14 ++--- R/components.R | 2 +- R/conversion.R | 6 +-- R/decomposition.R | 2 +- R/embedding.R | 4 +- R/foreign.R | 2 +- R/games.R | 28 +++++----- R/hrg.R | 4 +- R/incidence.R | 2 +- R/layout.R | 18 +++---- R/migration-fixture.R | 6 +-- R/motifs.R | 6 +-- R/plot.shapes.R | 2 +- R/rewire.R | 2 +- R/similarity.R | 2 +- R/structural-properties.R | 8 +-- R/topology.R | 12 ++--- tests/testthat/_snaps/migration-fixture.md | 17 +++++++ tests/testthat/test-migration-fixture.R | 59 ++++++++++++++++++++++ tools/generate-migrations.R | 28 +++++++++- 23 files changed, 169 insertions(+), 69 deletions(-) diff --git a/R/adjacency.R b/R/adjacency.R index f17ba443814..0aa72fddb34 100644 --- a/R/adjacency.R +++ b/R/adjacency.R @@ -294,9 +294,9 @@ graph_from_adjacency_matrix <- function( # BEGIN GENERATED ARG_HANDLE: graph_from_adjacency_matrix, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("a", "ad")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("a", "ad")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn graph_from_adjacency_matrix}.", i = "Spell out the full argument name.")) - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("a", "ad", "add", "add.")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("a", "ad", "add", "add.")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn graph_from_adjacency_matrix}.") # Pre-3.0.0 signature: graph_from_adjacency_matrix(adjmatrix, mode, weighted, diag, add.colnames, add.rownames) .old_signature <- function(mode, weighted, diag, add.colnames, add.rownames, ...) { @@ -452,9 +452,9 @@ from_adjacency <- function( # BEGIN GENERATED ARG_HANDLE: from_adjacency, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("a", "ad")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("a", "ad")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn from_adjacency}.", i = "Spell out the full argument name.")) - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("a", "ad", "add", "add.")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("a", "ad", "add", "add.")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn from_adjacency}.") # Pre-3.0.0 signature: from_adjacency(adjmatrix, mode, weighted, diag, add.colnames, add.rownames) .old_signature <- function(mode, weighted, diag, add.colnames, add.rownames, ...) { diff --git a/R/centrality.R b/R/centrality.R index 39ee45778a7..70f79985827 100644 --- a/R/centrality.R +++ b/R/centrality.R @@ -1964,7 +1964,7 @@ page_rank <- function( # BEGIN GENERATED ARG_HANDLE: page_rank, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("d")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("d")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn page_rank}.") # Pre-3.0.0 signature: page_rank(graph, algo, vids, directed, damping, personalized, weights, options) .old_signature <- function(algo, vids, directed, damping, personalized, weights, options, ...) { diff --git a/R/cliques.R b/R/cliques.R index 29fefbe4a65..2c1ded9b56b 100644 --- a/R/cliques.R +++ b/R/cliques.R @@ -518,7 +518,7 @@ weighted_cliques <- function( # BEGIN GENERATED ARG_HANDLE: weighted_cliques, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m", "ma", "max")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m", "ma", "max")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn weighted_cliques}.") # Pre-3.0.0 signature: weighted_cliques(graph, vertex.weights, min.weight, max.weight, maximal) .old_signature <- function(vertex.weights, min.weight, max.weight, maximal, ...) { @@ -811,7 +811,7 @@ clique_size_counts <- function( # BEGIN GENERATED ARG_HANDLE: clique_size_counts, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m", "ma")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m", "ma")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn clique_size_counts}.") # Pre-3.0.0 signature: clique_size_counts(graph, min, max, maximal) .old_signature <- function(min, max, maximal, ...) { diff --git a/R/community.R b/R/community.R index 783f7676000..5252ab20b0b 100644 --- a/R/community.R +++ b/R/community.R @@ -781,9 +781,9 @@ make_clusters <- function( # BEGIN GENERATED ARG_HANDLE: make_clusters, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("m", "me")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("m", "me")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn make_clusters}.", i = "Spell out the full argument name.")) - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn make_clusters}.") # Pre-3.0.0 signature: make_clusters(graph, membership, algorithm, merges, modularity) .old_signature <- function(algorithm, merges, modularity, ...) { @@ -1581,9 +1581,9 @@ cluster_spinglass <- function( # BEGIN GENERATED ARG_HANDLE: cluster_spinglass, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("g")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("g")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn cluster_spinglass}.", i = "Spell out the full argument name.")) - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("s", "st", "g", "ga", "gam", "gamm")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("s", "st", "g", "ga", "gam", "gamm")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn cluster_spinglass}.") # Pre-3.0.0 signature: cluster_spinglass(graph, weights, vertex, spins, parupdate, start.temp, stop.temp, cool.fact, update.rule, gamma, implementation, gamma.minus) .old_signature <- function(weights, vertex, spins, parupdate, start.temp, stop.temp, cool.fact, update.rule, gamma, implementation, gamma.minus, ...) { @@ -2025,7 +2025,7 @@ cluster_walktrap <- function( # BEGIN GENERATED ARG_HANDLE: cluster_walktrap, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m", "me")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m", "me")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn cluster_walktrap}.") # Pre-3.0.0 signature: cluster_walktrap(graph, weights, steps, merges, modularity, membership) .old_signature <- function(weights, steps, merges, modularity, membership, ...) { @@ -2204,7 +2204,7 @@ cluster_edge_betweenness <- function( # BEGIN GENERATED ARG_HANDLE: cluster_edge_betweenness, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m", "me")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m", "me")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn cluster_edge_betweenness}.") # Pre-3.0.0 signature: cluster_edge_betweenness(graph, weights, directed, edge.betweenness, merges, bridges, modularity, membership) .old_signature <- function(weights, directed, edge.betweenness, merges, bridges, modularity, membership, ...) { @@ -2347,7 +2347,7 @@ cluster_fast_greedy <- function( # BEGIN GENERATED ARG_HANDLE: cluster_fast_greedy, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m", "me")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m", "me")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn cluster_fast_greedy}.") # Pre-3.0.0 signature: cluster_fast_greedy(graph, merges, modularity, membership, weights) .old_signature <- function(merges, modularity, membership, weights, ...) { diff --git a/R/components.R b/R/components.R index e1ef087a952..7dc4d9bb756 100644 --- a/R/components.R +++ b/R/components.R @@ -207,7 +207,7 @@ decompose <- function( # BEGIN GENERATED ARG_HANDLE: decompose, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn decompose}.") # Pre-3.0.0 signature: decompose(graph, mode, max.comps, min.vertices) .old_signature <- function(mode, max.comps, min.vertices, ...) { diff --git a/R/conversion.R b/R/conversion.R index 61791722a72..e0ac436a6b4 100644 --- a/R/conversion.R +++ b/R/conversion.R @@ -469,7 +469,7 @@ as_adjacency_matrix <- function( # BEGIN GENERATED ARG_HANDLE: as_adjacency_matrix, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("a", "at", "att")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("a", "at", "att")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn as_adjacency_matrix}.") # Pre-3.0.0 signature: as_adjacency_matrix(graph, type, attr, edges, names, sparse) .old_signature <- function(attr, edges, names, sparse, ...) { @@ -872,7 +872,7 @@ as_adj_list <- function( # BEGIN GENERATED ARG_HANDLE: as_adj_list, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn as_adj_list}.") # Pre-3.0.0 signature: as_adj_list(graph, mode, loops, multiple) .old_signature <- function(mode, loops, multiple, ...) { @@ -1422,7 +1422,7 @@ as_biadjacency_matrix <- function( # BEGIN GENERATED ARG_HANDLE: as_biadjacency_matrix, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("a", "at", "att")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("a", "at", "att")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn as_biadjacency_matrix}.") # Pre-3.0.0 signature: as_biadjacency_matrix(graph, types, attr, names, sparse) .old_signature <- function(attr, names, sparse, ...) { diff --git a/R/decomposition.R b/R/decomposition.R index 80a1f1fef7f..609644e900b 100644 --- a/R/decomposition.R +++ b/R/decomposition.R @@ -128,7 +128,7 @@ is_chordal <- function( # BEGIN GENERATED ARG_HANDLE: is_chordal, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("a", "al", "alp", "alph")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("a", "al", "alp", "alph")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn is_chordal}.") # Pre-3.0.0 signature: is_chordal(graph, alpha, alpham1, fillin, newgraph) .old_signature <- function(alpha, alpham1, fillin, newgraph, ...) { diff --git a/R/embedding.R b/R/embedding.R index da95f723479..e76d3ba1941 100644 --- a/R/embedding.R +++ b/R/embedding.R @@ -117,7 +117,7 @@ embed_adjacency_matrix <- function( # BEGIN GENERATED ARG_HANDLE: embed_adjacency_matrix, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("w")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("w")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn embed_adjacency_matrix}.") # Pre-3.0.0 signature: embed_adjacency_matrix(graph, no, weights, which, scaled, cvec, options) .old_signature <- function(weights, which, scaled, cvec, options, ...) { @@ -345,7 +345,7 @@ embed_laplacian_matrix <- function( # BEGIN GENERATED ARG_HANDLE: embed_laplacian_matrix, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("w")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("w")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn embed_laplacian_matrix}.") # Pre-3.0.0 signature: embed_laplacian_matrix(graph, no, weights, which, type, scaled, options) .old_signature <- function(weights, which, type, scaled, options, ...) { diff --git a/R/foreign.R b/R/foreign.R index d0768024e41..81ab555d833 100644 --- a/R/foreign.R +++ b/R/foreign.R @@ -839,7 +839,7 @@ graph_from_graphdb <- function( # BEGIN GENERATED ARG_HANDLE: graph_from_graphdb, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("p")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("p")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn graph_from_graphdb}.") # Pre-3.0.0 signature: graph_from_graphdb(url, prefix, type, nodes, pair, which, base, compressed, directed) .old_signature <- function(prefix, type, nodes, pair, which, base, compressed, directed, ...) { diff --git a/R/games.R b/R/games.R index eda1cb03a22..f098183c874 100644 --- a/R/games.R +++ b/R/games.R @@ -886,7 +886,7 @@ sample_pa <- function( # BEGIN GENERATED ARG_HANDLE: sample_pa, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("o", "ou", "out", "out.")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("o", "ou", "out", "out.")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn sample_pa}.") # Pre-3.0.0 signature: sample_pa(n, power, m, out.dist, out.seq, out.pref, zero.appeal, directed, algorithm, start.graph) .old_signature <- function(out.dist, out.seq, out.pref, zero.appeal, directed, algorithm, start.graph, ...) { @@ -1032,7 +1032,7 @@ pa <- function( # BEGIN GENERATED ARG_HANDLE: pa, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("o", "ou", "out", "out.")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("o", "ou", "out", "out.")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn pa}.") # Pre-3.0.0 signature: pa(n, power, m, out.dist, out.seq, out.pref, zero.appeal, directed, algorithm, start.graph) .old_signature <- function(out.dist, out.seq, out.pref, zero.appeal, directed, algorithm, start.graph, ...) { @@ -1918,9 +1918,9 @@ sample_pa_age <- function( # BEGIN GENERATED ARG_HANDLE: sample_pa_age, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("a", "ag", "agi", "agin", "aging", "aging.")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("a", "ag", "agi", "agin", "aging", "aging.")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn sample_pa_age}.", i = "Spell out the full argument name.")) - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("a", "ag", "o", "ou", "out", "out.", "d", "z", "ze", "zer", "zero", "zero.")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("a", "ag", "o", "ou", "out", "out.", "d", "z", "ze", "zer", "zero", "zero.")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn sample_pa_age}.") # Pre-3.0.0 signature: sample_pa_age(n, pa.exp, aging.exp, m, aging.bin, out.dist, out.seq, out.pref, directed, zero.deg.appeal, zero.age.appeal, deg.coef, age.coef, time.window) .old_signature <- function(aging.bin, out.dist, out.seq, out.pref, directed, zero.deg.appeal, zero.age.appeal, deg.coef, age.coef, time.window, ...) { @@ -2106,9 +2106,9 @@ pa_age <- function( # BEGIN GENERATED ARG_HANDLE: pa_age, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("a", "ag", "agi", "agin", "aging", "aging.")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("a", "ag", "agi", "agin", "aging", "aging.")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn pa_age}.", i = "Spell out the full argument name.")) - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("a", "ag", "o", "ou", "out", "out.", "d", "z", "ze", "zer", "zero", "zero.")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("a", "ag", "o", "ou", "out", "out.", "d", "z", "ze", "zer", "zero", "zero.")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn pa_age}.") # Pre-3.0.0 signature: pa_age(n, pa.exp, aging.exp, m, aging.bin, out.dist, out.seq, out.pref, directed, zero.deg.appeal, zero.age.appeal, deg.coef, age.coef, time.window) .old_signature <- function(aging.bin, out.dist, out.seq, out.pref, directed, zero.deg.appeal, zero.age.appeal, deg.coef, age.coef, time.window, ...) { @@ -2233,7 +2233,7 @@ sample_traits_callaway <- function( # BEGIN GENERATED ARG_HANDLE: sample_traits_callaway, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("t", "ty", "typ", "type")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("t", "ty", "typ", "type")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn sample_traits_callaway}.", i = "Spell out the full argument name.")) # Pre-3.0.0 signature: sample_traits_callaway(nodes, types, edge.per.step, type.dist, pref.matrix, directed) .old_signature <- function(edge.per.step, type.dist, pref.matrix, directed, ...) { @@ -2317,7 +2317,7 @@ traits_callaway <- function( # BEGIN GENERATED ARG_HANDLE: traits_callaway, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("t", "ty", "typ", "type")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("t", "ty", "typ", "type")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn traits_callaway}.", i = "Spell out the full argument name.")) # Pre-3.0.0 signature: traits_callaway(nodes, types, edge.per.step, type.dist, pref.matrix, directed) .old_signature <- function(edge.per.step, type.dist, pref.matrix, directed, ...) { @@ -2390,7 +2390,7 @@ sample_traits <- function( # BEGIN GENERATED ARG_HANDLE: sample_traits, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("t", "ty", "typ", "type")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("t", "ty", "typ", "type")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn sample_traits}.", i = "Spell out the full argument name.")) # Pre-3.0.0 signature: sample_traits(nodes, types, k, type.dist, pref.matrix, directed) .old_signature <- function(type.dist, pref.matrix, directed, ...) { @@ -2468,7 +2468,7 @@ traits <- function( # BEGIN GENERATED ARG_HANDLE: traits, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("t", "ty", "typ", "type")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("t", "ty", "typ", "type")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn traits}.", i = "Spell out the full argument name.")) # Pre-3.0.0 signature: traits(nodes, types, k, type.dist, pref.matrix, directed) .old_signature <- function(type.dist, pref.matrix, directed, ...) { @@ -2752,7 +2752,7 @@ sample_pref <- function( # BEGIN GENERATED ARG_HANDLE: sample_pref, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("t", "ty", "typ", "type")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("t", "ty", "typ", "type")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn sample_pref}.", i = "Spell out the full argument name.")) # Pre-3.0.0 signature: sample_pref(nodes, types, type.dist, fixed.sizes, pref.matrix, directed, loops) .old_signature <- function(type.dist, fixed.sizes, pref.matrix, directed, loops, ...) { @@ -2845,7 +2845,7 @@ pref <- function( # BEGIN GENERATED ARG_HANDLE: pref, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("t", "ty", "typ", "type")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("t", "ty", "typ", "type")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn pref}.", i = "Spell out the full argument name.")) # Pre-3.0.0 signature: pref(nodes, types, type.dist, fixed.sizes, pref.matrix, directed, loops) .old_signature <- function(type.dist, fixed.sizes, pref.matrix, directed, loops, ...) { @@ -2920,7 +2920,7 @@ sample_asym_pref <- function( # BEGIN GENERATED ARG_HANDLE: sample_asym_pref, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("t", "ty", "typ", "type")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("t", "ty", "typ", "type")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn sample_asym_pref}.", i = "Spell out the full argument name.")) # Pre-3.0.0 signature: sample_asym_pref(nodes, types, type.dist.matrix, pref.matrix, loops) .old_signature <- function(type.dist.matrix, pref.matrix, loops, ...) { @@ -3013,7 +3013,7 @@ asym_pref <- function( # BEGIN GENERATED ARG_HANDLE: asym_pref, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("t", "ty", "typ", "type")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("t", "ty", "typ", "type")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn asym_pref}.", i = "Spell out the full argument name.")) # Pre-3.0.0 signature: asym_pref(nodes, types, type.dist.matrix, pref.matrix, loops) .old_signature <- function(type.dist.matrix, pref.matrix, loops, ...) { diff --git a/R/hrg.R b/R/hrg.R index 5d9b5ae0eaa..107edd73ecc 100644 --- a/R/hrg.R +++ b/R/hrg.R @@ -243,7 +243,7 @@ fit_hrg <- function( # BEGIN GENERATED ARG_HANDLE: fit_hrg, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("s", "st")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("s", "st")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn fit_hrg}.") # Pre-3.0.0 signature: fit_hrg(graph, hrg, start, steps) .old_signature <- function(start, steps, ...) { @@ -542,7 +542,7 @@ predict_edges <- function( # BEGIN GENERATED ARG_HANDLE: predict_edges, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("n", "nu", "num", "num.")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("n", "nu", "num", "num.")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn predict_edges}.") # Pre-3.0.0 signature: predict_edges(graph, hrg, start, num.samples, num.bins) .old_signature <- function(start, num.samples, num.bins, ...) { diff --git a/R/incidence.R b/R/incidence.R index 7dc4364063d..2552c3bb912 100644 --- a/R/incidence.R +++ b/R/incidence.R @@ -197,7 +197,7 @@ graph_from_biadjacency_matrix <- function( # BEGIN GENERATED ARG_HANDLE: graph_from_biadjacency_matrix, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn graph_from_biadjacency_matrix}.") # Pre-3.0.0 signature: graph_from_biadjacency_matrix(incidence, directed, mode, multiple, weighted, add.names) .old_signature <- function(directed, mode, multiple, weighted, add.names, ...) { diff --git a/R/layout.R b/R/layout.R index 5c028fe8959..3fbcf7b97fe 100644 --- a/R/layout.R +++ b/R/layout.R @@ -956,7 +956,7 @@ layout_as_tree <- function( # BEGIN GENERATED ARG_HANDLE: layout_as_tree, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("r", "ro", "roo")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("r", "ro", "roo")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn layout_as_tree}.") # Pre-3.0.0 signature: layout_as_tree(graph, root, circular, rootlevel, mode, flip.y) .old_signature <- function(root, circular, rootlevel, mode, flip.y, ...) { @@ -1625,7 +1625,7 @@ layout_with_dh <- function( # BEGIN GENERATED ARG_HANDLE: layout_with_dh, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("c", "co", "coo", "w", "we", "wei", "weig", "weigh", "weight", "weight.", "weight.n", "weight.no", "weight.nod", "weight.node", "weight.node.", "weight.e", "weight.ed", "weight.edg", "weight.edge", "weight.edge.")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("c", "co", "coo", "w", "we", "wei", "weig", "weigh", "weight", "weight.", "weight.n", "weight.no", "weight.nod", "weight.node", "weight.node.", "weight.e", "weight.ed", "weight.edg", "weight.edge", "weight.edge.")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn layout_with_dh}.") # Pre-3.0.0 signature: layout_with_dh(graph, coords, maxiter, fineiter, cool.fact, weight.node.dist, weight.border, weight.edge.lengths, weight.edge.crossings, weight.node.edge.dist) .old_signature <- function(coords, maxiter, fineiter, cool.fact, weight.node.dist, weight.border, weight.edge.lengths, weight.edge.crossings, weight.node.edge.dist, ...) { @@ -1823,9 +1823,9 @@ layout_with_fr <- function( # BEGIN GENERATED ARG_HANDLE: layout_with_fr, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("g", "gr")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("g", "gr")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn layout_with_fr}.", i = "Spell out the full argument name.")) - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("c", "co", "coo", "m", "mi", "min", "ma", "max")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("c", "co", "coo", "m", "mi", "min", "ma", "max")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn layout_with_fr}.") # Pre-3.0.0 signature: layout_with_fr(graph, coords, dim, niter, start.temp, grid, weights, minx, maxx, miny, maxy, minz, maxz, coolexp, maxdelta, area, repulserad, maxiter) .old_signature <- function(coords, dim, niter, start.temp, grid, weights, minx, maxx, miny, maxy, minz, maxz, coolexp, maxdelta, area, repulserad, maxiter, ...) { @@ -2065,7 +2065,7 @@ layout_with_gem <- function( # BEGIN GENERATED ARG_HANDLE: layout_with_gem, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("t", "te", "tem", "temp", "temp.", "temp.m")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("t", "te", "tem", "temp", "temp.", "temp.m")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn layout_with_gem}.") # Pre-3.0.0 signature: layout_with_gem(graph, coords, maxiter, temp.max, temp.min, temp.init) .old_signature <- function(coords, maxiter, temp.max, temp.min, temp.init, ...) { @@ -2199,7 +2199,7 @@ layout_with_graphopt <- function( # BEGIN GENERATED ARG_HANDLE: layout_with_graphopt, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("s", "m", "ma", "sp", "spr", "spri", "sprin", "spring", "spring.")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("s", "m", "ma", "sp", "spr", "spri", "sprin", "spring", "spring.")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn layout_with_graphopt}.") # Pre-3.0.0 signature: layout_with_graphopt(graph, start, niter, charge, mass, spring.length, spring.constant, max.sa.movement) .old_signature <- function(start, niter, charge, mass, spring.length, spring.constant, max.sa.movement, ...) { @@ -2364,7 +2364,7 @@ layout_with_kk <- function( # BEGIN GENERATED ARG_HANDLE: layout_with_kk, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("c", "co", "coo", "m", "ma", "max", "mi", "min", "s")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("c", "co", "coo", "m", "ma", "max", "mi", "min", "s")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn layout_with_kk}.") # Pre-3.0.0 signature: layout_with_kk(graph, coords, dim, maxiter, epsilon, kkconst, weights, minx, maxx, miny, maxy, minz, maxz, niter, sigma, initemp, coolexp, start) .old_signature <- function(coords, dim, maxiter, epsilon, kkconst, weights, minx, maxx, miny, maxy, minz, maxz, niter, sigma, initemp, coolexp, start, ...) { @@ -2603,7 +2603,7 @@ layout_with_lgl <- function( # BEGIN GENERATED ARG_HANDLE: layout_with_lgl, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m", "ma", "max", "c", "r")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m", "ma", "max", "c", "r")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn layout_with_lgl}.") # Pre-3.0.0 signature: layout_with_lgl(graph, maxiter, maxdelta, area, coolexp, repulserad, cellsize, root) .old_signature <- function(maxiter, maxdelta, area, coolexp, repulserad, cellsize, root, ...) { @@ -3313,7 +3313,7 @@ norm_coords <- function( # BEGIN GENERATED ARG_HANDLE: norm_coords, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("x", "xm", "y", "ym", "z", "zm")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("x", "xm", "y", "ym", "z", "zm")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn norm_coords}.") # Pre-3.0.0 signature: norm_coords(layout, xmin, xmax, ymin, ymax, zmin, zmax) .old_signature <- function(xmin, xmax, ymin, ymax, zmin, zmax, ...) { diff --git a/R/migration-fixture.R b/R/migration-fixture.R index 9d9de569d20..8b8cdfd108f 100644 --- a/R/migration-fixture.R +++ b/R/migration-fixture.R @@ -20,7 +20,7 @@ migration_fixture <- function( # BEGIN GENERATED ARG_HANDLE: migration_fixture, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("w", "we", "wei", "weig", "weigh")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("w", "we", "wei", "weig", "weigh")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn migration_fixture}.") # Pre-3.0.0 signature: migration_fixture(graph, n, weight, kind, directed) .old_signature <- function(weight, kind, directed, ...) { @@ -84,7 +84,7 @@ migration_fixture_prefix <- function( # BEGIN GENERATED ARG_HANDLE: migration_fixture_prefix, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("d", "di")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("d", "di")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn migration_fixture_prefix}.", i = "Spell out the full argument name.")) # Pre-3.0.0 signature: migration_fixture_prefix(dimvector, p, dim, permutation) .old_signature <- function(dim, permutation, ...) { @@ -147,7 +147,7 @@ migration_fixture_shadow <- function( # BEGIN GENERATED ARG_HANDLE: migration_fixture_shadow, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("a", "at", "att")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("a", "at", "att")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn migration_fixture_shadow}.") # Pre-3.0.0 signature: migration_fixture_shadow(graph, attr, names, c) .old_signature <- function(attr, names, c, ...) { diff --git a/R/motifs.R b/R/motifs.R index 97a526b2905..4ac4ef36b00 100644 --- a/R/motifs.R +++ b/R/motifs.R @@ -182,7 +182,7 @@ motifs <- function( # BEGIN GENERATED ARG_HANDLE: motifs, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("c")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("c")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn motifs}.") # Pre-3.0.0 signature: motifs(graph, size, cut.prob, callback) .old_signature <- function(cut.prob, callback, ...) { @@ -368,9 +368,9 @@ sample_motifs <- function( # BEGIN GENERATED ARG_HANDLE: sample_motifs, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("s")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("s")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn sample_motifs}.", i = "Spell out the full argument name.")) - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("s", "sa", "sam", "samp", "sampl")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("s", "sa", "sam", "samp", "sampl")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn sample_motifs}.") # Pre-3.0.0 signature: sample_motifs(graph, size, cut.prob, sample.size, sample) .old_signature <- function(cut.prob, sample.size, sample, ...) { diff --git a/R/plot.shapes.R b/R/plot.shapes.R index dc1eb672675..59f89b25b2a 100644 --- a/R/plot.shapes.R +++ b/R/plot.shapes.R @@ -383,7 +383,7 @@ add_shape <- function( # BEGIN GENERATED ARG_HANDLE: add_shape, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("p")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("p")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn add_shape}.") # Pre-3.0.0 signature: add_shape(shape, clip, plot, parameters) .old_signature <- function(clip, plot, parameters, ...) { diff --git a/R/rewire.R b/R/rewire.R index 775e449d68a..2615f6035f8 100644 --- a/R/rewire.R +++ b/R/rewire.R @@ -139,7 +139,7 @@ each_edge <- function( # BEGIN GENERATED ARG_HANDLE: each_edge, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn each_edge}.") # Pre-3.0.0 signature: each_edge(prob, loops, multiple, mode) .old_signature <- function(loops, multiple, mode, ...) { diff --git a/R/similarity.R b/R/similarity.R index 1b4b2313b15..705821bc040 100644 --- a/R/similarity.R +++ b/R/similarity.R @@ -71,7 +71,7 @@ similarity <- function( # BEGIN GENERATED ARG_HANDLE: similarity, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn similarity}.") # Pre-3.0.0 signature: similarity(graph, vids, mode, loops, method) .old_signature <- function(mode, loops, method, ...) { diff --git a/R/structural-properties.R b/R/structural-properties.R index c2970ebc5a9..936c7e98e9c 100644 --- a/R/structural-properties.R +++ b/R/structural-properties.R @@ -986,7 +986,7 @@ mean_distance <- function( # BEGIN GENERATED ARG_HANDLE: mean_distance, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("d")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("d")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn mean_distance}.") # Pre-3.0.0 signature: mean_distance(graph, weights, directed, unconnected, details) .old_signature <- function(weights, directed, unconnected, details, ...) { @@ -2733,7 +2733,7 @@ ego_size <- function( # BEGIN GENERATED ARG_HANDLE: ego_size, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn ego_size}.") # Pre-3.0.0 signature: ego_size(graph, order, nodes, mode, mindist) .old_signature <- function(mode, mindist, ...) { @@ -2892,7 +2892,7 @@ ego <- function( # BEGIN GENERATED ARG_HANDLE: ego, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn ego}.") # Pre-3.0.0 signature: ego(graph, order, nodes, mode, mindist) .old_signature <- function(mode, mindist, ...) { @@ -2971,7 +2971,7 @@ make_ego_graph <- function( # BEGIN GENERATED ARG_HANDLE: make_ego_graph, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("m")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("m")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn make_ego_graph}.") # Pre-3.0.0 signature: make_ego_graph(graph, order, nodes, mode, mindist) .old_signature <- function(mode, mindist, ...) { diff --git a/R/topology.R b/R/topology.R index 1069c076de5..7f916398e55 100644 --- a/R/topology.R +++ b/R/topology.R @@ -198,7 +198,7 @@ graph.subisomorphic.lad <- function( # BEGIN GENERATED ARG_HANDLE: graph.subisomorphic.lad, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_forbidden <- base::intersect(base::names(base::sys.call()), base::c("t")) + .arg_forbidden <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::sys.call())[-1L])), base::c("t")) if (base::length(.arg_forbidden) > 0L) cli::cli_abort(base::c("Argument {.arg {(.arg_forbidden)}} matches multiple formal arguments of {.fn graph.subisomorphic.lad}.", i = "Spell out the full argument name.")) # Pre-3.0.0 signature: graph.subisomorphic.lad(pattern, target, domains, induced, map, all.maps, time.limit) .old_signature <- function(domains, induced, map, all.maps, time.limit, ...) { @@ -442,7 +442,7 @@ graph.isomorphic.bliss <- function( # BEGIN GENERATED ARG_HANDLE: graph.isomorphic.bliss, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("c", "co", "col", "colo", "color", "colors")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("c", "co", "col", "colo", "color", "colors")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn graph.isomorphic.bliss}.") # Pre-3.0.0 signature: graph.isomorphic.bliss(graph1, graph2, colors1, colors2, sh) .old_signature <- function(colors1, colors2, sh, ...) { @@ -502,7 +502,7 @@ graph.isomorphic.vf2 <- function( # BEGIN GENERATED ARG_HANDLE: graph.isomorphic.vf2, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("v", "ve", "ver", "vert", "verte", "vertex", "vertex.", "vertex.c", "vertex.co", "vertex.col", "vertex.colo", "vertex.color", "e", "ed", "edg", "edge", "edge.", "edge.c", "edge.co", "edge.col", "edge.colo", "edge.color")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("v", "ve", "ver", "vert", "verte", "vertex", "vertex.", "vertex.c", "vertex.co", "vertex.col", "vertex.colo", "vertex.color", "e", "ed", "edg", "edge", "edge.", "edge.c", "edge.co", "edge.col", "edge.colo", "edge.color")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn graph.isomorphic.vf2}.") # Pre-3.0.0 signature: graph.isomorphic.vf2(graph1, graph2, vertex.color1, vertex.color2, edge.color1, edge.color2) .old_signature <- function(vertex.color1, vertex.color2, edge.color1, edge.color2, ...) { @@ -573,7 +573,7 @@ graph.subisomorphic.vf2 <- function( # BEGIN GENERATED ARG_HANDLE: graph.subisomorphic.vf2, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("v", "ve", "ver", "vert", "verte", "vertex", "vertex.", "vertex.c", "vertex.co", "vertex.col", "vertex.colo", "vertex.color", "e", "ed", "edg", "edge", "edge.", "edge.c", "edge.co", "edge.col", "edge.colo", "edge.color")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("v", "ve", "ver", "vert", "verte", "vertex", "vertex.", "vertex.c", "vertex.co", "vertex.col", "vertex.colo", "vertex.color", "e", "ed", "edg", "edge", "edge.", "edge.c", "edge.co", "edge.col", "edge.colo", "edge.color")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn graph.subisomorphic.vf2}.") # Pre-3.0.0 signature: graph.subisomorphic.vf2(graph1, graph2, vertex.color1, vertex.color2, edge.color1, edge.color2) .old_signature <- function(vertex.color1, vertex.color2, edge.color1, edge.color2, ...) { @@ -815,7 +815,7 @@ graph.count.isomorphisms.vf2 <- function( # BEGIN GENERATED ARG_HANDLE: graph.count.isomorphisms.vf2, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("v", "ve", "ver", "vert", "verte", "vertex", "vertex.", "vertex.c", "vertex.co", "vertex.col", "vertex.colo", "vertex.color", "e", "ed", "edg", "edge", "edge.", "edge.c", "edge.co", "edge.col", "edge.colo", "edge.color")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("v", "ve", "ver", "vert", "verte", "vertex", "vertex.", "vertex.c", "vertex.co", "vertex.col", "vertex.colo", "vertex.color", "e", "ed", "edg", "edge", "edge.", "edge.c", "edge.co", "edge.col", "edge.colo", "edge.color")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn graph.count.isomorphisms.vf2}.") # Pre-3.0.0 signature: graph.count.isomorphisms.vf2(graph1, graph2, vertex.color1, vertex.color2, edge.color1, edge.color2) .old_signature <- function(vertex.color1, vertex.color2, edge.color1, edge.color2, ...) { @@ -966,7 +966,7 @@ graph.count.subisomorphisms.vf2 <- function( # BEGIN GENERATED ARG_HANDLE: graph.count.subisomorphisms.vf2, do not edit, see tools/generate-migrations.R # fmt: skip if (...length() > 0L) { - .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), base::c("v", "ve", "ver", "vert", "verte", "vertex", "vertex.", "vertex.c", "vertex.co", "vertex.col", "vertex.colo", "vertex.color", "e", "ed", "edg", "edge", "edge.", "edge.c", "edge.co", "edge.col", "edge.colo", "edge.color")) + .arg_ambiguous <- base::intersect(base::names(base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), base::as.list(base::substitute(...())))), base::c("v", "ve", "ver", "vert", "verte", "vertex", "vertex.", "vertex.c", "vertex.co", "vertex.col", "vertex.colo", "vertex.color", "e", "ed", "edg", "edge", "edge.", "edge.c", "edge.co", "edge.col", "edge.colo", "edge.color")) if (base::length(.arg_ambiguous) > 0L) cli::cli_abort("Argument {.arg {(.arg_ambiguous[[1L]])}} matches multiple arguments of {.fn graph.count.subisomorphisms.vf2}.") # Pre-3.0.0 signature: graph.count.subisomorphisms.vf2(graph1, graph2, vertex.color1, vertex.color2, edge.color1, edge.color2) .old_signature <- function(vertex.color1, vertex.color2, edge.color1, edge.color2, ...) { diff --git a/tests/testthat/_snaps/migration-fixture.md b/tests/testthat/_snaps/migration-fixture.md index a801fbf30fa..6f7200aeb87 100644 --- a/tests/testthat/_snaps/migration-fixture.md +++ b/tests/testthat/_snaps/migration-fixture.md @@ -50,6 +50,23 @@ [1] FALSE +# a named empty slot is not an ambiguous abbreviation + + Code + migration_fixture_shadow("g", a = 1) + Condition + Error in `migration_fixture_shadow()`: + ! Argument `a` matches multiple arguments of `migration_fixture_shadow()`. + +# a named empty slot is not a forbidden prefix + + Code + migration_fixture_prefix(1:2, 0.5, d = 3) + Condition + Error in `migration_fixture_prefix()`: + ! Argument `d` matches multiple formal arguments of `migration_fixture_prefix()`. + i Spell out the full argument name. + # empty argument slot messages Code diff --git a/tests/testthat/test-migration-fixture.R b/tests/testthat/test-migration-fixture.R index 8746f9bd7be..3f5c584d747 100644 --- a/tests/testthat/test-migration-fixture.R +++ b/tests/testthat/test-migration-fixture.R @@ -143,6 +143,65 @@ test_that("several empty slots each consume a position", { expect_equal(res$type, "out") }) +# The two guards that run before `.old_signature()` read argument *names* and +# never look at the values, so an empty slot used to trip them even though it +# supplies nothing. `f(x, a = )` returned a matrix on 2.3.3 and errored with +# "matches multiple arguments" on the dev version. + +test_that("a named empty slot is not an ambiguous abbreviation", { + rlang::local_options(lifecycle_verbosity = "warning") + + # `w` could mean `weights` or the deprecated `weight`; empty, it means + # neither, and the old signature would have matched it by position. + expect_no_warning(res <- migration_fixture("g", 5, w = )) + expect_equal(res$weights, NULL) + + # `a` could mean `attr` or `weights`-via-`attr` in the shadow fixture. + expect_no_warning(res <- migration_fixture_shadow("g", a = )) + expect_equal(res$weights, NULL) + + # A value in the same slot is still rejected. + expect_snapshot(error = TRUE, migration_fixture_shadow("g", a = 1)) +}) + +test_that("a named empty slot is not a forbidden prefix", { + rlang::local_options(lifecycle_verbosity = "warning") + + # `d` is a strict prefix of both `dimvector` and `dim`. + expect_no_warning(res <- migration_fixture_prefix(1:2, 0.5, d = )) + expect_equal(res$dim, NULL) + + # A value in the same slot is still rejected. + expect_snapshot(error = TRUE, migration_fixture_prefix(1:2, 0.5, d = 3)) +}) + +test_that("the two shapes from #2646 behave as they do on CRAN", { + # The reproducers verbatim, tied to the bug rather than to the fixture. + rlang::local_options(lifecycle_verbosity = "warning") + m <- matrix(c(0, 1, 1, 0), 2, dimnames = list(c("a", "b"), c("a", "b"))) + d <- data.frame(from = "a", to = "b") + + expect_no_warning( + g <- graph_from_adjacency_matrix( + adjmatrix = m, + mode = "undirected", + weighted = TRUE, + ) + ) + expect_ecount(g, 1) + + expect_no_warning(h <- graph_from_data_frame(d, , directed = FALSE)) + expect_ecount(h, 1) + expect_false(is_directed(h)) + + # A named empty slot on a real migrated function, which is what the guards + # were getting wrong. + expect_equal( + dim(as_adjacency_matrix(make_ring(4), a = , sparse = FALSE)), + c(4L, 4L) + ) +}) + test_that("a `...` of nothing but empty slots does not engage recovery", { rlang::local_options(lifecycle_verbosity = "warning") expect_no_warning(res <- migration_fixture("g", 5, , )) diff --git a/tools/generate-migrations.R b/tools/generate-migrations.R index c67fb4ea279..8ba051b3eec 100644 --- a/tools/generate-migrations.R +++ b/tools/generate-migrations.R @@ -514,6 +514,26 @@ render_vector <- function(items) { # The block opens with `# fmt: skip` so `air` leaves it alone: the layout is this # generator's, which buys back the vertical space the unrolling costs and drops # the code that used to predict how `air` would wrap. +# Both guards below read argument *names* and never look at the values, which +# made them the one place an empty slot still diverged from the pre-migration +# behaviour: `as_adjacency_matrix(make_ring(4), a = )` errors with "matches +# multiple arguments" on the dev version and returns a 4x4 matrix on 2.3.3. An +# empty slot supplies nothing, so it cannot be ambiguous between two arguments +# and cannot conflict with a formal -- the old signature would have matched it +# by position and left the formal missing. `.old_signature()` already gets this +# right, via `base::missing()`; the guards run before it and did not. +# +# The empty slot is the empty symbol, which is a symbol whose name is the empty +# string. `Filter()` keeps this to one expression, which matters because the +# block is `# fmt: skip` and every line of it is already long. +drop_empty_slots <- function(expr) { + paste0( + "base::Filter(function(.x) !(base::is.symbol(.x) && !base::nzchar(base::as.character(.x))), ", + expr, + ")" + ) +} + render_arg_handle <- function(entry) { fn <- entry$fn old <- entry$recover_old @@ -524,7 +544,9 @@ render_arg_handle <- function(entry) { guards <- c( guards, paste0( - " .arg_forbidden <- base::intersect(base::names(base::sys.call()), ", + " .arg_forbidden <- base::intersect(base::names(", + drop_empty_slots("base::as.list(base::sys.call())[-1L]"), + "), ", render_vector(quote_items(entry$forbidden_tags)), ")" ), @@ -540,7 +562,9 @@ render_arg_handle <- function(entry) { guards <- c( guards, paste0( - " .arg_ambiguous <- base::intersect(base::names(base::substitute(...())), ", + " .arg_ambiguous <- base::intersect(base::names(", + drop_empty_slots("base::as.list(base::substitute(...()))"), + "), ", render_vector(quote_items(ambiguous)), ")" ),