Skip to content

Commit

Permalink
v0.2.18 MTN R-devel API restrictions
Browse files Browse the repository at this point in the history
  • Loading branch information
brodieG committed Jun 22, 2024
2 parents 6ffdfc9 + 549880a commit 9d20600
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 23 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Title: Trust, but Verify
Description: Declarative template-based framework for verifying that objects
meet structural requirements, and auto-composing error messages when they do
not.
Version: 0.2.16
Version: 0.2.18
Authors@R: c(
person("Brodie", "Gaslam", email="[email protected]",
role=c("aut", "cre")),
Expand Down
8 changes: 8 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## 0.2.17-18

* Fix bad C API accesses uncovered by new R-devel checks.

## 0.2.16

* Fix -Wformat warnings.

## 0.2.15

* [#109](https://github.com/brodieG/vetr/issues/109) allow for substituted
Expand Down
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ care of the rest:
tpl <- numeric(1L)
vet(tpl, 1:3)
## [1] "`length(1:3)` should be 1 (is 3)"

vet(tpl, "hello")
## [1] "`\"hello\"` should be type \"numeric\" (is \"character\")"

vet(tpl, 42)
## [1] TRUE

Expand All @@ -59,6 +61,7 @@ example, zero length templates match any length:
tpl <- integer()
vet(tpl, 1L:3L)
## [1] TRUE

vet(tpl, 1L)
## [1] TRUE

Expand All @@ -68,6 +71,7 @@ considered integer:
tpl <- integer(1L)
vet(tpl, 1) # this is a numeric, not an integer
## [1] TRUE

vet(tpl, 1.0001)
## [1] "`1.0001` should be type \"integer-like\" (is \"double\")"

Expand All @@ -79,6 +83,7 @@ considered integer:

vet(tpl.iris, iris)
## [1] TRUE

vet(tpl.iris, iris.fake)
## [1] "`levels(iris.fake$Species)[3]` should be \"virginica\" (is \"sibirica\")"

Expand Down Expand Up @@ -134,8 +139,10 @@ You can combine templates with `&&` / `||`:

vet(numeric(1L) || NULL, NULL)
## [1] TRUE

vet(numeric(1L) || NULL, 42)
## [1] TRUE

vet(numeric(1L) || NULL, "foo")
## [1] "`\"foo\"` should be `NULL`, or type \"numeric\" (is \"character\")"

Expand All @@ -144,6 +151,7 @@ refer to the object:

vet(numeric(1L) && . > 0, -42) # strictly positive scalar numeric
## [1] "`-42 > 0` is not TRUE (FALSE)"

vet(numeric(1L) && . > 0, 42)
## [1] TRUE

Expand All @@ -161,8 +169,10 @@ them:

vet(vet.exp, 42)
## [1] TRUE

vet(vet.exp, "foo")
## [1] TRUE

vet(vet.exp, "baz")
## [1] "At least one of these should pass:"
## [2] " - `\"baz\" %in% c(\"foo\", \"bar\")` is not TRUE (FALSE)"
Expand All @@ -172,7 +182,7 @@ them:
`isTRUE(all(. >= x & . <= y))` for large vectors):

vet(all_bw(., 0, 1), runif(5) + 1)
## [1] "`all_bw(runif(5) + 1, 0, 1)` is not TRUE (is chr: \"`1.234342` at index 1 not in `[0,1]`\")"
## [1] "`all_bw(runif(5) + 1, 0, 1)` is not TRUE (is chr: \"`1.614709` at index 1 not in `[0,1]`\")"

There are a number of predefined vetting tokens you can use in your
vetting expressions such as:
Expand All @@ -198,6 +208,7 @@ functions:
}
fun(1:2, "foo")
## Error in fun(x = 1:2, y = "foo"): For argument `x`, `length(1:2)` should be 1 (is 2)

fun(1, "foo")
## Error in fun(x = 1, y = "foo"): For argument `y`, `"foo"` should be type "logical" (is "character")

