Skip to content

Commit a2cb084

Browse files
committed
fix regression from introduction of external generics
1 parent 6e79bc9 commit a2cb084

2 files changed

Lines changed: 46 additions & 1 deletion

File tree

R/method-register-S4.R

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ class_has_S4_ancestor <- function(class) {
2828
}
2929

3030
S3_generic_S4_signature <- function(generic) {
31-
if (!is_S3_generic(generic) || !is_internal_generic(generic$name)) {
31+
if (
32+
!(is_S3_generic(generic) || is_external_S3_generic(generic)) ||
33+
!is_internal_generic(generic$name)
34+
) {
3235
return(NULL)
3336
}
3437

@@ -39,3 +42,8 @@ S3_generic_S4_signature <- function(generic) {
3942

4043
generic@signature
4144
}
45+
46+
is_external_S3_generic <- function(generic) {
47+
is_external_generic(generic) &&
48+
identical(generic$dispatch_args, "__S3__")
49+
}

tests/testthat/test-method-register-S3.R

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,43 @@ test_that("internal replacement generics can register full S4 signatures", {
128128
))
129129
})
130130

131+
test_that("sentinels for internal replacement generics keep full S4 signatures", {
132+
on.exit(S4_remove_classes(c(
133+
"S4regDimnamesSentinelParent",
134+
"S4regDimnamesSentinelChild"
135+
)))
136+
137+
setClass("S4regDimnamesSentinelParent", contains = "VIRTUAL")
138+
S4regDimnamesSentinelChild <- new_class(
139+
"S4regDimnamesSentinelChild",
140+
parent = getClass("S4regDimnamesSentinelParent"),
141+
properties = list(x = class_list),
142+
package = NULL
143+
)
144+
145+
dimnames_sentinel <- generic_sentinel(as_generic(`dimnames<-`))
146+
expect_no_error(
147+
register_method(
148+
dimnames_sentinel,
149+
list(S4regDimnamesSentinelChild, class_list),
150+
function(x, value) x,
151+
package = NULL
152+
)
153+
)
154+
on.exit(
155+
methods::removeMethod(
156+
"dimnames<-",
157+
c("S4regDimnamesSentinelChild", "list")
158+
),
159+
add = TRUE,
160+
after = FALSE
161+
)
162+
expect_true(methods::hasMethod(
163+
"dimnames<-",
164+
c("S4regDimnamesSentinelChild", "list")
165+
))
166+
})
167+
131168
test_that("S3 registration for a multi-class S3 class uses only the first class", {
132169
local_s3_generic("s3_gen")
133170
method(s3_gen, new_S3_class(c("ordered", "factor"))) <- function(x) "ord"

0 commit comments

Comments
 (0)