From b395fe4e2ee05f53958f8f05e9199caba5bbdb0d Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 20 Oct 2022 11:23:22 +0200 Subject: [PATCH 01/12] Use chained error in `stop_location_negative_missing()` --- NAMESPACE | 2 + R/subscript-loc.R | 66 ++++++++++++++++---------- R/subscript.R | 36 ++++++++++++++ tests/testthat/_snaps/slice-assign.md | 5 +- tests/testthat/_snaps/slice.md | 5 +- tests/testthat/_snaps/subscript-loc.md | 30 +++++++----- 6 files changed, 103 insertions(+), 41 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index e752736e0..84a176d1b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -6,6 +6,7 @@ S3method("$",vctrs_list_of) S3method("$",vctrs_rcrd) S3method("$",vctrs_sclr) S3method("$",vctrs_vctr) +S3method("$<-",vctrs_error_subscript_type) S3method("$<-",vctrs_list_of) S3method("$<-",vctrs_rcrd) S3method("$<-",vctrs_sclr) @@ -34,6 +35,7 @@ S3method("[[",vctrs_list_of) S3method("[[",vctrs_rcrd) S3method("[[",vctrs_sclr) S3method("[[",vctrs_vctr) +S3method("[[<-",vctrs_error_subscript_type) S3method("[[<-",vctrs_list_of) S3method("[[<-",vctrs_rcrd) S3method("[[<-",vctrs_sclr) diff --git a/R/subscript-loc.R b/R/subscript-loc.R index 3fabb24b3..600a4d1af 100644 --- a/R/subscript-loc.R +++ b/R/subscript-loc.R @@ -286,30 +286,36 @@ vec_as_location2_result <- function(i, stop_location_negative_missing <- function(i, ..., call = caller_env()) { - cnd_signal(new_error_subscript_type( + causal <- error_cnd( + i = i, + ..., + header = cnd_header_location_negative_missing, + call = NULL, + use_cli_format = TRUE + ) + contextual <- new_error_subscript_type( i, ..., - body = cnd_body_vctrs_error_location_negative_missing, - call = call - )) + body = function(...) chr(), + call = call, + parent = causal + ) + + cnd_signal(contextual) } -cnd_body_vctrs_error_location_negative_missing <- function(cnd, ...) { + +cnd_header_location_negative_missing <- function(cnd, ...) { missing_loc <- which(is.na(cnd$i)) - arg <- append_arg("Subscript", cnd$subscript_arg) + arg <- cnd_subscript_arg(cnd) - if (length(missing_loc) == 1) { - loc <- glue::glue("{arg} has a missing value at location {missing_loc}.") - } else { - n_loc <- length(missing_loc) - missing_loc <- ensure_full_stop(enumerate(missing_loc)) - loc <- glue::glue( - "{arg} has {n_loc} missing values at locations {missing_loc}" + n_loc <- length(missing_loc) + + c( + "Negative locations can't have missing values.", + "x" = cli::format_inline( + "{arg} has {n_loc} missing value{?s} at location{?s} {missing_loc}." ) - } - format_error_bullets(c( - x = "Negative locations can't have missing values.", - i = loc - )) + ) } stop_location_negative_positive <- function(i, ..., call = caller_env()) { @@ -371,18 +377,28 @@ cnd_bullets_location2_need_positive <- function(cnd, ...) { } stop_location_negative <- function(i, ..., call = caller_env()) { - cnd_signal(new_error_subscript_type( + causal <- error_cnd( + i = i, + header = cnd_header_location_need_non_negative, + ..., + call = NULL, + use_cli_format = TRUE + ) + contextual <- new_error_subscript_type( i, - body = cnd_bullets_location_need_non_negative, ..., - call = call - )) + body = function(...) chr(), + call = call, + parent = causal + ) + + cnd_signal(contextual) } -cnd_bullets_location_need_non_negative <- function(cnd, ...) { +cnd_header_location_need_non_negative <- function(cnd, ...) { cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) - format_error_bullets(c( + c( x = glue::glue_data(cnd, "{subscript_arg} can't contain negative locations.") - )) + ) } stop_location_zero <- function(i, ..., call = caller_env()) { diff --git a/R/subscript.R b/R/subscript.R index 7b87c0ba0..f4afd8550 100644 --- a/R/subscript.R +++ b/R/subscript.R @@ -173,6 +173,42 @@ new_error_subscript_type <- function(i, ) } +# Subscripts errors are currently customised by rethrowing errors with +# special fields. The setter methods forward these fields to parent +# errors so that causal errors may benefit from these customisations. + +#' @export +`$<-.vctrs_error_subscript_type` <- function(x, i, value) { + x <- NextMethod() + i <- as_string(i) + + if (!is_null(x[["parent"]]) && is_subscript_field(i)) { + x[["parent"]][[i]] <- value + } + + x +} +#' @export +`[[<-.vctrs_error_subscript_type` <- function(x, i, value) { + x <- NextMethod() + + if (!is_null(x[["parent"]]) && is_subscript_field(i)) { + x[["parent"]][[i]] <- value + } + + x +} + +is_subscript_field <- function(x) { + is_character(x) && x %in% c( + "i", + "subscript_arg", + "subscript_elt", + "subscript_action" + ) +} + + #' @export cnd_header.vctrs_error_subscript_type <- function(cnd) { action <- cnd_subscript_action(cnd) diff --git a/tests/testthat/_snaps/slice-assign.md b/tests/testthat/_snaps/slice-assign.md index 5d1d2b540..b494eac8e 100644 --- a/tests/testthat/_snaps/slice-assign.md +++ b/tests/testthat/_snaps/slice-assign.md @@ -82,8 +82,9 @@ Error: ! Must assign to elements with a valid subscript vector. - x Negative locations can't have missing values. - i Subscript has a missing value at location 2. + Caused by error: + ! Negative locations can't have missing values. + x Subscript has 1 missing value at location 2. # `vec_assign()` error args can be overridden diff --git a/tests/testthat/_snaps/slice.md b/tests/testthat/_snaps/slice.md index 62fed97f0..fd8864bcb 100644 --- a/tests/testthat/_snaps/slice.md +++ b/tests/testthat/_snaps/slice.md @@ -60,8 +60,9 @@ Condition Error in `vec_slice()`: ! Must subset elements with a valid subscript vector. - x Negative locations can't have missing values. - i Subscript `i` has a missing value at location 2. + Caused by error: + ! Negative locations can't have missing values. + x `i` has 1 missing value at location 2. --- diff --git a/tests/testthat/_snaps/subscript-loc.md b/tests/testthat/_snaps/subscript-loc.md index 641f0af34..c2afd8045 100644 --- a/tests/testthat/_snaps/subscript-loc.md +++ b/tests/testthat/_snaps/subscript-loc.md @@ -354,8 +354,9 @@ Error: ! Must subset elements with a valid subscript vector. - x Negative locations can't have missing values. - i Subscript `-c(1L, NA)` has a missing value at location 2. + Caused by error: + ! Negative locations can't have missing values. + x `-c(1L, NA)` has 1 missing value at location 2. Code (expect_error(vec_as_location(-c(1L, rep(NA, 10)), 30), class = "vctrs_error_subscript_type") ) @@ -363,8 +364,9 @@ Error: ! Must subset elements with a valid subscript vector. - x Negative locations can't have missing values. - i Subscript `-c(1L, rep(NA, 10))` has 10 missing values at locations 2, 3, 4, 5, 6, etc. + Caused by error: + ! Negative locations can't have missing values. + x `-c(1L, rep(NA, 10))` has 10 missing values at locations 2, 3, 4, 5, 6, 7, 8, 9, 10, and 11. # vec_as_location() checks for mix of negative and positive locations @@ -669,8 +671,9 @@ Condition Error: ! Must subset elements with a valid subscript vector. - x Negative locations can't have missing values. - i Subscript `x` has 2 missing values at locations 2 and 3. + Caused by error: + ! Negative locations can't have missing values. + x `x` has 2 missing values at locations 2 and 3. --- @@ -679,8 +682,9 @@ Condition Error: ! Must subset elements with a valid subscript vector. - x Negative locations can't have missing values. - i Subscript `x` has 2 missing values at locations 2 and 3. + Caused by error: + ! Negative locations can't have missing values. + x `x` has 2 missing values at locations 2 and 3. # empty string character indices never match empty string names (#1489) @@ -760,8 +764,9 @@ Error in `my_function()`: ! Must subset elements with a valid subscript vector. - x Negative locations can't have missing values. - i Subscript `foo` has a missing value at location 2. + Caused by error: + ! Negative locations can't have missing values. + x `foo` has 1 missing value at location 2. Code (expect_error(vec_as_location(c(-1, 1), 3, arg = "foo", call = call( "my_function")), class = "vctrs_error_subscript_type")) @@ -845,8 +850,9 @@ Error: ! Must rename columns with a valid subscript vector. - x Negative locations can't have missing values. - i Subscript `foo(bar)` has a missing value at location 2. + Caused by error: + ! Negative locations can't have missing values. + x `foo(bar)` has 1 missing value at location 2. Code (expect_error(with_tibble_cols(vec_as_location(c(-1, 1), 3)), class = "vctrs_error_subscript_type") ) From 0145b39ed077a291cb8f8e5140869575af0cdaa0 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 20 Oct 2022 12:16:12 +0200 Subject: [PATCH 02/12] Use "can't" phrasing in headers of subscript errors --- R/subscript.R | 14 ++- tests/testthat/_snaps/error-call.md | 10 +- tests/testthat/_snaps/slice-assign.md | 8 +- tests/testthat/_snaps/slice-chop.md | 8 +- tests/testthat/_snaps/slice.md | 10 +- tests/testthat/_snaps/subscript-loc.md | 157 +++++++++++++------------ tests/testthat/_snaps/subscript.md | 38 +++--- 7 files changed, 128 insertions(+), 117 deletions(-) diff --git a/R/subscript.R b/R/subscript.R index f4afd8550..f6a3961cb 100644 --- a/R/subscript.R +++ b/R/subscript.R @@ -211,12 +211,20 @@ is_subscript_field <- function(x) { #' @export cnd_header.vctrs_error_subscript_type <- function(cnd) { - action <- cnd_subscript_action(cnd) + arg <- cnd[["subscript_arg"]] + if (is_subscript_arg(arg)) { + with <- glue::glue(" with {format_subscript_arg(arg)}") + } else { + with <- "" + } + + action <- cnd_subscript_action(cnd, assign_to = FALSE) elt <- cnd_subscript_element(cnd) + if (cnd_subscript_scalar(cnd)) { - glue::glue("Must {action} {elt[[1]]} with a single valid subscript.") + glue::glue("Can't {action} {elt[[1]]}{with}.") } else { - glue::glue("Must {action} {elt[[2]]} with a valid subscript vector.") + glue::glue("Can't {action} {elt[[2]]}{with}.") } } #' @export diff --git a/tests/testthat/_snaps/error-call.md b/tests/testthat/_snaps/error-call.md index eb9c1af3b..9fa9ddc08 100644 --- a/tests/testthat/_snaps/error-call.md +++ b/tests/testthat/_snaps/error-call.md @@ -218,7 +218,7 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `my_arg`. x Can't convert from `my_arg` to due to loss of precision. --- @@ -228,7 +228,7 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Can't convert from to due to loss of precision. --- @@ -238,7 +238,7 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `my_arg`. x `my_arg` must be logical, numeric, or character, not an empty list. --- @@ -258,7 +258,7 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript can't contain missing values. x It has a missing value at location 1. @@ -326,7 +326,7 @@ Output Error in `vec_slice()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `i`. x `i` must be logical, numeric, or character, not an environment. # list_sizes() reports error context diff --git a/tests/testthat/_snaps/slice-assign.md b/tests/testthat/_snaps/slice-assign.md index b494eac8e..6cd514bb1 100644 --- a/tests/testthat/_snaps/slice-assign.md +++ b/tests/testthat/_snaps/slice-assign.md @@ -16,7 +16,7 @@ Output Error: - ! Must assign to elements with a valid subscript vector. + ! Can't assign elements. x Logical subscript must be size 1 or 2, not 3. --- @@ -27,7 +27,7 @@ Output Error: - ! Must assign to elements with a valid subscript vector. + ! Can't assign elements. x Logical subscript must be size 1 or 32, not 2. # must assign existing elements @@ -72,7 +72,7 @@ Output Error: - ! Must assign to elements with a valid subscript vector. + ! Can't assign elements. x Negative and positive locations can't be mixed. i Subscript has a positive value at location 2. Code @@ -81,7 +81,7 @@ Output Error: - ! Must assign to elements with a valid subscript vector. + ! Can't assign elements. Caused by error: ! Negative locations can't have missing values. x Subscript has 1 missing value at location 2. diff --git a/tests/testthat/_snaps/slice-chop.md b/tests/testthat/_snaps/slice-chop.md index 97d2cd8d1..f79e057c2 100644 --- a/tests/testthat/_snaps/slice-chop.md +++ b/tests/testthat/_snaps/slice-chop.md @@ -158,7 +158,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript can't contain `0` values. i It has a `0` value at location 1. Code @@ -167,7 +167,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript can't contain negative locations. # list_unchop() fails with complex foreign S3 classes @@ -298,7 +298,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript must be numeric, not the string "x". Code (expect_error(list_unchop(list(1), indices = list(foobar(1L))), class = "vctrs_error_subscript_type") @@ -306,7 +306,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript must be numeric, not a object. # can ignore names in `list_unchop()` by providing a `zap()` name-spec (#232) diff --git a/tests/testthat/_snaps/slice.md b/tests/testthat/_snaps/slice.md index fd8864bcb..da8a10a7a 100644 --- a/tests/testthat/_snaps/slice.md +++ b/tests/testthat/_snaps/slice.md @@ -5,7 +5,7 @@ Output Error in `vec_slice()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `i`. x `i` must be logical, numeric, or character, not a object. Code (expect_error(vec_slice(1:3, matrix(TRUE, nrow = 1)), class = "vctrs_error_subscript_type") @@ -13,7 +13,7 @@ Output Error in `vec_slice()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `i`. x Subscript `i` must be a simple vector, not a matrix. # can't index beyond the end of a vector @@ -42,7 +42,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `2^31`. x Can't convert from `2^31` to due to loss of precision. # Unnamed vector with character subscript is caught @@ -59,7 +59,7 @@ vec_slice(1:3, -c(1L, NA)) Condition Error in `vec_slice()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `i`. Caused by error: ! Negative locations can't have missing values. x `i` has 1 missing value at location 2. @@ -70,7 +70,7 @@ vec_slice(1:3, c(-1L, 1L)) Condition Error in `vec_slice()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `i`. x Negative and positive locations can't be mixed. i Subscript `i` has a positive value at location 2. diff --git a/tests/testthat/_snaps/subscript-loc.md b/tests/testthat/_snaps/subscript-loc.md index c2afd8045..9c74a8a0f 100644 --- a/tests/testthat/_snaps/subscript-loc.md +++ b/tests/testthat/_snaps/subscript-loc.md @@ -6,7 +6,7 @@ Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `TRUE`. x `TRUE` must be numeric or character, not `TRUE`. Code (expect_error(vec_as_location2(mtcars, 10L), class = "vctrs_error_subscript_type") @@ -14,7 +14,7 @@ Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `mtcars`. x `mtcars` must be numeric or character, not a object. Code (expect_error(vec_as_location2(env(), 10L), class = "vctrs_error_subscript_type") @@ -22,7 +22,7 @@ Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `env()`. x `env()` must be numeric or character, not an environment. Code (expect_error(vec_as_location2(foobar(), 10L), class = "vctrs_error_subscript_type") @@ -30,21 +30,21 @@ Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `foobar()`. x `foobar()` must be numeric or character, not a object. Code (expect_error(vec_as_location2(2.5, 10L), class = "vctrs_error_subscript_type")) Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `2.5`. x Can't convert from `2.5` to due to loss of precision. Code (expect_error(vec_as_location2(Inf, 10L), class = "vctrs_error_subscript_type")) Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `Inf`. x Can't convert from `Inf` to due to loss of precision. Code (expect_error(vec_as_location2(-Inf, 10L), class = "vctrs_error_subscript_type") @@ -52,7 +52,7 @@ Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `-Inf`. x Can't convert from `-Inf` to due to loss of precision. Code # Idem with custom `arg` @@ -61,7 +61,7 @@ Output Error in `my_function()`: - ! Must extract element with a single valid subscript. + ! Can't extract element with `foo`. x `foo` must be numeric or character, not a object. Code (expect_error(vec_as_location2(2.5, 3L, arg = "foo", call = call("my_function")), @@ -69,7 +69,7 @@ Output Error in `my_function()`: - ! Must extract element with a single valid subscript. + ! Can't extract element with `foo`. x Can't convert from `foo` to due to loss of precision. Code (expect_error(with_tibble_rows(vec_as_location2(TRUE)), class = "vctrs_error_subscript_type") @@ -77,7 +77,7 @@ Output Error: - ! Must remove row with a single valid subscript. + ! Can't remove row with `foo(bar)`. x `foo(bar)` must be numeric or character, not `TRUE`. # vec_as_location() requires integer, character, or logical inputs @@ -88,7 +88,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `mtcars`. x `mtcars` must be logical, numeric, or character, not a object. Code (expect_error(vec_as_location(env(), 10L), class = "vctrs_error_subscript_type") @@ -96,7 +96,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `env()`. x `env()` must be logical, numeric, or character, not an environment. Code (expect_error(vec_as_location(foobar(), 10L), class = "vctrs_error_subscript_type") @@ -104,14 +104,14 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `foobar()`. x `foobar()` must be logical, numeric, or character, not a object. Code (expect_error(vec_as_location(2.5, 10L), class = "vctrs_error_subscript_type")) Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `2.5`. x Can't convert from `2.5` to due to loss of precision. Code (expect_error(vec_as_location(list(), 10L), class = "vctrs_error_subscript_type") @@ -119,7 +119,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `list()`. x `list()` must be logical, numeric, or character, not an empty list. Code (expect_error(vec_as_location(function() NULL, 10L), class = "vctrs_error_subscript_type") @@ -127,7 +127,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `function() NULL`. x `function() NULL` must be logical, numeric, or character, not a function. Code (expect_error(vec_as_location(Sys.Date(), 3L), class = "vctrs_error_subscript_type") @@ -135,7 +135,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `Sys.Date()`. x `Sys.Date()` must be logical, numeric, or character, not a object. Code # Idem with custom `arg` @@ -144,7 +144,7 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `foo`. x `foo` must be logical, numeric, or character, not an environment. Code (expect_error(vec_as_location(foobar(), 10L, arg = "foo", call = call( @@ -152,7 +152,7 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `foo`. x `foo` must be logical, numeric, or character, not a object. Code (expect_error(vec_as_location(2.5, 3L, arg = "foo", call = call("my_function")), @@ -160,7 +160,7 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `foo`. x Can't convert from `foo` to due to loss of precision. # vec_as_location() and variants check for OOB elements (#1605) @@ -223,7 +223,7 @@ Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `1:2`. x Subscript `1:2` must be size 1, not 2. Code (expect_error(vec_as_location2(c("foo", "bar"), 2L, c("foo", "bar")), class = "vctrs_error_subscript_type") @@ -231,7 +231,7 @@ Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `c("foo", "bar")`. x Subscript `c("foo", "bar")` must be size 1, not 2. Code # Idem with custom `arg` @@ -240,7 +240,7 @@ Output Error in `my_function()`: - ! Must extract element with a single valid subscript. + ! Can't extract element with `foo`. x Subscript `foo` must be size 1, not 2. Code (expect_error(vec_as_location2(mtcars, 10L, arg = "foo", call = call( @@ -248,7 +248,7 @@ Output Error in `my_function()`: - ! Must extract element with a single valid subscript. + ! Can't extract element with `foo`. x `foo` must be numeric or character, not a object. Code (expect_error(vec_as_location2(1:2, 2L, arg = "foo", call = call("my_function")), @@ -256,7 +256,7 @@ Output Error in `my_function()`: - ! Must extract element with a single valid subscript. + ! Can't extract element with `foo`. x Subscript `foo` must be size 1, not 2. # vec_as_location2() requires positive integers @@ -266,14 +266,14 @@ Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `0`. x Subscript `0` must be a positive location, not 0. Code (expect_error(vec_as_location2(-1, 2L), class = "vctrs_error_subscript_type")) Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `-1`. x Subscript `-1` must be a positive location, not -1. Code # Idem with custom `arg` @@ -282,7 +282,7 @@ Output Error in `my_function()`: - ! Must extract element with a single valid subscript. + ! Can't extract element with `foo`. x Subscript `foo` must be a positive location, not 0. # vec_as_location2() fails with NA @@ -293,7 +293,7 @@ Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `na_int`. x Subscript `na_int` must be a location, not an integer `NA`. Code (expect_error(vec_as_location2(na_chr, 1L, names = "foo"), class = "vctrs_error_subscript_type") @@ -301,7 +301,7 @@ Output Error: - ! Must extract element with a single valid subscript. + ! Can't extract element with `na_chr`. x Subscript `na_chr` must be a location, not a character `NA`. Code # Idem with custom `arg` @@ -310,7 +310,7 @@ Output Error in `my_function()`: - ! Must extract element with a single valid subscript. + ! Can't extract element with `foo`. x Subscript `foo` must be a location, not an integer `NA`. # num_as_location() optionally forbids negative indices @@ -321,7 +321,8 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `dbl(1, -1)`. + Caused by error: x Subscript `dbl(1, -1)` can't contain negative locations. # num_as_location() optionally forbids zero indices @@ -332,7 +333,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `0L`. x Subscript `0L` can't contain `0` values. i It has a `0` value at location 1. Code @@ -341,7 +342,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `c(0, 0, 0, 0, 0, 0)`. x Subscript `c(0, 0, 0, 0, 0, 0)` can't contain `0` values. i It has 6 `0` values at locations 1, 2, 3, 4, 5, etc. @@ -353,7 +354,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `-c(1L, NA)`. Caused by error: ! Negative locations can't have missing values. x `-c(1L, NA)` has 1 missing value at location 2. @@ -363,7 +364,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `-c(1L, rep(NA, 10))`. Caused by error: ! Negative locations can't have missing values. x `-c(1L, rep(NA, 10))` has 10 missing values at locations 2, 3, 4, 5, 6, 7, 8, 9, 10, and 11. @@ -376,7 +377,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `c(-1L, 1L)`. x Negative and positive locations can't be mixed. i Subscript `c(-1L, 1L)` has a positive value at location 2. Code @@ -385,7 +386,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `c(-1L, rep(1L, 10))`. x Negative and positive locations can't be mixed. i Subscript `c(-1L, rep(1L, 10))` has 10 positive values at locations 2, 3, 4, 5, 6, etc. @@ -397,7 +398,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `c(TRUE, FALSE)`. x Logical subscript `c(TRUE, FALSE)` must be size 1 or 3, not 2. # character subscripts require named vectors @@ -483,7 +484,7 @@ num_as_location(c(0, -1), n = 2L, negative = "invert", zero = "error") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `c(0, -1)`. x Subscript `c(0, -1)` can't contain `0` values. i It has a `0` value at location 1. @@ -493,7 +494,7 @@ num_as_location(c(-1, 0), n = 2L, negative = "invert", zero = "error") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `c(-1, 0)`. x Subscript `c(-1, 0)` can't contain `0` values. i It has a `0` value at location 2. @@ -566,7 +567,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript can't contain missing values. x It has a missing value at location 2. Code @@ -575,7 +576,7 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript can't contain missing values. x It has missing values at locations 2 and 4. Code @@ -584,7 +585,7 @@ Output Error: - ! Must rename columns with a valid subscript vector. + ! Can't rename columns with `foo(bar)`. x Subscript `foo(bar)` can't contain missing values. x It has missing values at locations 2 and 4. Code @@ -593,7 +594,7 @@ Output Error: - ! Must rename columns with a valid subscript vector. + ! Can't rename columns with `foo(bar)`. x Subscript `foo(bar)` can't contain missing values. x It has a missing value at location 1. Code @@ -602,7 +603,7 @@ Output Error: - ! Must rename columns with a valid subscript vector. + ! Can't rename columns with `foo(bar)`. x Subscript `foo(bar)` can't contain missing values. x It has a missing value at location 1. Code @@ -611,7 +612,7 @@ Output Error: - ! Must rename columns with a valid subscript vector. + ! Can't rename columns with `foo(bar)`. x Subscript `foo(bar)` can't contain missing values. x It has a missing value at location 2. Code @@ -620,7 +621,7 @@ Output Error: - ! Must rename columns with a valid subscript vector. + ! Can't rename columns with `foo(bar)`. x Subscript `foo(bar)` can't contain missing values. x It has a missing value at location 1. @@ -630,7 +631,7 @@ vec_as_location(x, n = 4L, missing = "error") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript can't contain missing values. x It has missing values at locations 2 and 4. @@ -640,7 +641,7 @@ vec_as_location(x, n = 2L, missing = "error") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript can't contain missing values. x It has a missing value at location 1. @@ -650,7 +651,7 @@ vec_as_location(x, n = 2L, names = names, missing = "error") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript can't contain missing values. x It has missing values at locations 1 and 3. @@ -660,7 +661,7 @@ vec_as_location(x, n = 4L, missing = "error") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript can't contain missing values. x It has missing values at locations 1 and 3. @@ -670,7 +671,7 @@ num_as_location(x, n = 4L, missing = "propagate", negative = "invert") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `x`. Caused by error: ! Negative locations can't have missing values. x `x` has 2 missing values at locations 2 and 3. @@ -681,7 +682,7 @@ num_as_location(x, n = 4L, missing = "error", negative = "invert") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `x`. Caused by error: ! Negative locations can't have missing values. x `x` has 2 missing values at locations 2 and 3. @@ -692,7 +693,7 @@ vec_as_location("", n = 2L, names = names) Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript can't contain the empty string. x It has an empty string at location 1. @@ -702,7 +703,7 @@ vec_as_location(c("", "y", ""), n = 2L, names = names) Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript can't contain the empty string. x It has an empty string at locations 1 and 3. @@ -715,7 +716,8 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `foo`. + Caused by error: x Subscript `foo` can't contain negative locations. Code (expect_error(num_as_location2(-1, 2, negative = "error", arg = "foo", call = call( @@ -723,7 +725,7 @@ Output Error in `my_function()`: - ! Must extract element with a single valid subscript. + ! Can't extract element with `foo`. x Subscript `foo` must be a positive location, not -1. Code (expect_error(vec_as_location2(0, 2, arg = "foo", call = call("my_function")), @@ -731,7 +733,7 @@ Output Error in `my_function()`: - ! Must extract element with a single valid subscript. + ! Can't extract element with `foo`. x Subscript `foo` must be a positive location, not 0. Code (expect_error(vec_as_location2(na_dbl, 2, arg = "foo", call = call( @@ -739,7 +741,7 @@ Output Error in `my_function()`: - ! Must extract element with a single valid subscript. + ! Can't extract element with `foo`. x Subscript `foo` must be a location, not an integer `NA`. Code (expect_error(vec_as_location2(c(1, 2), 2, arg = "foo", call = call( @@ -747,7 +749,7 @@ Output Error in `my_function()`: - ! Must extract element with a single valid subscript. + ! Can't extract element with `foo`. x Subscript `foo` must be size 1, not 2. Code (expect_error(vec_as_location(c(TRUE, FALSE), 3, arg = "foo", call = call( @@ -755,7 +757,7 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `foo`. x Logical subscript `foo` must be size 1 or 3, not 2. Code (expect_error(vec_as_location(c(-1, NA), 3, arg = "foo", call = call( @@ -763,7 +765,7 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `foo`. Caused by error: ! Negative locations can't have missing values. x `foo` has 1 missing value at location 2. @@ -773,7 +775,7 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `foo`. x Negative and positive locations can't be mixed. i Subscript `foo` has a positive value at location 2. Code @@ -791,7 +793,7 @@ Output Error in `my_function()`: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `foo`. x Subscript `foo` can't contain `0` values. i It has a `0` value at location 1. Code @@ -801,7 +803,8 @@ Output Error: - ! Must rename columns with a valid subscript vector. + ! Can't rename columns with `foo(bar)`. + Caused by error: x Subscript `foo(bar)` can't contain negative locations. Code (expect_error(with_tibble_cols(num_as_location2(-1, 2, negative = "error")), @@ -809,7 +812,7 @@ Output Error: - ! Must rename column with a single valid subscript. + ! Can't rename column with `foo(bar)`. x Subscript `foo(bar)` must be a positive location, not -1. Code (expect_error(with_tibble_cols(vec_as_location2(0, 2)), class = "vctrs_error_subscript_type") @@ -817,7 +820,7 @@ Output Error: - ! Must rename column with a single valid subscript. + ! Can't rename column with `foo(bar)`. x Subscript `foo(bar)` must be a positive location, not 0. Code (expect_error(with_tibble_cols(vec_as_location2(na_dbl, 2)), class = "vctrs_error_subscript_type") @@ -825,7 +828,7 @@ Output Error: - ! Must rename column with a single valid subscript. + ! Can't rename column with `foo(bar)`. x Subscript `foo(bar)` must be a location, not an integer `NA`. Code (expect_error(with_tibble_cols(vec_as_location2(c(1, 2), 2)), class = "vctrs_error_subscript_type") @@ -833,7 +836,7 @@ Output Error: - ! Must rename column with a single valid subscript. + ! Can't rename column with `foo(bar)`. x Subscript `foo(bar)` must be size 1, not 2. Code (expect_error(with_tibble_cols(vec_as_location(c(TRUE, FALSE), 3)), class = "vctrs_error_subscript_size") @@ -841,7 +844,7 @@ Output Error: - ! Must rename columns with a valid subscript vector. + ! Can't rename columns with `foo(bar)`. x Logical subscript `foo(bar)` must be size 1 or 3, not 2. Code (expect_error(with_tibble_cols(vec_as_location(c(-1, NA), 3)), class = "vctrs_error_subscript_type") @@ -849,7 +852,7 @@ Output Error: - ! Must rename columns with a valid subscript vector. + ! Can't rename columns with `foo(bar)`. Caused by error: ! Negative locations can't have missing values. x `foo(bar)` has 1 missing value at location 2. @@ -859,7 +862,7 @@ Output Error: - ! Must rename columns with a valid subscript vector. + ! Can't rename columns with `foo(bar)`. x Negative and positive locations can't be mixed. i Subscript `foo(bar)` has a positive value at location 2. Code @@ -877,7 +880,7 @@ Output Error: - ! Must rename columns with a valid subscript vector. + ! Can't rename columns with `foo(bar)`. x Subscript `foo(bar)` can't contain `0` values. i It has a `0` value at location 1. @@ -1026,7 +1029,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `matrix(TRUE, nrow = 1)`. x Subscript `matrix(TRUE, nrow = 1)` must be a simple vector, not a matrix. Code (expect_error(vec_as_location(array(TRUE, dim = c(1, 1, 1)), 3L), class = "vctrs_error_subscript_type") @@ -1034,7 +1037,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements with `array(TRUE, dim = c(1, 1, 1))`. x Subscript `array(TRUE, dim = c(1, 1, 1))` must be a simple vector, not an array. Code (expect_error(with_tibble_rows(vec_as_location(matrix(TRUE, nrow = 1), 3L)), @@ -1042,7 +1045,7 @@ Output Error: - ! Must remove rows with a valid subscript vector. + ! Can't remove rows with `foo(bar)`. x Subscript `foo(bar)` must be a simple vector, not a matrix. # vec_as_location() UI diff --git a/tests/testthat/_snaps/subscript.md b/tests/testthat/_snaps/subscript.md index 1e0a13fa4..43aa2ff5c 100644 --- a/tests/testthat/_snaps/subscript.md +++ b/tests/testthat/_snaps/subscript.md @@ -6,7 +6,7 @@ Output Error: - ! Must rename columns with a valid subscript vector. + ! Can't rename columns with `foo(bar)`. x `foo(bar)` must be logical, numeric, or character, not an environment. --- @@ -17,7 +17,7 @@ Output Error: - ! Must extract tables with a valid subscript vector. + ! Can't extract tables with `foo(bar)`. x `foo(bar)` must be logical, numeric, or character, not an environment. # vec_as_subscript() checks dimensionality @@ -28,7 +28,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript must be a simple vector, not a matrix. Code (expect_error(vec_as_subscript(array(TRUE, dim = c(1, 1, 1))), class = "vctrs_error_subscript_type") @@ -36,7 +36,7 @@ Output Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript must be a simple vector, not an array. Code (expect_error(with_tibble_rows(vec_as_subscript(matrix(TRUE, nrow = 1))), @@ -44,7 +44,7 @@ Output Error: - ! Must remove rows with a valid subscript vector. + ! Can't remove rows with `foo(bar)`. x Subscript `foo(bar)` must be a simple vector, not a matrix. # vec_as_subscript() forbids subscript types @@ -53,7 +53,7 @@ vec_as_subscript(1L, logical = "error", numeric = "error") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript must be character, not the number 1. --- @@ -62,7 +62,7 @@ vec_as_subscript("foo", logical = "error", character = "error") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript must be numeric, not the string "foo". --- @@ -71,7 +71,7 @@ vec_as_subscript(TRUE, logical = "error") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript must be numeric or character, not `TRUE`. --- @@ -80,7 +80,7 @@ vec_as_subscript("foo", character = "error") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript must be logical or numeric, not the string "foo". --- @@ -89,7 +89,7 @@ vec_as_subscript(NULL, numeric = "error") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript must be logical or character, not `NULL`. --- @@ -98,7 +98,7 @@ vec_as_subscript(quote(foo), character = "error") Condition Error: - ! Must subset elements with a valid subscript vector. + ! Can't subset elements. x Subscript must be logical or numeric, not a symbol. # vec_as_subscript2() forbids subscript types @@ -107,7 +107,7 @@ vec_as_subscript2(1L, numeric = "error") Condition Error: - ! Must extract element with a single valid subscript. + ! Can't extract element. x Subscript must be character, not the number 1. --- @@ -116,7 +116,7 @@ vec_as_subscript2("foo", character = "error") Condition Error: - ! Must extract element with a single valid subscript. + ! Can't extract element. x Subscript must be numeric, not the string "foo". --- @@ -125,7 +125,7 @@ vec_as_subscript2(TRUE) Condition Error: - ! Must extract element with a single valid subscript. + ! Can't extract element. x Subscript must be numeric or character, not `TRUE`. # vec_as_subscript2() retains the call when throwing vec_as_subscript() errors (#1605) @@ -134,7 +134,7 @@ vec_as_subscript2(1L, numeric = "error", call = call("foo")) Condition Error in `foo()`: - ! Must extract element with a single valid subscript. + ! Can't extract element. x Subscript must be character, not the number 1. --- @@ -143,7 +143,7 @@ vec_as_subscript2(1.5, call = call("foo")) Condition Error in `foo()`: - ! Must extract element with a single valid subscript. + ! Can't extract element. x Can't convert from to due to loss of precision. # vec_as_subscript2() retains the call when erroring on logical input (#1605) @@ -152,7 +152,7 @@ vec_as_subscript2(TRUE, call = call("foo")) Condition Error in `foo()`: - ! Must extract element with a single valid subscript. + ! Can't extract element. x Subscript must be numeric or character, not `TRUE`. # `logical = 'cast'` is deprecated @@ -169,7 +169,7 @@ vec_as_subscript2(TRUE, logical = "error") Condition Error: - ! Must extract element with a single valid subscript. + ! Can't extract element. x Subscript must be numeric or character, not `TRUE`. # lossy cast errors for scalar subscripts work (#1606) @@ -178,6 +178,6 @@ vec_as_subscript2(1.5) Condition Error: - ! Must extract element with a single valid subscript. + ! Can't extract element. x Can't convert from to due to loss of precision. From 229daf09cd51f5fd544dbd8b74eb88dcf66dadc7 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 20 Oct 2022 14:09:21 +0200 Subject: [PATCH 03/12] Use chained error for negative locations --- R/subscript-loc.R | 6 ++---- tests/testthat/_snaps/slice-chop.md | 3 ++- tests/testthat/_snaps/subscript-loc.md | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/R/subscript-loc.R b/R/subscript-loc.R index 600a4d1af..83edd900c 100644 --- a/R/subscript-loc.R +++ b/R/subscript-loc.R @@ -395,10 +395,8 @@ stop_location_negative <- function(i, ..., call = caller_env()) { cnd_signal(contextual) } cnd_header_location_need_non_negative <- function(cnd, ...) { - cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) - c( - x = glue::glue_data(cnd, "{subscript_arg} can't contain negative locations.") - ) + arg <- cnd_subscript_arg(cnd) + glue::glue("{arg} can't contain negative locations.") } stop_location_zero <- function(i, ..., call = caller_env()) { diff --git a/tests/testthat/_snaps/slice-chop.md b/tests/testthat/_snaps/slice-chop.md index f79e057c2..ada76eee5 100644 --- a/tests/testthat/_snaps/slice-chop.md +++ b/tests/testthat/_snaps/slice-chop.md @@ -168,7 +168,8 @@ Error: ! Can't subset elements. - x Subscript can't contain negative locations. + Caused by error: + ! Subscript can't contain negative locations. # list_unchop() fails with complex foreign S3 classes diff --git a/tests/testthat/_snaps/subscript-loc.md b/tests/testthat/_snaps/subscript-loc.md index 9c74a8a0f..6bca63016 100644 --- a/tests/testthat/_snaps/subscript-loc.md +++ b/tests/testthat/_snaps/subscript-loc.md @@ -323,7 +323,7 @@ Error: ! Can't subset elements with `dbl(1, -1)`. Caused by error: - x Subscript `dbl(1, -1)` can't contain negative locations. + ! `dbl(1, -1)` can't contain negative locations. # num_as_location() optionally forbids zero indices @@ -718,7 +718,7 @@ Error in `my_function()`: ! Can't subset elements with `foo`. Caused by error: - x Subscript `foo` can't contain negative locations. + ! `foo` can't contain negative locations. Code (expect_error(num_as_location2(-1, 2, negative = "error", arg = "foo", call = call( "my_function")), class = "vctrs_error_subscript_type")) @@ -805,7 +805,7 @@ Error: ! Can't rename columns with `foo(bar)`. Caused by error: - x Subscript `foo(bar)` can't contain negative locations. + ! `foo(bar)` can't contain negative locations. Code (expect_error(with_tibble_cols(num_as_location2(-1, 2, negative = "error")), class = "vctrs_error_subscript_type")) From c5f2262eb0f30fe5e380dab23092c93c58926327 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 20 Oct 2022 14:26:25 +0200 Subject: [PATCH 04/12] Use chained error in `stop_location_zero()` --- R/subscript-loc.R | 28 +++++++++++++++++--------- tests/testthat/_snaps/slice-chop.md | 1 + tests/testthat/_snaps/subscript-loc.md | 18 +++++++++++------ 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/R/subscript-loc.R b/R/subscript-loc.R index 83edd900c..656894a27 100644 --- a/R/subscript-loc.R +++ b/R/subscript-loc.R @@ -400,17 +400,28 @@ cnd_header_location_need_non_negative <- function(cnd, ...) { } stop_location_zero <- function(i, ..., call = caller_env()) { - cnd_signal(new_error_subscript_type( + causal <- error_cnd( + i = i, + header = cnd_header_location_need_non_zero, + ..., + call = NULL, + use_cli_format = TRUE + ) + contextual <- new_error_subscript_type( i, - body = cnd_bullets_location_need_non_zero, ..., - call = call - )) + body = function(...) chr(), + call = call, + parent = causal + ) + cnd_signal(contextual) } -cnd_bullets_location_need_non_zero <- function(cnd, ...) { +cnd_header_location_need_non_zero <- function(cnd, ...) { + arg <- cnd_subscript_arg(cnd) + header <- glue::glue("{arg} can't contain `0` values.") + zero_loc <- which(cnd$i == 0) zero_loc_size <- length(zero_loc) - arg <- append_arg("Subscript", cnd$subscript_arg) if (zero_loc_size == 1) { loc <- glue::glue("It has a `0` value at location {zero_loc}.") @@ -420,10 +431,7 @@ cnd_bullets_location_need_non_zero <- function(cnd, ...) { "It has {zero_loc_size} `0` values at locations {zero_loc}" ) } - format_error_bullets(c( - x = glue::glue("{arg} can't contain `0` values."), - i = loc - )) + c(header, i = loc) } stop_subscript_missing <- function(i, ..., call = caller_env()) { diff --git a/tests/testthat/_snaps/slice-chop.md b/tests/testthat/_snaps/slice-chop.md index ada76eee5..657b0b226 100644 --- a/tests/testthat/_snaps/slice-chop.md +++ b/tests/testthat/_snaps/slice-chop.md @@ -159,6 +159,7 @@ Error: ! Can't subset elements. + Caused by error: x Subscript can't contain `0` values. i It has a `0` value at location 1. Code diff --git a/tests/testthat/_snaps/subscript-loc.md b/tests/testthat/_snaps/subscript-loc.md index 6bca63016..2ef1ad611 100644 --- a/tests/testthat/_snaps/subscript-loc.md +++ b/tests/testthat/_snaps/subscript-loc.md @@ -334,7 +334,8 @@ Error: ! Can't subset elements with `0L`. - x Subscript `0L` can't contain `0` values. + Caused by error: + x `0L` can't contain `0` values. i It has a `0` value at location 1. Code (expect_error(num_as_location(c(0, 0, 0, 0, 0, 0), 1, zero = "error"), class = "vctrs_error_subscript_type") @@ -343,7 +344,8 @@ Error: ! Can't subset elements with `c(0, 0, 0, 0, 0, 0)`. - x Subscript `c(0, 0, 0, 0, 0, 0)` can't contain `0` values. + Caused by error: + x `c(0, 0, 0, 0, 0, 0)` can't contain `0` values. i It has 6 `0` values at locations 1, 2, 3, 4, 5, etc. # vec_as_location() checks for mix of negative and missing locations @@ -485,7 +487,8 @@ Condition Error: ! Can't subset elements with `c(0, -1)`. - x Subscript `c(0, -1)` can't contain `0` values. + Caused by error: + x `c(0, -1)` can't contain `0` values. i It has a `0` value at location 1. --- @@ -495,7 +498,8 @@ Condition Error: ! Can't subset elements with `c(-1, 0)`. - x Subscript `c(-1, 0)` can't contain `0` values. + Caused by error: + x `c(-1, 0)` can't contain `0` values. i It has a `0` value at location 2. # num_as_location() with `oob = 'extend'` doesn't allow ignored oob negative values (#1614) @@ -794,7 +798,8 @@ Error in `my_function()`: ! Can't subset elements with `foo`. - x Subscript `foo` can't contain `0` values. + Caused by error: + x `foo` can't contain `0` values. i It has a `0` value at location 1. Code # With tibble columns @@ -881,7 +886,8 @@ Error: ! Can't rename columns with `foo(bar)`. - x Subscript `foo(bar)` can't contain `0` values. + Caused by error: + x `foo(bar)` can't contain `0` values. i It has a `0` value at location 1. # can customise OOB errors From 9f218076c2c18283b779b0e25a0d8c59482a2e21 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 20 Oct 2022 14:44:35 +0200 Subject: [PATCH 05/12] Use chained error in `stop_subscript_missing()` --- R/subscript-loc.R | 27 ++++++++++------ tests/testthat/_snaps/error-call.md | 3 +- tests/testthat/_snaps/slice-chop.md | 2 +- tests/testthat/_snaps/subscript-loc.md | 45 ++++++++++++++++---------- 4 files changed, 48 insertions(+), 29 deletions(-) diff --git a/R/subscript-loc.R b/R/subscript-loc.R index 656894a27..ef3c66af9 100644 --- a/R/subscript-loc.R +++ b/R/subscript-loc.R @@ -435,15 +435,25 @@ cnd_header_location_need_non_zero <- function(cnd, ...) { } stop_subscript_missing <- function(i, ..., call = caller_env()) { - cnd_signal(new_error_subscript_type( + causal <- error_cnd( i = i, - body = cnd_bullets_subscript_missing, + header = cnd_header_subscript_missing, ..., - call = call - )) + call = NULL, + use_cli_format = TRUE + ) + contextual <- new_error_subscript_type( + i, + ..., + body = function(...) chr(), + call = call, + parent = causal + ) + cnd_signal(contextual) } -cnd_bullets_subscript_missing <- function(cnd, ...) { - cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) +cnd_header_subscript_missing <- function(cnd, ...) { + arg <- cnd_subscript_arg(cnd) + header <- glue::glue("{arg} can't contain missing values.") missing_loc <- which(is.na(cnd$i)) if (length(missing_loc) == 1) { @@ -453,10 +463,7 @@ cnd_bullets_subscript_missing <- function(cnd, ...) { missing_line <- glue::glue("It has missing values at locations {missing_enum}") } - format_error_bullets(c( - x = glue::glue_data(cnd, "{subscript_arg} can't contain missing values."), - x = missing_line - )) + c(header, x = missing_line) } stop_subscript_empty <- function(i, ..., call = caller_env()) { diff --git a/tests/testthat/_snaps/error-call.md b/tests/testthat/_snaps/error-call.md index 9fa9ddc08..d14de133e 100644 --- a/tests/testthat/_snaps/error-call.md +++ b/tests/testthat/_snaps/error-call.md @@ -259,7 +259,8 @@ Error in `my_function()`: ! Can't subset elements. - x Subscript can't contain missing values. + Caused by error: + ! Subscript can't contain missing values. x It has a missing value at location 1. # `vec_ptype()` reports correct error call diff --git a/tests/testthat/_snaps/slice-chop.md b/tests/testthat/_snaps/slice-chop.md index 657b0b226..68d038f87 100644 --- a/tests/testthat/_snaps/slice-chop.md +++ b/tests/testthat/_snaps/slice-chop.md @@ -160,7 +160,7 @@ Error: ! Can't subset elements. Caused by error: - x Subscript can't contain `0` values. + ! Subscript can't contain `0` values. i It has a `0` value at location 1. Code (expect_error(list_unchop(list(1), indices = list(-1)), class = "vctrs_error_subscript_type") diff --git a/tests/testthat/_snaps/subscript-loc.md b/tests/testthat/_snaps/subscript-loc.md index 2ef1ad611..98e6f3831 100644 --- a/tests/testthat/_snaps/subscript-loc.md +++ b/tests/testthat/_snaps/subscript-loc.md @@ -335,7 +335,7 @@ Error: ! Can't subset elements with `0L`. Caused by error: - x `0L` can't contain `0` values. + ! `0L` can't contain `0` values. i It has a `0` value at location 1. Code (expect_error(num_as_location(c(0, 0, 0, 0, 0, 0), 1, zero = "error"), class = "vctrs_error_subscript_type") @@ -345,7 +345,7 @@ Error: ! Can't subset elements with `c(0, 0, 0, 0, 0, 0)`. Caused by error: - x `c(0, 0, 0, 0, 0, 0)` can't contain `0` values. + ! `c(0, 0, 0, 0, 0, 0)` can't contain `0` values. i It has 6 `0` values at locations 1, 2, 3, 4, 5, etc. # vec_as_location() checks for mix of negative and missing locations @@ -488,7 +488,7 @@ Error: ! Can't subset elements with `c(0, -1)`. Caused by error: - x `c(0, -1)` can't contain `0` values. + ! `c(0, -1)` can't contain `0` values. i It has a `0` value at location 1. --- @@ -499,7 +499,7 @@ Error: ! Can't subset elements with `c(-1, 0)`. Caused by error: - x `c(-1, 0)` can't contain `0` values. + ! `c(-1, 0)` can't contain `0` values. i It has a `0` value at location 2. # num_as_location() with `oob = 'extend'` doesn't allow ignored oob negative values (#1614) @@ -572,7 +572,8 @@ Error: ! Can't subset elements. - x Subscript can't contain missing values. + Caused by error: + ! Subscript can't contain missing values. x It has a missing value at location 2. Code (expect_error(vec_as_location(c(1, NA, 2, NA), 2, missing = "error", arg = "foo", @@ -581,7 +582,8 @@ Error in `my_function()`: ! Can't subset elements. - x Subscript can't contain missing values. + Caused by error: + ! Subscript can't contain missing values. x It has missing values at locations 2 and 4. Code (expect_error(with_tibble_cols(vec_as_location(c(1, NA, 2, NA), 2, missing = "error")), @@ -590,7 +592,8 @@ Error: ! Can't rename columns with `foo(bar)`. - x Subscript `foo(bar)` can't contain missing values. + Caused by error: + ! `foo(bar)` can't contain missing values. x It has missing values at locations 2 and 4. Code (expect_error(with_tibble_cols(vec_as_location(NA, 1, missing = "error")), @@ -599,7 +602,8 @@ Error: ! Can't rename columns with `foo(bar)`. - x Subscript `foo(bar)` can't contain missing values. + Caused by error: + ! `foo(bar)` can't contain missing values. x It has a missing value at location 1. Code (expect_error(with_tibble_cols(vec_as_location(NA, 3, missing = "error")), @@ -608,7 +612,8 @@ Error: ! Can't rename columns with `foo(bar)`. - x Subscript `foo(bar)` can't contain missing values. + Caused by error: + ! `foo(bar)` can't contain missing values. x It has a missing value at location 1. Code (expect_error(with_tibble_cols(vec_as_location(c(TRUE, NA, FALSE), 3, missing = "error")), @@ -617,7 +622,8 @@ Error: ! Can't rename columns with `foo(bar)`. - x Subscript `foo(bar)` can't contain missing values. + Caused by error: + ! `foo(bar)` can't contain missing values. x It has a missing value at location 2. Code (expect_error(with_tibble_cols(vec_as_location(NA_character_, 2, missing = "error", @@ -626,7 +632,8 @@ Error: ! Can't rename columns with `foo(bar)`. - x Subscript `foo(bar)` can't contain missing values. + Caused by error: + ! `foo(bar)` can't contain missing values. x It has a missing value at location 1. # can alter logical missing value handling (#1595) @@ -636,7 +643,8 @@ Condition Error: ! Can't subset elements. - x Subscript can't contain missing values. + Caused by error: + ! Subscript can't contain missing values. x It has missing values at locations 2 and 4. --- @@ -646,7 +654,8 @@ Condition Error: ! Can't subset elements. - x Subscript can't contain missing values. + Caused by error: + ! Subscript can't contain missing values. x It has a missing value at location 1. # can alter character missing value handling (#1595) @@ -656,7 +665,8 @@ Condition Error: ! Can't subset elements. - x Subscript can't contain missing values. + Caused by error: + ! Subscript can't contain missing values. x It has missing values at locations 1 and 3. # can alter integer missing value handling (#1595) @@ -666,7 +676,8 @@ Condition Error: ! Can't subset elements. - x Subscript can't contain missing values. + Caused by error: + ! Subscript can't contain missing values. x It has missing values at locations 1 and 3. # can alter negative integer missing value handling (#1595) @@ -799,7 +810,7 @@ Error in `my_function()`: ! Can't subset elements with `foo`. Caused by error: - x `foo` can't contain `0` values. + ! `foo` can't contain `0` values. i It has a `0` value at location 1. Code # With tibble columns @@ -887,7 +898,7 @@ Error: ! Can't rename columns with `foo(bar)`. Caused by error: - x `foo(bar)` can't contain `0` values. + ! `foo(bar)` can't contain `0` values. i It has a `0` value at location 1. # can customise OOB errors From 310b201da2b6ffd92f19211c56e192e4fca05a70 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 20 Oct 2022 14:46:27 +0200 Subject: [PATCH 06/12] Mark error as internal --- R/subscript-loc.R | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/R/subscript-loc.R b/R/subscript-loc.R index ef3c66af9..9584905ce 100644 --- a/R/subscript-loc.R +++ b/R/subscript-loc.R @@ -540,7 +540,8 @@ cnd_header.vctrs_error_subscript_oob <- function(cnd, ...) { #' @export cnd_body.vctrs_error_subscript_oob <- function(cnd, ...) { - switch(cnd_subscript_type(cnd), + switch( + cnd_subscript_type(cnd), numeric = if (cnd_subscript_oob_non_consecutive(cnd)) { cnd_body_vctrs_error_subscript_oob_non_consecutive(cnd, ...) @@ -549,7 +550,7 @@ cnd_body.vctrs_error_subscript_oob <- function(cnd, ...) { }, character = cnd_body_vctrs_error_subscript_oob_name(cnd, ...), - abort("Internal error: subscript type can't be `logical` for OOB errors.") + abort("Subscript type can't be `logical` for OOB errors.", .internal = TRUE) ) } cnd_body_vctrs_error_subscript_oob_location <- function(cnd, ...) { From 8ef06dd54d78bdb1195e33a93d20ae4790eab4cf Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 20 Oct 2022 14:59:54 +0200 Subject: [PATCH 07/12] Use chained error in `stop_subscript_empty()` --- R/subscript-loc.R | 29 ++++++++++++++++---------- tests/testthat/_snaps/subscript-loc.md | 6 ++++-- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/R/subscript-loc.R b/R/subscript-loc.R index 9584905ce..1a1882925 100644 --- a/R/subscript-loc.R +++ b/R/subscript-loc.R @@ -467,28 +467,35 @@ cnd_header_subscript_missing <- function(cnd, ...) { } stop_subscript_empty <- function(i, ..., call = caller_env()) { - cnd_signal(new_error_subscript_type( + causal <- error_cnd( i = i, - body = cnd_bullets_subscript_empty, + header = cnd_bullets_subscript_empty, ..., - call = call - )) + call = NULL, + use_cli_format = TRUE + ) + contextual <- new_error_subscript_type( + i, + ..., + body = function(...) chr(), + call = call, + parent = causal + ) + cnd_signal(contextual) } cnd_bullets_subscript_empty <- function(cnd, ...) { - cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) + arg <- cnd_subscript_arg(cnd) + header <- glue::glue("{arg} can't contain the empty string.") loc <- which(cnd$i == "") if (length(loc) == 1) { - line <- glue::glue("It has an empty string at location {loc}.") + locations <- glue::glue("It has an empty string at location {loc}.") } else { enum <- ensure_full_stop(enumerate(loc)) - line <- glue::glue("It has an empty string at locations {enum}") + locations <- glue::glue("It has an empty string at locations {enum}") } - format_error_bullets(c( - x = glue::glue_data(cnd, "{subscript_arg} can't contain the empty string."), - x = line - )) + c(header, x = locations) } stop_indicator_size <- function(i, n, ..., call = caller_env()) { diff --git a/tests/testthat/_snaps/subscript-loc.md b/tests/testthat/_snaps/subscript-loc.md index 98e6f3831..256ec09e2 100644 --- a/tests/testthat/_snaps/subscript-loc.md +++ b/tests/testthat/_snaps/subscript-loc.md @@ -709,7 +709,8 @@ Condition Error: ! Can't subset elements. - x Subscript can't contain the empty string. + Caused by error: + ! Subscript can't contain the empty string. x It has an empty string at location 1. --- @@ -719,7 +720,8 @@ Condition Error: ! Can't subset elements. - x Subscript can't contain the empty string. + Caused by error: + ! Subscript can't contain the empty string. x It has an empty string at locations 1 and 3. # can customise subscript type errors From 0332d00ff9c3f2ed8cabbdc19a818f52b4d7e9dc Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 20 Oct 2022 15:12:14 +0200 Subject: [PATCH 08/12] Extract `new_chained_error_subscript_type()` --- R/subscript-loc.R | 82 ++++++++++++----------------------------------- R/subscript.R | 20 ++++++++++++ 2 files changed, 40 insertions(+), 62 deletions(-) diff --git a/R/subscript-loc.R b/R/subscript-loc.R index 1a1882925..90b976931 100644 --- a/R/subscript-loc.R +++ b/R/subscript-loc.R @@ -286,22 +286,13 @@ vec_as_location2_result <- function(i, stop_location_negative_missing <- function(i, ..., call = caller_env()) { - causal <- error_cnd( - i = i, - ..., - header = cnd_header_location_negative_missing, - call = NULL, - use_cli_format = TRUE - ) - contextual <- new_error_subscript_type( + cnd <- new_chained_error_subscript_type( i, ..., - body = function(...) chr(), - call = call, - parent = causal + header = cnd_header_location_negative_missing, + call = call ) - - cnd_signal(contextual) + cnd_signal(cnd) } cnd_header_location_negative_missing <- function(cnd, ...) { @@ -377,22 +368,13 @@ cnd_bullets_location2_need_positive <- function(cnd, ...) { } stop_location_negative <- function(i, ..., call = caller_env()) { - causal <- error_cnd( - i = i, - header = cnd_header_location_need_non_negative, - ..., - call = NULL, - use_cli_format = TRUE - ) - contextual <- new_error_subscript_type( + cnd <- new_chained_error_subscript_type( i, ..., - body = function(...) chr(), - call = call, - parent = causal + header = cnd_header_location_need_non_negative, + call = call ) - - cnd_signal(contextual) + cnd_signal(cnd) } cnd_header_location_need_non_negative <- function(cnd, ...) { arg <- cnd_subscript_arg(cnd) @@ -400,21 +382,13 @@ cnd_header_location_need_non_negative <- function(cnd, ...) { } stop_location_zero <- function(i, ..., call = caller_env()) { - causal <- error_cnd( - i = i, - header = cnd_header_location_need_non_zero, - ..., - call = NULL, - use_cli_format = TRUE - ) - contextual <- new_error_subscript_type( + cnd <- new_chained_error_subscript_type( i, ..., - body = function(...) chr(), - call = call, - parent = causal + header = cnd_header_location_need_non_zero, + call = call ) - cnd_signal(contextual) + cnd_signal(cnd) } cnd_header_location_need_non_zero <- function(cnd, ...) { arg <- cnd_subscript_arg(cnd) @@ -435,21 +409,13 @@ cnd_header_location_need_non_zero <- function(cnd, ...) { } stop_subscript_missing <- function(i, ..., call = caller_env()) { - causal <- error_cnd( - i = i, - header = cnd_header_subscript_missing, - ..., - call = NULL, - use_cli_format = TRUE - ) - contextual <- new_error_subscript_type( + cnd <- new_chained_error_subscript_type( i, ..., - body = function(...) chr(), - call = call, - parent = causal + header = cnd_header_subscript_missing, + call = call ) - cnd_signal(contextual) + cnd_signal(cnd) } cnd_header_subscript_missing <- function(cnd, ...) { arg <- cnd_subscript_arg(cnd) @@ -467,21 +433,13 @@ cnd_header_subscript_missing <- function(cnd, ...) { } stop_subscript_empty <- function(i, ..., call = caller_env()) { - causal <- error_cnd( - i = i, - header = cnd_bullets_subscript_empty, - ..., - call = NULL, - use_cli_format = TRUE - ) - contextual <- new_error_subscript_type( + cnd <- new_chained_error_subscript_type( i, ..., - body = function(...) chr(), - call = call, - parent = causal + header = cnd_bullets_subscript_empty, + call = call ) - cnd_signal(contextual) + cnd_signal(cnd) } cnd_bullets_subscript_empty <- function(cnd, ...) { arg <- cnd_subscript_arg(cnd) diff --git a/R/subscript.R b/R/subscript.R index f6a3961cb..78944fa1b 100644 --- a/R/subscript.R +++ b/R/subscript.R @@ -173,6 +173,26 @@ new_error_subscript_type <- function(i, ) } +new_chained_error_subscript_type <- function(i, + ..., + header = NULL, + call = caller_env()) { + causal <- error_cnd( + i = i, + header = header, + ..., + call = NULL, + use_cli_format = TRUE + ) + new_error_subscript_type( + i, + ..., + body = function(...) chr(), + call = call, + parent = causal + ) +} + # Subscripts errors are currently customised by rethrowing errors with # special fields. The setter methods forward these fields to parent # errors so that causal errors may benefit from these customisations. From 5778b97adcfd49542cfd0696c2d1a386d4dc4a8c Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 20 Oct 2022 15:40:45 +0200 Subject: [PATCH 09/12] Use chained error in `stop_indicator_size()` --- R/subscript-loc.R | 16 +++++++--------- R/subscript.R | 19 +++++++++++++++++++ tests/testthat/_snaps/slice-assign.md | 6 ++++-- tests/testthat/_snaps/subscript-loc.md | 9 ++++++--- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/R/subscript-loc.R b/R/subscript-loc.R index 90b976931..5d4d5ef32 100644 --- a/R/subscript-loc.R +++ b/R/subscript-loc.R @@ -457,20 +457,18 @@ cnd_bullets_subscript_empty <- function(cnd, ...) { } stop_indicator_size <- function(i, n, ..., call = caller_env()) { - cnd_signal(new_error_subscript_size( + cnd <- new_chained_error_subscript_size( i, n = n, ..., - body = cnd_body_vctrs_error_indicator_size, + header = cnd_header_logical_subscript_size, call = call - )) -} -cnd_body_vctrs_error_indicator_size <- function(cnd, ...) { - cnd$subscript_arg <- append_arg("Logical subscript", cnd$subscript_arg) - glue_data_bullets( - cnd, - x = "{subscript_arg} must be size 1 or {n}, not {vec_size(i)}." ) + cnd_signal(cnd) +} +cnd_header_logical_subscript_size <- function(cnd, ...) { + cnd$arg <- append_arg("Logical subscript", cnd$subscript_arg) + glue::glue_data(cnd, "{arg} must be size 1 or {n}, not {vec_size(i)}.") } stop_subscript_oob <- function(i, diff --git a/R/subscript.R b/R/subscript.R index 78944fa1b..c31ab66ce 100644 --- a/R/subscript.R +++ b/R/subscript.R @@ -192,6 +192,25 @@ new_chained_error_subscript_type <- function(i, parent = causal ) } +new_chained_error_subscript_size <- function(i, + ..., + header = NULL, + call = caller_env()) { + causal <- error_cnd( + i = i, + header = header, + ..., + call = NULL, + use_cli_format = TRUE + ) + new_error_subscript_size( + i, + ..., + body = function(...) chr(), + call = call, + parent = causal + ) +} # Subscripts errors are currently customised by rethrowing errors with # special fields. The setter methods forward these fields to parent diff --git a/tests/testthat/_snaps/slice-assign.md b/tests/testthat/_snaps/slice-assign.md index 6cd514bb1..7867502ce 100644 --- a/tests/testthat/_snaps/slice-assign.md +++ b/tests/testthat/_snaps/slice-assign.md @@ -17,7 +17,8 @@ Error: ! Can't assign elements. - x Logical subscript must be size 1 or 2, not 3. + Caused by error: + ! Logical subscript must be size 1 or 2, not 3. --- @@ -28,7 +29,8 @@ Error: ! Can't assign elements. - x Logical subscript must be size 1 or 32, not 2. + Caused by error: + ! Logical subscript must be size 1 or 32, not 2. # must assign existing elements diff --git a/tests/testthat/_snaps/subscript-loc.md b/tests/testthat/_snaps/subscript-loc.md index 256ec09e2..2f6cd9ca5 100644 --- a/tests/testthat/_snaps/subscript-loc.md +++ b/tests/testthat/_snaps/subscript-loc.md @@ -401,7 +401,8 @@ Error: ! Can't subset elements with `c(TRUE, FALSE)`. - x Logical subscript `c(TRUE, FALSE)` must be size 1 or 3, not 2. + Caused by error: + ! Logical subscript `c(TRUE, FALSE)` must be size 1 or 3, not 2. # character subscripts require named vectors @@ -775,7 +776,8 @@ Error in `my_function()`: ! Can't subset elements with `foo`. - x Logical subscript `foo` must be size 1 or 3, not 2. + Caused by error: + ! Logical subscript `foo` must be size 1 or 3, not 2. Code (expect_error(vec_as_location(c(-1, NA), 3, arg = "foo", call = call( "my_function")), class = "vctrs_error_subscript_type")) @@ -863,7 +865,8 @@ Error: ! Can't rename columns with `foo(bar)`. - x Logical subscript `foo(bar)` must be size 1 or 3, not 2. + Caused by error: + ! Logical subscript `c(TRUE, FALSE)` must be size 1 or 3, not 2. Code (expect_error(with_tibble_cols(vec_as_location(c(-1, NA), 3)), class = "vctrs_error_subscript_type") ) From 01d0c9a014a482606edf60f8c8b9b7adeb94813d Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 20 Oct 2022 15:45:29 +0200 Subject: [PATCH 10/12] Simplify result rethrowing --- R/subscript-loc.R | 70 +++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/R/subscript-loc.R b/R/subscript-loc.R index 5d4d5ef32..0405fa702 100644 --- a/R/subscript-loc.R +++ b/R/subscript-loc.R @@ -199,15 +199,8 @@ vec_as_location2_result <- function(i, arg = arg, call = call ) - if (!is_null(result$err)) { - parent <- result$err - return(result(err = new_error_location2_type( - i = i, - subscript_arg = arg, - body = parent$body, - call = call - ))) + return(result) } # Locations must be size 1, can't be NA, and must be positive @@ -284,6 +277,36 @@ vec_as_location2_result <- function(i, } } +new_error_location2_type <- function(i, + ..., + class = NULL) { + new_error_subscript2_type( + class = class, + i = i, + numeric = "cast", + character = "cast", + ... + ) +} + +cnd_bullets_location2_need_scalar <- function(cnd, ...) { + cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) + format_error_bullets(c( + x = glue::glue_data(cnd, "{subscript_arg} must be size 1, not {length(i)}.") + )) +} +cnd_bullets_location2_need_present <- function(cnd, ...) { + cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) + format_error_bullets(c( + x = glue::glue_data(cnd, "{subscript_arg} must be a location, not {obj_type_friendly(i)}.") + )) +} +cnd_bullets_location2_need_positive <- function(cnd, ...) { + cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) + format_error_bullets(c( + x = glue::glue_data(cnd, "{subscript_arg} must be a positive location, not {i}.") + )) +} stop_location_negative_missing <- function(i, ..., call = caller_env()) { cnd <- new_chained_error_subscript_type( @@ -336,37 +359,6 @@ cnd_body_vctrs_error_location_negative_positive <- function(cnd, ...) { )) } - -new_error_location2_type <- function(i, - ..., - class = NULL) { - new_error_subscript2_type( - class = class, - i = i, - numeric = "cast", - character = "cast", - ... - ) -} -cnd_bullets_location2_need_scalar <- function(cnd, ...) { - cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) - format_error_bullets(c( - x = glue::glue_data(cnd, "{subscript_arg} must be size 1, not {length(i)}.") - )) -} -cnd_bullets_location2_need_present <- function(cnd, ...) { - cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) - format_error_bullets(c( - x = glue::glue_data(cnd, "{subscript_arg} must be a location, not {obj_type_friendly(i)}.") - )) -} -cnd_bullets_location2_need_positive <- function(cnd, ...) { - cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) - format_error_bullets(c( - x = glue::glue_data(cnd, "{subscript_arg} must be a positive location, not {i}.") - )) -} - stop_location_negative <- function(i, ..., call = caller_env()) { cnd <- new_chained_error_subscript_type( i, From 6550fd613766f24a69a4a13c83c02fcf9ae8ec75 Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Thu, 20 Oct 2022 16:39:00 +0200 Subject: [PATCH 11/12] Use chained errors for scalar location checks --- R/subscript-loc.R | 59 ++++++++++++++++---------- tests/testthat/_snaps/subscript-loc.md | 54 +++++++++++++++-------- 2 files changed, 72 insertions(+), 41 deletions(-) diff --git a/R/subscript-loc.R b/R/subscript-loc.R index 0405fa702..417ac0578 100644 --- a/R/subscript-loc.R +++ b/R/subscript-loc.R @@ -207,10 +207,10 @@ vec_as_location2_result <- function(i, i <- result$ok if (length(i) != 1L) { - return(result(err = new_error_location2_type( + return(result(err = new_chained_error_location2_type( i = i, subscript_arg = arg, - body = cnd_bullets_location2_need_scalar, + header = cnd_header_location2_need_scalar, call = call ))) } @@ -222,10 +222,10 @@ vec_as_location2_result <- function(i, if (is.na(i)) { if (!allow_missing && is.na(i)) { - result <- result(err = new_error_location2_type( + result <- result(err = new_chained_error_location2_type( i = i, subscript_arg = arg, - body = cnd_bullets_location2_need_present, + header = cnd_header_location2_need_present, call = call )) } else { @@ -235,19 +235,19 @@ vec_as_location2_result <- function(i, } if (identical(i, 0L)) { - return(result(err = new_error_location2_type( + return(result(err = new_chained_error_location2_type( i = i, subscript_arg = arg, - body = cnd_bullets_location2_need_positive, + header = cnd_header_location2_need_positive, call = call ))) } if (!allow_negative && neg) { - return(result(err = new_error_location2_type( + return(result(err = new_chained_error_location2_type( i = i, subscript_arg = arg, - body = cnd_bullets_location2_need_positive, + header = cnd_header_location2_need_positive, call = call ))) } @@ -288,24 +288,37 @@ new_error_location2_type <- function(i, ... ) } +new_chained_error_location2_type <- function(i, + ..., + header = NULL, + call = caller_env()) { + causal <- error_cnd( + i = i, + header = header, + ..., + call = NULL, + use_cli_format = TRUE + ) + new_error_location2_type( + i = i, + ..., + body = function(...) chr(), + call = call, + parent = causal + ) +} -cnd_bullets_location2_need_scalar <- function(cnd, ...) { - cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) - format_error_bullets(c( - x = glue::glue_data(cnd, "{subscript_arg} must be size 1, not {length(i)}.") - )) +cnd_header_location2_need_scalar <- function(cnd, ...) { + cnd$subscript_arg <- cnd_subscript_arg(cnd) + glue::glue_data(cnd, "{subscript_arg} must be size 1, not {length(i)}.") } -cnd_bullets_location2_need_present <- function(cnd, ...) { - cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) - format_error_bullets(c( - x = glue::glue_data(cnd, "{subscript_arg} must be a location, not {obj_type_friendly(i)}.") - )) +cnd_header_location2_need_present <- function(cnd, ...) { + cnd$subscript_arg <- cnd_subscript_arg(cnd) + glue::glue_data(cnd, "{subscript_arg} must be a location, not {obj_type_friendly(i)}.") } -cnd_bullets_location2_need_positive <- function(cnd, ...) { - cnd$subscript_arg <- append_arg("Subscript", cnd$subscript_arg) - format_error_bullets(c( - x = glue::glue_data(cnd, "{subscript_arg} must be a positive location, not {i}.") - )) +cnd_header_location2_need_positive <- function(cnd, ...) { + cnd$subscript_arg <- cnd_subscript_arg(cnd) + glue::glue_data(cnd, "{subscript_arg} must be a positive location, not {i}.") } stop_location_negative_missing <- function(i, ..., call = caller_env()) { diff --git a/tests/testthat/_snaps/subscript-loc.md b/tests/testthat/_snaps/subscript-loc.md index 2f6cd9ca5..a618c3227 100644 --- a/tests/testthat/_snaps/subscript-loc.md +++ b/tests/testthat/_snaps/subscript-loc.md @@ -224,7 +224,8 @@ Error: ! Can't extract element with `1:2`. - x Subscript `1:2` must be size 1, not 2. + Caused by error: + ! `1:2` must be size 1, not 2. Code (expect_error(vec_as_location2(c("foo", "bar"), 2L, c("foo", "bar")), class = "vctrs_error_subscript_type") ) @@ -232,7 +233,8 @@ Error: ! Can't extract element with `c("foo", "bar")`. - x Subscript `c("foo", "bar")` must be size 1, not 2. + Caused by error: + ! `c("foo", "bar")` must be size 1, not 2. Code # Idem with custom `arg` (expect_error(vec_as_location2(1:2, 2L, arg = "foo", call = call("my_function")), @@ -241,7 +243,8 @@ Error in `my_function()`: ! Can't extract element with `foo`. - x Subscript `foo` must be size 1, not 2. + Caused by error: + ! `foo` must be size 1, not 2. Code (expect_error(vec_as_location2(mtcars, 10L, arg = "foo", call = call( "my_function")), class = "vctrs_error_subscript_type")) @@ -257,7 +260,8 @@ Error in `my_function()`: ! Can't extract element with `foo`. - x Subscript `foo` must be size 1, not 2. + Caused by error: + ! `foo` must be size 1, not 2. # vec_as_location2() requires positive integers @@ -267,14 +271,16 @@ Error: ! Can't extract element with `0`. - x Subscript `0` must be a positive location, not 0. + Caused by error: + ! `0` must be a positive location, not 0. Code (expect_error(vec_as_location2(-1, 2L), class = "vctrs_error_subscript_type")) Output Error: ! Can't extract element with `-1`. - x Subscript `-1` must be a positive location, not -1. + Caused by error: + ! `-1` must be a positive location, not -1. Code # Idem with custom `arg` (expect_error(vec_as_location2(0, 2L, arg = "foo", call = call("my_function")), @@ -283,7 +289,8 @@ Error in `my_function()`: ! Can't extract element with `foo`. - x Subscript `foo` must be a positive location, not 0. + Caused by error: + ! `foo` must be a positive location, not 0. # vec_as_location2() fails with NA @@ -294,7 +301,8 @@ Error: ! Can't extract element with `na_int`. - x Subscript `na_int` must be a location, not an integer `NA`. + Caused by error: + ! `na_int` must be a location, not an integer `NA`. Code (expect_error(vec_as_location2(na_chr, 1L, names = "foo"), class = "vctrs_error_subscript_type") ) @@ -302,7 +310,8 @@ Error: ! Can't extract element with `na_chr`. - x Subscript `na_chr` must be a location, not a character `NA`. + Caused by error: + ! `na_chr` must be a location, not a character `NA`. Code # Idem with custom `arg` (expect_error(vec_as_location2(na_int, 2L, arg = "foo", call = call( @@ -311,7 +320,8 @@ Error in `my_function()`: ! Can't extract element with `foo`. - x Subscript `foo` must be a location, not an integer `NA`. + Caused by error: + ! `foo` must be a location, not an integer `NA`. # num_as_location() optionally forbids negative indices @@ -744,7 +754,8 @@ Error in `my_function()`: ! Can't extract element with `foo`. - x Subscript `foo` must be a positive location, not -1. + Caused by error: + ! `foo` must be a positive location, not -1. Code (expect_error(vec_as_location2(0, 2, arg = "foo", call = call("my_function")), class = "vctrs_error_subscript_type")) @@ -752,7 +763,8 @@ Error in `my_function()`: ! Can't extract element with `foo`. - x Subscript `foo` must be a positive location, not 0. + Caused by error: + ! `foo` must be a positive location, not 0. Code (expect_error(vec_as_location2(na_dbl, 2, arg = "foo", call = call( "my_function")), class = "vctrs_error_subscript_type")) @@ -760,7 +772,8 @@ Error in `my_function()`: ! Can't extract element with `foo`. - x Subscript `foo` must be a location, not an integer `NA`. + Caused by error: + ! `foo` must be a location, not an integer `NA`. Code (expect_error(vec_as_location2(c(1, 2), 2, arg = "foo", call = call( "my_function")), class = "vctrs_error_subscript_type")) @@ -768,7 +781,8 @@ Error in `my_function()`: ! Can't extract element with `foo`. - x Subscript `foo` must be size 1, not 2. + Caused by error: + ! `foo` must be size 1, not 2. Code (expect_error(vec_as_location(c(TRUE, FALSE), 3, arg = "foo", call = call( "my_function")), class = "vctrs_error_subscript_size")) @@ -833,7 +847,8 @@ Error: ! Can't rename column with `foo(bar)`. - x Subscript `foo(bar)` must be a positive location, not -1. + Caused by error: + ! `foo(bar)` must be a positive location, not -1. Code (expect_error(with_tibble_cols(vec_as_location2(0, 2)), class = "vctrs_error_subscript_type") ) @@ -841,7 +856,8 @@ Error: ! Can't rename column with `foo(bar)`. - x Subscript `foo(bar)` must be a positive location, not 0. + Caused by error: + ! `foo(bar)` must be a positive location, not 0. Code (expect_error(with_tibble_cols(vec_as_location2(na_dbl, 2)), class = "vctrs_error_subscript_type") ) @@ -849,7 +865,8 @@ Error: ! Can't rename column with `foo(bar)`. - x Subscript `foo(bar)` must be a location, not an integer `NA`. + Caused by error: + ! `foo(bar)` must be a location, not an integer `NA`. Code (expect_error(with_tibble_cols(vec_as_location2(c(1, 2), 2)), class = "vctrs_error_subscript_type") ) @@ -857,7 +874,8 @@ Error: ! Can't rename column with `foo(bar)`. - x Subscript `foo(bar)` must be size 1, not 2. + Caused by error: + ! `foo(bar)` must be size 1, not 2. Code (expect_error(with_tibble_cols(vec_as_location(c(TRUE, FALSE), 3)), class = "vctrs_error_subscript_size") ) From 0365f28a88566ba3c8ff23f1f2f78e1c21f67fee Mon Sep 17 00:00:00 2001 From: Lionel Henry Date: Fri, 21 Oct 2022 13:56:44 +0200 Subject: [PATCH 12/12] Use chained errors in `subscript.c` --- NAMESPACE | 1 - R/subscript.R | 26 +++++----- src/decl/subscript-decl.h | 12 ++--- src/globals.c | 1 + src/globals.h | 1 + src/subscript.c | 40 +++++++------- tests/testthat/_snaps/error-call.md | 12 +++-- tests/testthat/_snaps/slice-chop.md | 6 ++- tests/testthat/_snaps/slice.md | 9 ++-- tests/testthat/_snaps/subscript-loc.md | 72 +++++++++++++++++--------- tests/testthat/_snaps/subscript.md | 57 +++++++++++++------- 11 files changed, 146 insertions(+), 91 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 84a176d1b..221d799df 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -102,7 +102,6 @@ S3method(cnd_body,vctrs_error_names_cannot_be_dot_dot) S3method(cnd_body,vctrs_error_names_cannot_be_empty) S3method(cnd_body,vctrs_error_names_must_be_unique) S3method(cnd_body,vctrs_error_subscript_oob) -S3method(cnd_body,vctrs_error_subscript_type) S3method(cnd_header,vctrs_error_cast_lossy) S3method(cnd_header,vctrs_error_incompatible_size) S3method(cnd_header,vctrs_error_matches_incomplete) diff --git a/R/subscript.R b/R/subscript.R index c31ab66ce..317aa236a 100644 --- a/R/subscript.R +++ b/R/subscript.R @@ -177,6 +177,8 @@ new_chained_error_subscript_type <- function(i, ..., header = NULL, call = caller_env()) { + header <- header %||% cnd_header_subscript_type + causal <- error_cnd( i = i, header = header, @@ -266,19 +268,19 @@ cnd_header.vctrs_error_subscript_type <- function(cnd) { glue::glue("Can't {action} {elt[[2]]}{with}.") } } -#' @export -cnd_body.vctrs_error_subscript_type <- function(cnd) { + +cnd_header_subscript_type <- function(cnd, ...) { arg <- cnd_subscript_arg(cnd) type <- obj_type_friendly(cnd$i) expected_types <- cnd_subscript_expected_types(cnd) - format_error_bullets(c( - x = cli::format_inline("{arg} must be {.or {expected_types}}, not {type}.") - )) + cli::format_inline("{arg} must be {.or {expected_types}}, not {type}.") } -new_cnd_bullets_subscript_lossy_cast <- function(lossy_err) { + +new_cnd_header_subscript_lossy_cast <- function(lossy_err) { + force(lossy_err) function(cnd, ...) { - format_error_bullets(c(x = cnd_header(lossy_err))) + cnd_header(lossy_err) } } @@ -327,8 +329,8 @@ new_error_subscript2_type <- function(i, ) } -cnd_body_subscript_dim <- function(cnd, ...) { - arg <- append_arg("Subscript", cnd$subscript_arg) +cnd_header_subscript_dim <- function(cnd, ...) { + arg <- cnd_subscript_arg(cnd) dim <- length(dim(cnd$i)) if (dim < 2) { @@ -340,9 +342,9 @@ cnd_body_subscript_dim <- function(cnd, ...) { shape <- "an array" } - format_error_bullets(c( - x = glue::glue("{arg} must be a simple vector, not {shape}.") - )) + c( + glue::glue("{arg} must be a simple vector, not {shape}.") + ) } cnd_subscript_element <- function(cnd, capital = FALSE) { diff --git a/src/decl/subscript-decl.h b/src/decl/subscript-decl.h index 118c66e38..4e2f66ce7 100644 --- a/src/decl/subscript-decl.h +++ b/src/decl/subscript-decl.h @@ -1,10 +1,10 @@ static -r_obj* fns_cnd_body_subscript_dim; +r_obj* fns_cnd_header_subscript_dim; static -r_obj* new_error_subscript_type(r_obj* subscript, - const struct subscript_opts* opts, - r_obj* body); +r_obj* new_chained_error_subscript_type(r_obj* subscript, + const struct subscript_opts* opts, + r_obj* body); static enum subscript_type_action parse_subscript_arg_type(r_obj* x, @@ -26,10 +26,10 @@ r_obj* dbl_cast_subscript_fallback(r_obj* subscript, ERR* err); static -r_obj* syms_new_dbl_cast_subscript_body; +r_obj* syms_new_cnd_header_subscript_lossy_cast; static r_obj* syms_lossy_err; static -r_obj* syms_new_error_subscript_type; +r_obj* syms_new_chained_error_subscript_type; diff --git a/src/globals.c b/src/globals.c index 772e4998a..141bdaaf0 100644 --- a/src/globals.c +++ b/src/globals.c @@ -54,6 +54,7 @@ void vctrs_init_globals(r_obj* ns) { syms.dot_error_arg = r_sym(".error_arg"); syms.dot_error_call = r_sym(".error_call"); syms.haystack_arg = r_sym("haystack_arg"); + syms.header = r_sym("header"); syms.needles_arg = r_sym("needles_arg"); syms.recurse = r_sym("recurse"); syms.repair_arg = r_sym("repair_arg"); diff --git a/src/globals.h b/src/globals.h index b2a6e501d..b6b89e6ed 100644 --- a/src/globals.h +++ b/src/globals.h @@ -11,6 +11,7 @@ struct syms { r_obj* dot_error_arg; r_obj* dot_error_call; r_obj* haystack_arg; + r_obj* header; r_obj* needles_arg; r_obj* recurse; r_obj* repair_arg; diff --git a/src/subscript.c b/src/subscript.c index 99c99e77b..88a9e1576 100644 --- a/src/subscript.c +++ b/src/subscript.c @@ -6,7 +6,7 @@ r_obj* vec_as_subscript_opts(r_obj* subscript, const struct subscript_opts* opts, ERR* err) { if (vec_dim_n(subscript) != 1) { - *err = new_error_subscript_type(subscript, opts, fns_cnd_body_subscript_dim); + *err = new_chained_error_subscript_type(subscript, opts, fns_cnd_header_subscript_dim); return r_null; } @@ -32,7 +32,7 @@ r_obj* vec_as_subscript_opts(r_obj* subscript, KEEP_AT(subscript, subscript_pi); if (!vec_is_vector(subscript)) { - *err = new_error_subscript_type(subscript, opts, r_null); + *err = new_chained_error_subscript_type(subscript, opts, r_null); FREE(2); return r_null; } @@ -78,7 +78,7 @@ r_obj* vec_as_subscript_opts(r_obj* subscript, } if (action == SUBSCRIPT_TYPE_ACTION_ERROR) { - *err = new_error_subscript_type(subscript, opts, r_null); + *err = new_chained_error_subscript_type(subscript, opts, r_null); FREE(2); return r_null; } @@ -126,7 +126,7 @@ r_obj* obj_cast_subscript(r_obj* subscript, return vec_cast_opts(&cast_opts); } - *err = new_error_subscript_type(subscript, opts, r_null); + *err = new_chained_error_subscript_type(subscript, opts, r_null); return r_null; } @@ -185,10 +185,10 @@ r_obj* dbl_cast_subscript_fallback(r_obj* subscript, if (*err) { r_obj* err_obj = KEEP(*err); - r_obj* body = KEEP(vctrs_eval_mask1(syms_new_dbl_cast_subscript_body, - syms_lossy_err, err_obj)); + r_obj* header = KEEP(vctrs_eval_mask1(syms_new_cnd_header_subscript_lossy_cast, + syms_lossy_err, err_obj)); - *err = new_error_subscript_type(subscript, opts, body); + *err = new_chained_error_subscript_type(subscript, opts, header); FREE(3); return r_null; } @@ -285,9 +285,9 @@ enum subscript_type_action parse_subscript_arg_type(r_obj* x, // Conditions ------------------------------------------------------------------ static -r_obj* new_error_subscript_type(r_obj* subscript, - const struct subscript_opts* opts, - r_obj* body) { +r_obj* new_chained_error_subscript_type(r_obj* subscript, + const struct subscript_opts* opts, + r_obj* header) { r_obj* logical = subscript_type_action_chr(opts->logical); r_obj* numeric = subscript_type_action_chr(opts->numeric); r_obj* character = subscript_type_action_chr(opts->character); @@ -296,7 +296,7 @@ r_obj* new_error_subscript_type(r_obj* subscript, r_obj* subscript_arg = KEEP(vctrs_arg(opts->subscript_arg)); r_obj* ffi_call = r_lazy_eval_protect(opts->call); - r_obj* syms[] = { + r_obj* params[] = { syms_i, syms_subscript_arg, syms_subscript_action, @@ -304,7 +304,7 @@ r_obj* new_error_subscript_type(r_obj* subscript, syms_logical, syms_numeric, syms_character, - syms_body, + syms.header, NULL }; r_obj* args[] = { @@ -315,11 +315,11 @@ r_obj* new_error_subscript_type(r_obj* subscript, logical, numeric, character, - body, + header, NULL }; - r_obj* call = KEEP(r_call_n(syms_new_error_subscript_type, syms, args)); + r_obj* call = KEEP(r_call_n(syms_new_chained_error_subscript_type, params, args)); r_obj* out = r_eval(call, vctrs_ns_env); FREE(3); @@ -330,21 +330,21 @@ r_obj* new_error_subscript_type(r_obj* subscript, // Init ---------------------------------------------------------------- void vctrs_init_subscript(r_obj* ns) { - syms_new_error_subscript_type = r_sym("new_error_subscript_type"); - syms_new_dbl_cast_subscript_body = r_sym("new_cnd_bullets_subscript_lossy_cast"); + syms_new_chained_error_subscript_type = r_sym("new_chained_error_subscript_type"); + syms_new_cnd_header_subscript_lossy_cast = r_sym("new_cnd_header_subscript_lossy_cast"); syms_lossy_err = r_sym("lossy_err"); - fns_cnd_body_subscript_dim = r_eval(r_sym("cnd_body_subscript_dim"), ns); + fns_cnd_header_subscript_dim = r_eval(r_sym("cnd_header_subscript_dim"), ns); } static -r_obj* fns_cnd_body_subscript_dim = NULL; +r_obj* fns_cnd_header_subscript_dim = NULL; static -r_obj* syms_new_dbl_cast_subscript_body = NULL; +r_obj* syms_new_cnd_header_subscript_lossy_cast = NULL; static r_obj* syms_lossy_err = NULL; static -r_obj* syms_new_error_subscript_type = NULL; +r_obj* syms_new_chained_error_subscript_type = NULL; diff --git a/tests/testthat/_snaps/error-call.md b/tests/testthat/_snaps/error-call.md index d14de133e..83ae58ac2 100644 --- a/tests/testthat/_snaps/error-call.md +++ b/tests/testthat/_snaps/error-call.md @@ -219,7 +219,8 @@ Error in `my_function()`: ! Can't subset elements with `my_arg`. - x Can't convert from `my_arg` to due to loss of precision. + Caused by error: + ! Can't convert from `my_arg` to due to loss of precision. --- @@ -229,7 +230,8 @@ Error in `my_function()`: ! Can't subset elements. - x Can't convert from to due to loss of precision. + Caused by error: + ! Can't convert from to due to loss of precision. --- @@ -239,7 +241,8 @@ Error in `my_function()`: ! Can't subset elements with `my_arg`. - x `my_arg` must be logical, numeric, or character, not an empty list. + Caused by error: + ! `my_arg` must be logical, numeric, or character, not an empty list. --- @@ -328,7 +331,8 @@ Error in `vec_slice()`: ! Can't subset elements with `i`. - x `i` must be logical, numeric, or character, not an environment. + Caused by error: + ! `i` must be logical, numeric, or character, not an environment. # list_sizes() reports error context diff --git a/tests/testthat/_snaps/slice-chop.md b/tests/testthat/_snaps/slice-chop.md index 68d038f87..ed80d14bc 100644 --- a/tests/testthat/_snaps/slice-chop.md +++ b/tests/testthat/_snaps/slice-chop.md @@ -301,7 +301,8 @@ Error: ! Can't subset elements. - x Subscript must be numeric, not the string "x". + Caused by error: + ! Subscript must be numeric, not the string "x". Code (expect_error(list_unchop(list(1), indices = list(foobar(1L))), class = "vctrs_error_subscript_type") ) @@ -309,7 +310,8 @@ Error: ! Can't subset elements. - x Subscript must be numeric, not a object. + Caused by error: + ! Subscript must be numeric, not a object. # can ignore names in `list_unchop()` by providing a `zap()` name-spec (#232) diff --git a/tests/testthat/_snaps/slice.md b/tests/testthat/_snaps/slice.md index da8a10a7a..1a99298bc 100644 --- a/tests/testthat/_snaps/slice.md +++ b/tests/testthat/_snaps/slice.md @@ -6,7 +6,8 @@ Error in `vec_slice()`: ! Can't subset elements with `i`. - x `i` must be logical, numeric, or character, not a object. + Caused by error: + ! `i` must be logical, numeric, or character, not a object. Code (expect_error(vec_slice(1:3, matrix(TRUE, nrow = 1)), class = "vctrs_error_subscript_type") ) @@ -14,7 +15,8 @@ Error in `vec_slice()`: ! Can't subset elements with `i`. - x Subscript `i` must be a simple vector, not a matrix. + Caused by error: + ! `i` must be a simple vector, not a matrix. # can't index beyond the end of a vector @@ -43,7 +45,8 @@ Error: ! Can't subset elements with `2^31`. - x Can't convert from `2^31` to due to loss of precision. + Caused by error: + ! Can't convert from `2^31` to due to loss of precision. # Unnamed vector with character subscript is caught diff --git a/tests/testthat/_snaps/subscript-loc.md b/tests/testthat/_snaps/subscript-loc.md index a618c3227..8fe851989 100644 --- a/tests/testthat/_snaps/subscript-loc.md +++ b/tests/testthat/_snaps/subscript-loc.md @@ -7,7 +7,8 @@ Error: ! Can't extract element with `TRUE`. - x `TRUE` must be numeric or character, not `TRUE`. + Caused by error: + ! `TRUE` must be numeric or character, not `TRUE`. Code (expect_error(vec_as_location2(mtcars, 10L), class = "vctrs_error_subscript_type") ) @@ -15,7 +16,8 @@ Error: ! Can't extract element with `mtcars`. - x `mtcars` must be numeric or character, not a object. + Caused by error: + ! `mtcars` must be numeric or character, not a object. Code (expect_error(vec_as_location2(env(), 10L), class = "vctrs_error_subscript_type") ) @@ -23,7 +25,8 @@ Error: ! Can't extract element with `env()`. - x `env()` must be numeric or character, not an environment. + Caused by error: + ! `env()` must be numeric or character, not an environment. Code (expect_error(vec_as_location2(foobar(), 10L), class = "vctrs_error_subscript_type") ) @@ -31,21 +34,24 @@ Error: ! Can't extract element with `foobar()`. - x `foobar()` must be numeric or character, not a object. + Caused by error: + ! `foobar()` must be numeric or character, not a object. Code (expect_error(vec_as_location2(2.5, 10L), class = "vctrs_error_subscript_type")) Output Error: ! Can't extract element with `2.5`. - x Can't convert from `2.5` to due to loss of precision. + Caused by error: + ! Can't convert from `2.5` to due to loss of precision. Code (expect_error(vec_as_location2(Inf, 10L), class = "vctrs_error_subscript_type")) Output Error: ! Can't extract element with `Inf`. - x Can't convert from `Inf` to due to loss of precision. + Caused by error: + ! Can't convert from `Inf` to due to loss of precision. Code (expect_error(vec_as_location2(-Inf, 10L), class = "vctrs_error_subscript_type") ) @@ -53,7 +59,8 @@ Error: ! Can't extract element with `-Inf`. - x Can't convert from `-Inf` to due to loss of precision. + Caused by error: + ! Can't convert from `-Inf` to due to loss of precision. Code # Idem with custom `arg` (expect_error(vec_as_location2(foobar(), 10L, arg = "foo", call = call( @@ -62,7 +69,8 @@ Error in `my_function()`: ! Can't extract element with `foo`. - x `foo` must be numeric or character, not a object. + Caused by error: + ! `foo` must be numeric or character, not a object. Code (expect_error(vec_as_location2(2.5, 3L, arg = "foo", call = call("my_function")), class = "vctrs_error_subscript_type")) @@ -70,7 +78,8 @@ Error in `my_function()`: ! Can't extract element with `foo`. - x Can't convert from `foo` to due to loss of precision. + Caused by error: + ! Can't convert from `foo` to due to loss of precision. Code (expect_error(with_tibble_rows(vec_as_location2(TRUE)), class = "vctrs_error_subscript_type") ) @@ -78,7 +87,8 @@ Error: ! Can't remove row with `foo(bar)`. - x `foo(bar)` must be numeric or character, not `TRUE`. + Caused by error: + ! `foo(bar)` must be numeric or character, not `TRUE`. # vec_as_location() requires integer, character, or logical inputs @@ -89,7 +99,8 @@ Error: ! Can't subset elements with `mtcars`. - x `mtcars` must be logical, numeric, or character, not a object. + Caused by error: + ! `mtcars` must be logical, numeric, or character, not a object. Code (expect_error(vec_as_location(env(), 10L), class = "vctrs_error_subscript_type") ) @@ -97,7 +108,8 @@ Error: ! Can't subset elements with `env()`. - x `env()` must be logical, numeric, or character, not an environment. + Caused by error: + ! `env()` must be logical, numeric, or character, not an environment. Code (expect_error(vec_as_location(foobar(), 10L), class = "vctrs_error_subscript_type") ) @@ -105,14 +117,16 @@ Error: ! Can't subset elements with `foobar()`. - x `foobar()` must be logical, numeric, or character, not a object. + Caused by error: + ! `foobar()` must be logical, numeric, or character, not a object. Code (expect_error(vec_as_location(2.5, 10L), class = "vctrs_error_subscript_type")) Output Error: ! Can't subset elements with `2.5`. - x Can't convert from `2.5` to due to loss of precision. + Caused by error: + ! Can't convert from `2.5` to due to loss of precision. Code (expect_error(vec_as_location(list(), 10L), class = "vctrs_error_subscript_type") ) @@ -120,7 +134,8 @@ Error: ! Can't subset elements with `list()`. - x `list()` must be logical, numeric, or character, not an empty list. + Caused by error: + ! `list()` must be logical, numeric, or character, not an empty list. Code (expect_error(vec_as_location(function() NULL, 10L), class = "vctrs_error_subscript_type") ) @@ -128,7 +143,8 @@ Error: ! Can't subset elements with `function() NULL`. - x `function() NULL` must be logical, numeric, or character, not a function. + Caused by error: + ! `function() NULL` must be logical, numeric, or character, not a function. Code (expect_error(vec_as_location(Sys.Date(), 3L), class = "vctrs_error_subscript_type") ) @@ -136,7 +152,8 @@ Error: ! Can't subset elements with `Sys.Date()`. - x `Sys.Date()` must be logical, numeric, or character, not a object. + Caused by error: + ! `Sys.Date()` must be logical, numeric, or character, not a object. Code # Idem with custom `arg` (expect_error(vec_as_location(env(), 10L, arg = "foo", call = call( @@ -145,7 +162,8 @@ Error in `my_function()`: ! Can't subset elements with `foo`. - x `foo` must be logical, numeric, or character, not an environment. + Caused by error: + ! `foo` must be logical, numeric, or character, not an environment. Code (expect_error(vec_as_location(foobar(), 10L, arg = "foo", call = call( "my_function")), class = "vctrs_error_subscript_type")) @@ -153,7 +171,8 @@ Error in `my_function()`: ! Can't subset elements with `foo`. - x `foo` must be logical, numeric, or character, not a object. + Caused by error: + ! `foo` must be logical, numeric, or character, not a object. Code (expect_error(vec_as_location(2.5, 3L, arg = "foo", call = call("my_function")), class = "vctrs_error_subscript_type")) @@ -161,7 +180,8 @@ Error in `my_function()`: ! Can't subset elements with `foo`. - x Can't convert from `foo` to due to loss of precision. + Caused by error: + ! Can't convert from `foo` to due to loss of precision. # vec_as_location() and variants check for OOB elements (#1605) @@ -252,7 +272,8 @@ Error in `my_function()`: ! Can't extract element with `foo`. - x `foo` must be numeric or character, not a object. + Caused by error: + ! `foo` must be numeric or character, not a object. Code (expect_error(vec_as_location2(1:2, 2L, arg = "foo", call = call("my_function")), class = "vctrs_error_subscript_type")) @@ -1070,7 +1091,8 @@ Error: ! Can't subset elements with `matrix(TRUE, nrow = 1)`. - x Subscript `matrix(TRUE, nrow = 1)` must be a simple vector, not a matrix. + Caused by error: + ! `matrix(TRUE, nrow = 1)` must be a simple vector, not a matrix. Code (expect_error(vec_as_location(array(TRUE, dim = c(1, 1, 1)), 3L), class = "vctrs_error_subscript_type") ) @@ -1078,7 +1100,8 @@ Error: ! Can't subset elements with `array(TRUE, dim = c(1, 1, 1))`. - x Subscript `array(TRUE, dim = c(1, 1, 1))` must be a simple vector, not an array. + Caused by error: + ! `array(TRUE, dim = c(1, 1, 1))` must be a simple vector, not an array. Code (expect_error(with_tibble_rows(vec_as_location(matrix(TRUE, nrow = 1), 3L)), class = "vctrs_error_subscript_type")) @@ -1086,7 +1109,8 @@ Error: ! Can't remove rows with `foo(bar)`. - x Subscript `foo(bar)` must be a simple vector, not a matrix. + Caused by error: + ! `foo(bar)` must be a simple vector, not a matrix. # vec_as_location() UI diff --git a/tests/testthat/_snaps/subscript.md b/tests/testthat/_snaps/subscript.md index 43aa2ff5c..7385e7810 100644 --- a/tests/testthat/_snaps/subscript.md +++ b/tests/testthat/_snaps/subscript.md @@ -7,7 +7,8 @@ Error: ! Can't rename columns with `foo(bar)`. - x `foo(bar)` must be logical, numeric, or character, not an environment. + Caused by error: + ! `foo(bar)` must be logical, numeric, or character, not an environment. --- @@ -18,7 +19,8 @@ Error: ! Can't extract tables with `foo(bar)`. - x `foo(bar)` must be logical, numeric, or character, not an environment. + Caused by error: + ! `foo(bar)` must be logical, numeric, or character, not an environment. # vec_as_subscript() checks dimensionality @@ -29,7 +31,8 @@ Error: ! Can't subset elements. - x Subscript must be a simple vector, not a matrix. + Caused by error: + ! Subscript must be a simple vector, not a matrix. Code (expect_error(vec_as_subscript(array(TRUE, dim = c(1, 1, 1))), class = "vctrs_error_subscript_type") ) @@ -37,7 +40,8 @@ Error: ! Can't subset elements. - x Subscript must be a simple vector, not an array. + Caused by error: + ! Subscript must be a simple vector, not an array. Code (expect_error(with_tibble_rows(vec_as_subscript(matrix(TRUE, nrow = 1))), class = "vctrs_error_subscript_type")) @@ -45,7 +49,8 @@ Error: ! Can't remove rows with `foo(bar)`. - x Subscript `foo(bar)` must be a simple vector, not a matrix. + Caused by error: + ! `foo(bar)` must be a simple vector, not a matrix. # vec_as_subscript() forbids subscript types @@ -54,7 +59,8 @@ Condition Error: ! Can't subset elements. - x Subscript must be character, not the number 1. + Caused by error: + ! Subscript must be character, not the number 1. --- @@ -63,7 +69,8 @@ Condition Error: ! Can't subset elements. - x Subscript must be numeric, not the string "foo". + Caused by error: + ! Subscript must be numeric, not the string "foo". --- @@ -72,7 +79,8 @@ Condition Error: ! Can't subset elements. - x Subscript must be numeric or character, not `TRUE`. + Caused by error: + ! Subscript must be numeric or character, not `TRUE`. --- @@ -81,7 +89,8 @@ Condition Error: ! Can't subset elements. - x Subscript must be logical or numeric, not the string "foo". + Caused by error: + ! Subscript must be logical or numeric, not the string "foo". --- @@ -90,7 +99,8 @@ Condition Error: ! Can't subset elements. - x Subscript must be logical or character, not `NULL`. + Caused by error: + ! Subscript must be logical or character, not `NULL`. --- @@ -99,7 +109,8 @@ Condition Error: ! Can't subset elements. - x Subscript must be logical or numeric, not a symbol. + Caused by error: + ! Subscript must be logical or numeric, not a symbol. # vec_as_subscript2() forbids subscript types @@ -108,7 +119,8 @@ Condition Error: ! Can't extract element. - x Subscript must be character, not the number 1. + Caused by error: + ! Subscript must be character, not the number 1. --- @@ -117,7 +129,8 @@ Condition Error: ! Can't extract element. - x Subscript must be numeric, not the string "foo". + Caused by error: + ! Subscript must be numeric, not the string "foo". --- @@ -126,7 +139,8 @@ Condition Error: ! Can't extract element. - x Subscript must be numeric or character, not `TRUE`. + Caused by error: + ! Subscript must be numeric or character, not `TRUE`. # vec_as_subscript2() retains the call when throwing vec_as_subscript() errors (#1605) @@ -135,7 +149,8 @@ Condition Error in `foo()`: ! Can't extract element. - x Subscript must be character, not the number 1. + Caused by error: + ! Subscript must be character, not the number 1. --- @@ -144,7 +159,8 @@ Condition Error in `foo()`: ! Can't extract element. - x Can't convert from to due to loss of precision. + Caused by error: + ! Can't convert from to due to loss of precision. # vec_as_subscript2() retains the call when erroring on logical input (#1605) @@ -153,7 +169,8 @@ Condition Error in `foo()`: ! Can't extract element. - x Subscript must be numeric or character, not `TRUE`. + Caused by error: + ! Subscript must be numeric or character, not `TRUE`. # `logical = 'cast'` is deprecated @@ -170,7 +187,8 @@ Condition Error: ! Can't extract element. - x Subscript must be numeric or character, not `TRUE`. + Caused by error: + ! Subscript must be numeric or character, not `TRUE`. # lossy cast errors for scalar subscripts work (#1606) @@ -179,5 +197,6 @@ Condition Error: ! Can't extract element. - x Can't convert from to due to loss of precision. + Caused by error: + ! Can't convert from to due to loss of precision.