Expand Down Expand Up @@ -280,9 +291,9 @@ review them:
- [`validate`](https://github.com/data-cleaning/validate) by Mark van
der Loo and Edwin de Jonge, with a primary focus on validating data
in data frames and similar data structures.
- [`assertr`](https://github.com/ropensci/assertr) by Tony Fischetti,
also focused on data validation in data frames and similar
structures.
- [`assertr`](https://github.com/tonyfischetti/assertr) by Tony
Fischetti, also focused on data validation in data frames and
similar structures.
- [`types`](https://github.com/jimhester/types) by Jim Hester, which
implements but does not enforce type hinting.
- [`argufy`](https://github.com/gaborcsardi/argufy) by Gábor Csárdi,
Expand Down
1 change: 1 addition & 0 deletions src/alike.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ Go to <https://www.r-project.org/Licenses/GPL-2> for a copy of the license.
extern SEXP ALIKEC_SYM_tilde;
extern SEXP ALIKEC_SYM_paren_open;
extern SEXP ALIKEC_SYM_args;
extern SEXP ALIKEC_SYM_function;
extern SEXP ALIKEC_SYM_deparse;
extern SEXP ALIKEC_SYM_nlines;
extern SEXP ALIKEC_SYM_getOption;
Expand Down
24 changes: 16 additions & 8 deletions src/fun.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,17 @@ struct ALIKEC_res ALIKEC_fun_alike_internal(
if(!isFunction(target) || !isFunction(current))
error("Arguments must be functions.");

SEXP tar_form, cur_form, args;
SEXP tar_form, cur_form, args, func;
SEXPTYPE tar_type = TYPEOF(target), cur_type = TYPEOF(current);
struct ALIKEC_res res = ALIKEC_res_init();

// Translate specials and builtins to formals, if possible

args = PROTECT(list2(ALIKEC_SYM_args, R_NilValue));
if(
tar_type == SPECIALSXP || tar_type == BUILTINSXP ||
cur_type == SPECIALSXP || cur_type == BUILTINSXP
) {
SET_TYPEOF(args, LANGSXP);
}
SET_TYPEOF(args, LANGSXP);
func = PROTECT(list3(ALIKEC_SYM_function, R_NilValue, R_NilValue));
SET_TYPEOF(func, LANGSXP);

if(tar_type == SPECIALSXP || tar_type == BUILTINSXP) {
SETCADR(args, target);
target = PROTECT(eval(args, R_BaseEnv));
Expand All @@ -69,6 +67,16 @@ struct ALIKEC_res ALIKEC_fun_alike_internal(
current = PROTECT(eval(args, R_BaseEnv));
} else PROTECT(R_NilValue);

// As of ~r86700 R became stricter about what we could call FORMALS on, so we
// need to make sure that we do get actual formals and not NULL.

if(TYPEOF(target) != CLOSXP) {
target = PROTECT(eval(func, R_BaseEnv));
} else PROTECT(R_NilValue);
if(TYPEOF(current) != CLOSXP) {
current = PROTECT(eval(func, R_BaseEnv));
} else PROTECT(R_NilValue);

// Cycle through all formals

int dots = 0, dots_last = 0, dots_reset = 0, tag_match = 1, dots_cur = 0;
Expand Down Expand Up @@ -156,7 +164,7 @@ struct ALIKEC_res ALIKEC_fun_alike_internal(
res.dat.strings.target[2] = arg_type;
}
}
UNPROTECT(3);
UNPROTECT(6);
if(!res.success) res.wrap = allocVector(VECSXP, 2);
return res;
}
Expand Down
2 changes: 2 additions & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ SEXP ALIKEC_SYM_inherits;
SEXP ALIKEC_SYM_paren_open;
SEXP ALIKEC_SYM_tilde;
SEXP ALIKEC_SYM_args;
SEXP ALIKEC_SYM_function;
SEXP ALIKEC_SYM_deparse;
SEXP ALIKEC_SYM_nlines;
SEXP ALIKEC_SYM_widthcutoff;
Expand Down Expand Up @@ -143,6 +144,7 @@ void R_init_vetr(DllInfo *info)
ALIKEC_SYM_paren_open = install("(");
ALIKEC_SYM_tilde = install("~");
ALIKEC_SYM_args = install("args");
ALIKEC_SYM_function = install("function");
ALIKEC_SYM_deparse = install("deparse");
ALIKEC_SYM_nlines = install("nlines");
ALIKEC_SYM_widthcutoff = install("width.cutoff");
Expand Down
14 changes: 6 additions & 8 deletions src/merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,17 @@ static SEXP ALIKEC_unique_msg(SEXP msgs) {
R_xlen_t len = xlength(msgs);
if(len < 2) return(msgs);

// Loop once to check for dupes
// Loop once to count how many distinct values

int some_dup = 0;
int distinct_vals = 1;
for(R_xlen_t i = 1; i < len; ++i) {
if(R_compute_identical(VECTOR_ELT(msgs, i - 1), VECTOR_ELT(msgs, i), 16)) {
some_dup = 1;
break;
if(!R_compute_identical(VECTOR_ELT(msgs, i - 1), VECTOR_ELT(msgs, i), 16)) {
++distinct_vals;
}
}
SEXP res;
if(some_dup) {
res = PROTECT(allocVector(VECSXP, len));
if(distinct_vals != len) {
res = PROTECT(allocVector(VECSXP, distinct_vals));
SET_VECTOR_ELT(res, 0, VECTOR_ELT(msgs, 0));
R_xlen_t j = 1;
for(R_xlen_t i = 1; i < len; ++i) {
Expand All @@ -138,7 +137,6 @@ static SEXP ALIKEC_unique_msg(SEXP msgs) {
SET_VECTOR_ELT(res, j++, VECTOR_ELT(msgs, i));
}
}
SETLENGTH(res, j);
UNPROTECT(1);
} else res = msgs;
return res;
Expand Down
2 changes: 1 addition & 1 deletion src/r-copied.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ SEXP ALIKEC_findFun(SEXP symbol, SEXP rho) {
error("Internal Error: `rho` must be environment");// nocov
SEXP vl;
while (rho != R_EmptyEnv) {
vl = findVarInFrame3(rho, symbol, TRUE);
vl = findVarInFrame(rho, symbol);
if (vl != R_UnboundValue) {
if (TYPEOF(vl) == PROMSXP) {
PROTECT(vl);
Expand Down
2 changes: 1 addition & 1 deletion vignettes/rmdhunks/related-packages.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ them:
* [`validate`](https://github.com/data-cleaning/validate) by Mark van
der Loo and Edwin de Jonge, with a primary focus on validating data in data
frames and similar data structures.
* [`assertr`](https://github.com/ropensci/assertr) by Tony Fischetti, also
* [`assertr`](https://github.com/tonyfischetti/assertr) by Tony Fischetti, also
focused on data validation in data frames and similar structures.
* [`types`](https://github.com/jimhester/types) by Jim Hester, which implements
but does not enforce type hinting.
Expand Down

0 comments on commit 9d20600

Please sign in to comment.