Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use vctrs to perform input validation #961

Merged
merged 10 commits into from
Sep 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
no longer think they are the right approach to solving this problem.
See #768 for more information.

* Use of map functions with expressions, calls, and pairlists has been
deprecated (#961).

* `update_list()` (#858) and `rerun()` (#877), and the use of tidyselect
with `map_at()` and friends (#874) have been deprecated. These functions
use some form of non-standard evaluation which we now believe is a poor
Expand Down Expand Up @@ -177,7 +180,7 @@

## Minor improvements and bug fixes

* `modify()` no longer supports modifying calls or pairlists.
* `modify()` no longer works with calls or pairlists.

* `modify_depth()` is no longer a generic. This makes it more consistent
with `map_depth()`.
Expand Down
6 changes: 3 additions & 3 deletions R/list-modify.R
Original file line number Diff line number Diff line change
Expand Up @@ -43,23 +43,23 @@
#' l <- list(new = 1, y = zap(), z = 5)
#' str(list_update(x, !!!l))
list_update <- function(.x, ...) {
vec_check_list(.x)
.x <- vctrs_list_compat(.x)
y <- dots_list(..., .named = NULL, .homonyms = "error")
list_recurse(.x, y, function(x, y) y, recurse = FALSE)
}

#' @export
#' @rdname list_update
list_modify <- function(.x, ...) {
vec_check_list(.x)
.x <- vctrs_list_compat(.x)
y <- dots_list(..., .named = NULL, .homonyms = "error")
list_recurse(.x, y, function(x, y) y)
}

#' @export
#' @rdname list_update
list_merge <- function(.x, ...) {
vec_check_list(.x)
.x <- vctrs_list_compat(.x)
y <- dots_list(..., .named = NULL, .homonyms = "error")
list_recurse(.x, y, c)
}
Expand Down
4 changes: 4 additions & 0 deletions R/map.R
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,11 @@ map_chr <- function(.x, .f, ..., .progress = FALSE) {
}

map_ <- function(.type, .x, .f, ..., .progress = FALSE, ..error_call = caller_env()) {
.x <- vctrs_vec_compat(.x)
vec_assert(.x, arg = ".x", call = ..error_call)

.f <- as_mapper(.f, ...)

i <- 0L
with_indexed_errors(
i = i,
Expand Down
7 changes: 7 additions & 0 deletions R/map2.R
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,14 @@ map2_chr <- function(.x, .y, .f, ..., .progress = FALSE) {
}

map2_ <- function(.type, .x, .y, .f, ..., .progress = FALSE, ..error_call = caller_env()) {
.x <- vctrs_vec_compat(.x)
.y <- vctrs_vec_compat(.y)
args <- vec_recycle_common(.x = .x, .y = .y, .call = ..error_call)
.x <- args$.x
.y <- args$.y

.f <- as_mapper(.f, ...)

i <- 0L
with_indexed_errors(
i = i,
Expand Down
9 changes: 5 additions & 4 deletions R/pmap.R
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,13 @@ pmap_chr <- function(.l, .f, ..., .progress = FALSE) {
}

pmap_ <- function(.type, .l, .f, ..., .progress = FALSE, ..error_call = caller_env()) {
.l <- vctrs_list_compat(.l, error_call = ..error_call)
.l <- map(.l, vctrs_vec_compat)
.l <- vec_recycle_common(!!!.l, .arg = ".l", .call = ..error_call)
hadley marked this conversation as resolved.
Show resolved Hide resolved
DavisVaughan marked this conversation as resolved.
Show resolved Hide resolved

.f <- as_mapper(.f, ...)
if (is.data.frame(.l)) {
.l <- as.list(.l)
}
i <- 0L

i <- 0L
with_indexed_errors(
i = i,
error_call = ..error_call,
Expand Down
32 changes: 32 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,35 @@ is_quantity <- function(x) {
}
x
}

vctrs_list_compat <- function(x, error_call = caller_env(), error_arg = caller_arg(x)) {
force(error_arg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this required? I thought part of the point of passing error_call and error_arg through in the specific way that we do is to avoid forcing the promises until they are actually required

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to do it to get a good error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe preserve x by assigning the result of vctrs_vec_compat(x) to out instead of x?

I agree that the default pattern should be to evaluate these things lazily.

Copy link
Member

@DavisVaughan DavisVaughan Sep 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, I couldn't figure out what the problem was before but now I see that what Lionel suggests is a nice simple fix that maintains the standard pattern

vctrs_list_compat <- function(x, error_call = caller_env(), error_arg = caller_arg(x)) {
  out <- vctrs_vec_compat(x)
  vec_check_list(out, call = error_call, arg = error_arg)
  out
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, that's better. I pushed a fix to main.

x <- vctrs_vec_compat(x)
vec_check_list(x, call = error_call, arg = error_arg)
x
}

# When we want to use vctrs, but treat lists like purrr does
# Treat data frames and S3 scalar lists like bare lists.
# But ensure rcrd vctrs retain their class.
vctrs_vec_compat <- function(x) {
if (is.null(x)) {
list()
hadley marked this conversation as resolved.
Show resolved Hide resolved
} else if (is.pairlist(x)) {
lifecycle::deprecate_soft("1.0.0",
I("Use of pairlists in map functions"),
details = "Please coerce explicitly with `as.list()`"
)
as.list(x)
} else if (is_call(x) || is.expression(x)) {
lifecycle::deprecate_soft("1.0.0",
I("Use of calls and pairlists in map functions"),
details = "Please coerce explicitly with `as.list()`"
)
as.list(x)
} else if (is.data.frame(x) || (is.list(x) && !vec_is(x))) {
unclass(x)
} else {
x
}
}
103 changes: 68 additions & 35 deletions revdep/README.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,83 @@
# Revdeps

## Failed to check (7)
## Failed to check (12)

|package |version |error |warning |note |
|:------------|:-------|:------|:-------|:----|
|elbird |0.2.5 |1 | | |
|ggPMX |? | | | |
|ImputeRobust |? | | | |
|NA |? | | | |
|[kerastuneR](failures.md#kerastuner)|0.1.0.5 |__+1__ | |-1 |
|NA |? | | | |
|NA |? | | | |
|NA |? | | | |
|[rATTAINS](failures.md#rattains)|0.1.3 |__+1__ | | |
|NA |? | | | |
|[stoRy](failures.md#story)|0.2.0 |__+1__ | | |
|[tidyjson](failures.md#tidyjson)|0.3.1 |__+1__ | | |

## New problems (31)
## New problems (59)

|package |version |error |warning |note |
|:-------------------|:-------|:---------|:-------|:--------|
|[autothresholdr](problems.md#autothresholdr)|1.4.0 | |__+1__ | |
|[campsis](problems.md#campsis)|1.3.0 |__+1__ |__+1__ | |
|[casino](problems.md#casino)|0.1.0 | |__+1__ |2 |
|[cattonum](problems.md#cattonum)|0.0.5 | | |1 __+1__ |
|[csvwr](problems.md#csvwr)|0.1.6 |__+1__ | | |
|[dibble](problems.md#dibble)|0.2.1 |__+1__ | | |
|[egor](problems.md#egor)|1.22.5 |__+2__ | | |
|[emba](problems.md#emba)|0.1.8 |__+1__ | |1 |
|[escalation](problems.md#escalation)|0.1.4 |__+1__ |__+1__ |2 |
|[eventr](problems.md#eventr)|1.0.0 |__+1__ | |1 |
|[ffscrapr](problems.md#ffscrapr)|1.4.7 |__+1__ |__+1__ |1 |
|[gghighlight](problems.md#gghighlight)|0.3.3 | |__+1__ | |
|[gratia](problems.md#gratia)|0.7.3 |__+1__ | | |
|[grizbayr](problems.md#grizbayr)|1.3.2 |__+1__ | | |
|[gwasrapidd](problems.md#gwasrapidd)|0.99.13 |__+1__ | | |
|[healthcareai](problems.md#healthcareai)|2.5.1 | | |__+1__ |
|[immunarch](problems.md#immunarch)|0.7.0 |__+1__ | |1 |
|[linea](problems.md#linea)|0.0.3 |-1 __+1__ | | |
|[mskcc.oncotree](problems.md#mskcconcotree)|0.1.0 |__+1__ | |1 |
|[partialised](problems.md#partialised)|0.1.0 |__+1__ | | |
|[PHEindicatormethods](problems.md#pheindicatormethods)|1.4.1 |__+2__ | | |
|[PLNmodels](problems.md#plnmodels)|0.11.7 |__+1__ |__+1__ |1 |
|[quincunx](problems.md#quincunx)|0.1.5 |__+2__ | | |
|[rb3](problems.md#rb3)|0.0.6 |__+1__ |__+1__ | |
|[ruta](problems.md#ruta)|1.1.0 |__+2__ |__+1__ |1 |
|[sbm](problems.md#sbm)|0.4.4 |__+1__ | | |
|[scrutiny](problems.md#scrutiny)|0.2.2 |__+1__ |__+1__ | |
|[tidybins](problems.md#tidybins)|0.1.0 |__+1__ | |1 |
|[tidywikidatar](problems.md#tidywikidatar)|0.5.4 |__+1__ | | |
|[TT](problems.md#tt)|0.98 |__+1__ | | |
|[varsExplore](problems.md#varsexplore)|0.3.0 |__+1__ |__+1__ |2 |
|package |version |error |warning |note |
|:-------------------|:-------|:--------|:-------|:--------|
|[allhomes](problems.md#allhomes)|0.3.0 |__+1__ | | |
|[broom.helpers](problems.md#broomhelpers)|1.9.0 |__+1__ |__+1__ | |
|[bumbl](problems.md#bumbl)|1.0.2 |__+1__ | | |
|[cattonum](problems.md#cattonum)|0.0.5 | | |1 __+1__ |
|[cheese](problems.md#cheese)|0.1.1 |__+1__ |__+1__ | |
|[codebook](problems.md#codebook)|0.9.2 | |__+1__ |3 |
|[connectapi](problems.md#connectapi)|0.1.1.1 |__+1__ | | |
|[crosstable](problems.md#crosstable)|0.5.0 |__+1__ | | |
|[csvwr](problems.md#csvwr)|0.1.6 |__+1__ |__+1__ | |
|[cubelyr](problems.md#cubelyr)|1.0.1 |__+1__ | | |
|[DataFakeR](problems.md#datafaker)|0.1.2 |__+1__ |__+1__ |1 |
|[dibble](problems.md#dibble)|0.2.1 |__+1__ | | |
|[dm](problems.md#dm)|1.0.2 |1 __+1__ | | |
|[embed](problems.md#embed)|1.0.0 |__+1__ | |1 |
|[ergm](problems.md#ergm)|4.2.2 |__+1__ | |1 |
|[ergm.ego](problems.md#ergmego)|1.0.1 |__+1__ | | |
|[ffscrapr](problems.md#ffscrapr)|1.4.7 | |__+1__ |1 |
|[finetune](problems.md#finetune)|1.0.0 |__+1__ | | |
|[flexsurv](problems.md#flexsurv)|2.2 |__+1__ | |2 |
|[GDPuc](problems.md#gdpuc)|0.9.2 |__+1__ | | |
|[gghighlight](problems.md#gghighlight)|0.3.3 | |__+1__ | |
|[gratia](problems.md#gratia)|0.7.3 |__+1__ | | |
|[grizbayr](problems.md#grizbayr)|1.3.2 |__+1__ | | |
|[gtreg](problems.md#gtreg)|0.1.1 |__+1__ |__+1__ | |
|[gtsummary](problems.md#gtsummary)|1.6.1 |__+2__ | | |
|[gwasrapidd](problems.md#gwasrapidd)|0.99.13 |__+1__ | | |
|[healthcareai](problems.md#healthcareai)|2.5.1 | | |__+1__ |
|[ICD10gm](problems.md#icd10gm)|1.2.4 |__+1__ | |1 |
|[ipmr](problems.md#ipmr)|0.0.5 |__+1__ | |2 |
|[ir](problems.md#ir)|0.2.1 |__+1__ | | |
|[jpmesh](problems.md#jpmesh)|2.1.0 |__+2__ |__+1__ |1 |
|[jstor](problems.md#jstor)|0.3.10 |__+1__ | | |
|[mskcc.oncotree](problems.md#mskcconcotree)|0.1.0 |__+1__ | |1 |
|[partialised](problems.md#partialised)|0.1.0 |__+1__ | | |
|[PHEindicatormethods](problems.md#pheindicatormethods)|1.4.1 |__+1__ | | |
|[pkgdown](problems.md#pkgdown)|2.0.6 |__+1__ | |1 |
|[psfmi](problems.md#psfmi)|1.0.0 |__+1__ |__+1__ |1 |
|[quincunx](problems.md#quincunx)|0.1.5 |__+2__ | | |
|[RCLabels](problems.md#rclabels)|0.1.1 |__+1__ | | |
|[rearrr](problems.md#rearrr)|0.3.1 |__+1__ | | |
|[recipes](problems.md#recipes)|1.0.1 |__+2__ | |1 |
|[roxygen2](problems.md#roxygen2)|7.2.1 |__+1__ | | |
|[ruta](problems.md#ruta)|1.1.0 |__+2__ |__+1__ |1 |
|[sbm](problems.md#sbm)|0.4.4 |__+1__ | | |
|[scImmuneGraph](problems.md#scimmunegraph)|1.1.3 |__+1__ | |1 |
|[scrutiny](problems.md#scrutiny)|0.2.2 |__+1__ |__+1__ | |
|[simMetric](problems.md#simmetric)|0.1.0 |__+1__ | | |
|[simpr](problems.md#simpr)|0.2.2 |__+1__ | | |
|[sketch](problems.md#sketch)|1.1.17 |__+1__ | | |
|[skimr](problems.md#skimr)|2.1.4 |__+2__ |__+1__ | |
|[tergm](problems.md#tergm)|4.1.0 |__+1__ | | |
|[tidycmprsk](problems.md#tidycmprsk)|0.1.2 |__+2__ | | |
|[tidypredict](problems.md#tidypredict)|0.4.9 |__+1__ |__+1__ | |
|[tidyr](problems.md#tidyr)|1.2.1 |__+1__ | |1 |
|[tidytext](problems.md#tidytext)|0.3.4 |__+1__ | | |
|[tidywikidatar](problems.md#tidywikidatar)|0.5.4 |__+1__ | | |
|[Tplyr](problems.md#tplyr)|0.4.4 |__+1__ | | |
|[utile.tools](problems.md#utiletools)|0.2.7 |__+1__ | | |
|[workflowsets](problems.md#workflowsets)|1.0.0 |__+1__ | | |

Loading