Skip to content

Commit 745ab1a

Browse files
authored
Pass prototypes to vec_ptype2() methods (r-lib#1049)
1 parent 6123315 commit 745ab1a

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

NEWS.md

+4
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ The following errors are caused by breaking changes.
8686
worked correctly in a double-dispatch setting. Parent methods must
8787
now be called manually.
8888

89+
* `vec_ptype2()` methods now get zero-size prototypes as inputs. This
90+
guarantees that methods do not peek at the data to determine the
91+
richer type.
92+
8993
* `vec_is_list()` no longer allows S3 lists that implement a `vec_proxy()`
9094
method to automatically be considered lists. A S3 list must explicitly
9195
inherit from `"list"` in the base class to be considered a list.

src/ptype2-dispatch.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ static inline SEXP vec_ptype2_default(SEXP x,
6565

6666
// [[ include("vctrs.h") ]]
6767
SEXP vec_ptype2_dispatch_s3(const struct ptype2_opts* opts) {
68-
SEXP x = opts->x;
69-
SEXP y = opts->y;
68+
SEXP x = PROTECT(vec_ptype(opts->x, opts->x_arg));
69+
SEXP y = PROTECT(vec_ptype(opts->y, opts->y_arg));
7070

7171
SEXP x_arg_obj = PROTECT(vctrs_arg(opts->x_arg));
7272
SEXP y_arg_obj = PROTECT(vctrs_arg(opts->y_arg));
@@ -99,7 +99,7 @@ SEXP vec_ptype2_dispatch_s3(const struct ptype2_opts* opts) {
9999

100100
if (method == R_NilValue) {
101101
SEXP out = vec_ptype2_default(x, y, x_arg_obj, y_arg_obj, opts->df_fallback);
102-
UNPROTECT(3);
102+
UNPROTECT(5);
103103
return out;
104104
}
105105

@@ -109,7 +109,7 @@ SEXP vec_ptype2_dispatch_s3(const struct ptype2_opts* opts) {
109109
syms_x_arg, x_arg_obj,
110110
syms_y_arg, y_arg_obj);
111111

112-
UNPROTECT(3);
112+
UNPROTECT(5);
113113
return out;
114114
}
115115

tests/testthat/test-type2.R

+20
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,26 @@ test_that("common type warnings for data frames take attributes into account", {
282282
})
283283
})
284284

285+
test_that("vec_ptype2() methods get prototypes", {
286+
x <- NULL
287+
y <- NULL
288+
289+
local_methods(vec_ptype2.vctrs_foobar.vctrs_foobar = function(x, y, ...) {
290+
x <<- x
291+
y <<- y
292+
NULL
293+
})
294+
295+
vec_ptype2(foobar(1:3), foobar(letters))
296+
expect_identical(x, foobar(int()))
297+
expect_identical(y, foobar(chr()))
298+
299+
skip("Figure out what to do with row names in `vec_ptype()`")
300+
vec_ptype2(foobar(mtcars), foobar(iris))
301+
expect_identical(x, foobar(mtcars[0, , drop = FALSE]))
302+
expect_identical(y, foobar(iris[0, , drop = FALSE]))
303+
})
304+
285305
test_that("vec_ptype2() errors have informative output", {
286306
verify_output(test_path("error", "test-type2.txt"), {
287307
"# can override scalar vector error message for base scalar types"

0 commit comments

Comments
 (0)