From 7ea68da17cffe3ed559d355c44223c15e09986f4 Mon Sep 17 00:00:00 2001 From: hcirellu Date: Fri, 20 Mar 2026 11:19:49 +0100 Subject: [PATCH 1/7] introduce S3 for intersect and use S4 selectMethod in S3 dispatch --- NAMESPACE | 12 +++ R/bit64-package.R | 2 +- R/setops64.R | 57 +++++++++++-- man/sets.Rd | 3 +- tests/testthat/test-setops64.R | 143 +++++++++++++++++++++++++++++++++ 5 files changed, 210 insertions(+), 7 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index d80abdf4..27a788fc 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -89,8 +89,12 @@ S3method(hashtab,cache_integer64) S3method(hashuni,cache_integer64) S3method(hashupo,cache_integer64) S3method(identical,integer64) +S3method(intersect,default) +S3method(intersect,integer64) S3method(is.double,default) S3method(is.double,integer64) +S3method(is.element,default) +S3method(is.element,integer64) S3method(is.finite,integer64) S3method(is.infinite,integer64) S3method(is.na,integer64) @@ -155,6 +159,10 @@ S3method(rowSums,default) S3method(rowSums,integer64) S3method(scale,integer64) S3method(seq,integer64) +S3method(setdiff,default) +S3method(setdiff,integer64) +S3method(setequal,default) +S3method(setequal,integer64) S3method(shellorder,integer64) S3method(shellsort,integer64) S3method(shellsortorder,integer64) @@ -182,6 +190,8 @@ S3method(table,default) S3method(table,integer64) S3method(tiepos,integer64) S3method(trunc,integer64) +S3method(union,default) +S3method(union,integer64) S3method(unipos,integer64) S3method(unique,integer64) export("%in%") @@ -329,6 +339,8 @@ importFrom(graphics,par) importFrom(graphics,title) importFrom(methods,as) importFrom(methods,is) +importFrom(methods,isGeneric) +importFrom(methods,selectMethod) importFrom(stats,cor) importFrom(stats,median) importFrom(stats,quantile) diff --git a/R/bit64-package.R b/R/bit64-package.R index dbac467a..e6937154 100644 --- a/R/bit64-package.R +++ b/R/bit64-package.R @@ -704,7 +704,7 @@ #' ramsort ramsortorder repeat.time setattr shellorder shellsort #' shellsortorder still.identical #' @importFrom graphics barplot par title -#' @importFrom methods as is +#' @importFrom methods as is isGeneric selectMethod #' @importFrom stats cor median quantile #' @importFrom utils head packageDescription strOptions tail getS3method #' @export : %in% is.double match order print.cache rank diff --git a/R/setops64.R b/R/setops64.R index 78deb9ab..3af2e26f 100644 --- a/R/setops64.R +++ b/R/setops64.R @@ -28,12 +28,22 @@ #' setequal(x, y) #' is.element(x, y) #' +#' @name sets #' @export #' @rdname sets union = function(x, y) { + if ((isS4(x) || isS4(y)) && isGeneric("union")) + return(selectMethod("union", c(x=class(x), y=class(y)))(x, y)) if (!(is.integer64(x) || is.integer64(y))) - return(base::union(x, y)) + return(union.default(x, y)) + union.integer64(x, y) +} + +#' @exportS3Method union default +union.default = base::union +#' @exportS3Method union integer64 +union.integer64 = function(x, y) { target_class = target_class(list(x, y)) # try using the benefit of integer64 caching, if possible. I.e. call unique() before as(). x = unique(x) @@ -56,13 +66,23 @@ union = function(x, y) { unique(c(x, y)) } + #' @export #' @rdname sets intersect = function(x, y) { if (is.null(x) || is.null(y)) return(NULL) + if ((isS4(x) || isS4(y)) && isGeneric("intersect")) + return(selectMethod("intersect", c(x=class(x), y=class(y)))(x, y)) if (!(is.integer64(x) || is.integer64(y))) - return(base::intersect(x, y)) + return(intersect.default(x, y)) + intersect.integer64(x, y) +} + +#' @exportS3Method intersect default +intersect.default = base::intersect +#' @exportS3Method intersect integer64 +intersect.integer64 = function(x, y) { target_class = target_class(list(x, y)) x = unique(x) class_x = class(x)[1L] @@ -87,9 +107,18 @@ intersect = function(x, y) { #' @export #' @rdname sets setequal = function(x, y) { + if ((isS4(x) || isS4(y)) && isGeneric("setequal")) + return(selectMethod("setequal", c(x=class(x), y=class(y)))(x, y)) if (!(is.integer64(x) || is.integer64(y))) - return(base::setequal(x, y)) + return(setequal.default(x, y)) + setequal.integer64(x, y) +} + +#' @exportS3Method setequal default +setequal.default = base::setequal +#' @exportS3Method setequal integer64 +setequal.integer64 = function(x, y) { x = unique(x) y = unique(y) length_x = length(x) @@ -109,9 +138,18 @@ setequal = function(x, y) { #' @export #' @rdname sets setdiff = function(x, y) { + if ((isS4(x) || isS4(y)) && isGeneric("setdiff")) + return(selectMethod("setdiff", c(x=class(x), y=class(y)))(x, y)) if (!(is.integer64(x) || is.integer64(y))) - return(base::setdiff(x, y)) + return(setdiff.default(x, y)) + setdiff.integer64(x, y) +} + +#' @exportS3Method setdiff default +setdiff.default = base::setdiff +#' @exportS3Method setdiff integer64 +setdiff.integer64 = function(x, y) { class_x = class(x)[1L] if (class_x %in% c("POSIXct", "Date")) x = unclass(x) @@ -138,9 +176,18 @@ setdiff = function(x, y) { #' @export #' @rdname sets is.element = function(el, set) { + if ((isS4(el) || isS4(set)) && isGeneric("is.element")) + return(selectMethod("is.element", c(el=class(el), set=class(set)))(el, set)) if (!(is.integer64(el) || is.integer64(set))) - return(base::is.element(el, set)) + return(is.element.default(el, set)) + is.element.integer64(el, set) +} + +#' @exportS3Method is.element default +is.element.default = base::is.element +#' @exportS3Method is.element integer64 +is.element.integer64 = function(el, set) { target_class = target_class(list(el, set)) class_el = class(el)[1L] if (class_el != target_class) { diff --git a/man/sets.Rd b/man/sets.Rd index e93b18fe..2ecedcaa 100644 --- a/man/sets.Rd +++ b/man/sets.Rd @@ -1,6 +1,7 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/setops64.R -\name{union} +\name{sets} +\alias{sets} \alias{union} \alias{intersect} \alias{setequal} diff --git a/tests/testthat/test-setops64.R b/tests/testthat/test-setops64.R index 91c6ccb9..3890416c 100644 --- a/tests/testthat/test-setops64.R +++ b/tests/testthat/test-setops64.R @@ -320,3 +320,146 @@ test_that("is.element works (additional cases)", { expect_true(is.element(NA_integer64_, NA)) }) + +test_that("S4 dispatch still happens for classes extending integer (#301)", { + methods::setClass("TestS4", representation(data="integer")) + + delete_intersect_generic = !methods::isGeneric("intersect") + suppressMessages(methods::setGeneric("intersect")) + delete_union_generic = !methods::isGeneric("union") + suppressMessages(methods::setGeneric("union")) + delete_setdiff_generic = !methods::isGeneric("setdiff") + suppressMessages(methods::setGeneric("setdiff")) + + methods::setMethod( + "intersect", + signature=c("TestS4", "integer64"), + function(x, y) "Successfully routed to S4 method A!" + ) + methods::setMethod( + "intersect", + signature=c("TestS4", "TestS4"), + function(x, y) "Successfully routed to S4 method B!" + ) + methods::setMethod( + "union", + signature=c("TestS4", "integer64"), + function(x, y) "Successfully routed to S4 method A!" + ) + methods::setMethod( + "union", + signature=c("TestS4", "TestS4"), + function(x, y) "Successfully routed to S4 method B!" + ) + methods::setMethod( + "setdiff", + signature=c("TestS4", "integer64"), + function(x, y) "Successfully routed to S4 method A!" + ) + methods::setMethod( + "setdiff", + signature=c("TestS4", "TestS4"), + function(x, y) "Successfully routed to S4 method B!" + ) + withr::defer({ + methods::removeMethod("setdiff", signature=c("TestS4", "integer64")) + methods::removeMethod("union", signature=c("TestS4", "integer64")) + methods::removeMethod("intersect", signature=c("TestS4", "integer64")) + methods::removeClass("TestS4") + if (delete_setdiff_generic) methods::removeGeneric("setdiff") + if (delete_union_generic) methods::removeGeneric("union") + if (delete_intersect_generic) methods::removeGeneric("intersect") + }) + + # Instantiate test objects + x = methods::new("TestS4", data = 1L) + y = as.integer64(2L) + + expect_identical(intersect(x, y), "Successfully routed to S4 method A!") + expect_identical(union(x, y), "Successfully routed to S4 method A!") + expect_identical(setdiff(x, y), "Successfully routed to S4 method A!") + # NB: nanoival class is "complex64" -- it kludges complex to be a pair + # of integer64 vectors, but there is no complex64 class, so it just + # shows up on the inheritance chain as 'complex' --> need to ensure + # S4 gets invoked when possible even if the inputs don't directly test + # as being is("integer64"). + expect_identical(intersect(x, x), "Successfully routed to S4 method B!") + expect_identical(union(x, x), "Successfully routed to S4 method B!") + expect_identical(setdiff(x, x), "Successfully routed to S4 method B!") +}) + +test_that("S4 dispatch still happens for classes extending integer64 (#301)", { + methods::setClass("TestS4", representation(data="integer64")) + + delete_intersect_generic = !methods::isGeneric("intersect") + suppressMessages(methods::setGeneric("intersect")) + delete_union_generic = !methods::isGeneric("union") + suppressMessages(methods::setGeneric("union")) + delete_setdiff_generic = !methods::isGeneric("setdiff") + suppressMessages(methods::setGeneric("setdiff")) + + methods::setMethod( + "intersect", + signature=c("TestS4", "integer64"), + function(x, y) "Successfully routed to S4 method A!" + ) + methods::setMethod( + "intersect", + signature=c("TestS4", "TestS4"), + function(x, y) "Successfully routed to S4 method B!" + ) + methods::setMethod( + "union", + signature=c("TestS4", "integer64"), + function(x, y) "Successfully routed to S4 method A!" + ) + methods::setMethod( + "union", + signature=c("TestS4", "TestS4"), + function(x, y) "Successfully routed to S4 method B!" + ) + methods::setMethod( + "setdiff", + signature=c("TestS4", "integer64"), + function(x, y) "Successfully routed to S4 method A!" + ) + methods::setMethod( + "setdiff", + signature=c("TestS4", "TestS4"), + function(x, y) "Successfully routed to S4 method B!" + ) + withr::defer({ + methods::removeMethod("setdiff", signature=c("TestS4", "integer64")) + methods::removeMethod("union", signature=c("TestS4", "integer64")) + methods::removeMethod("intersect", signature=c("TestS4", "integer64")) + methods::removeClass("TestS4") + if (delete_setdiff_generic) methods::removeGeneric("setdiff") + if (delete_union_generic) methods::removeGeneric("union") + if (delete_intersect_generic) methods::removeGeneric("intersect") + }) + + # Instantiate test objects + x = methods::new("TestS4", data = as.integer64(1L)) + y = as.integer64(2L) + + expect_identical(intersect(x, y), "Successfully routed to S4 method A!") + expect_identical(union(x, y), "Successfully routed to S4 method A!") + expect_identical(setdiff(x, y), "Successfully routed to S4 method A!") + # NB: nanoival class is "complex64" -- it kludges complex to be a pair + # of integer64 vectors, but there is no complex64 class, so it just + # shows up on the inheritance chain as 'complex' --> need to ensure + # S4 gets invoked when possible even if the inputs don't directly test + # as being is("integer64"). + expect_identical(intersect(x, x), "Successfully routed to S4 method B!") + expect_identical(union(x, x), "Successfully routed to S4 method B!") + expect_identical(setdiff(x, x), "Successfully routed to S4 method B!") +}) + +test_that("S3 dispatch still happens for classes extending integer64 (#298)", { + x = 1:2 + y = as.integer64(1L) + class(y) = c('foo', 'integer64') + expect_identical(intersect(x, y), as.integer64(1L)) + expect_identical(union(x, y), as.integer64(1:2)) + expect_identical(setdiff(x, y), 2L) +}) From df3fd9beac4d4574b1f9ea034a903b7f4e500e0b Mon Sep 17 00:00:00 2001 From: hcirellu Date: Mon, 23 Mar 2026 16:23:04 +0100 Subject: [PATCH 2/7] extend test for S4 and S3 dispatch --- tests/testthat/test-setops64.R | 167 +++++++++------------------------ 1 file changed, 42 insertions(+), 125 deletions(-) diff --git a/tests/testthat/test-setops64.R b/tests/testthat/test-setops64.R index 3890416c..c3daf6bf 100644 --- a/tests/testthat/test-setops64.R +++ b/tests/testthat/test-setops64.R @@ -321,145 +321,62 @@ test_that("is.element works (additional cases)", { }) -test_that("S4 dispatch still happens for classes extending integer (#301)", { - methods::setClass("TestS4", representation(data="integer")) - - delete_intersect_generic = !methods::isGeneric("intersect") - suppressMessages(methods::setGeneric("intersect")) - delete_union_generic = !methods::isGeneric("union") - suppressMessages(methods::setGeneric("union")) - delete_setdiff_generic = !methods::isGeneric("setdiff") - suppressMessages(methods::setGeneric("setdiff")) - - methods::setMethod( - "intersect", - signature=c("TestS4", "integer64"), - function(x, y) "Successfully routed to S4 method A!" - ) - methods::setMethod( - "intersect", - signature=c("TestS4", "TestS4"), - function(x, y) "Successfully routed to S4 method B!" - ) - methods::setMethod( - "union", - signature=c("TestS4", "integer64"), - function(x, y) "Successfully routed to S4 method A!" - ) - methods::setMethod( - "union", - signature=c("TestS4", "TestS4"), - function(x, y) "Successfully routed to S4 method B!" - ) - methods::setMethod( - "setdiff", - signature=c("TestS4", "integer64"), - function(x, y) "Successfully routed to S4 method A!" - ) - methods::setMethod( - "setdiff", - signature=c("TestS4", "TestS4"), - function(x, y) "Successfully routed to S4 method B!" - ) - withr::defer({ - methods::removeMethod("setdiff", signature=c("TestS4", "integer64")) - methods::removeMethod("union", signature=c("TestS4", "integer64")) - methods::removeMethod("intersect", signature=c("TestS4", "integer64")) - methods::removeClass("TestS4") - if (delete_setdiff_generic) methods::removeGeneric("setdiff") - if (delete_union_generic) methods::removeGeneric("union") - if (delete_intersect_generic) methods::removeGeneric("intersect") - }) - - # Instantiate test objects - x = methods::new("TestS4", data = 1L) - y = as.integer64(2L) - - expect_identical(intersect(x, y), "Successfully routed to S4 method A!") - expect_identical(union(x, y), "Successfully routed to S4 method A!") - expect_identical(setdiff(x, y), "Successfully routed to S4 method A!") - # NB: nanoival class is "complex64" -- it kludges complex to be a pair - # of integer64 vectors, but there is no complex64 class, so it just - # shows up on the inheritance chain as 'complex' --> need to ensure - # S4 gets invoked when possible even if the inputs don't directly test - # as being is("integer64"). - expect_identical(intersect(x, x), "Successfully routed to S4 method B!") - expect_identical(union(x, x), "Successfully routed to S4 method B!") - expect_identical(setdiff(x, x), "Successfully routed to S4 method B!") +test_that("S3 dispatch happens for classes extending integer64 (#298)", { + x = 1:2 + y = as.integer64(2:3) + class(y) = c('foo', 'integer64') + expect_identical(intersect(x, y), as.integer64(2L)) + expect_identical(union(x, y), as.integer64(1:3)) + expect_identical(setdiff(x, y), 1L) }) -test_that("S4 dispatch still happens for classes extending integer64 (#301)", { - methods::setClass("TestS4", representation(data="integer64")) +# This test has to be the last test, because it removes the generics (e.g. intersect) during R CMD CHECK, +# such that the following test have base::intersect instead of bit64::intersect as 'generic'. +with_parameters_test_that("S4 and S3 dispatch still happens for classes extending {dataType} (#301)", { + x = as(1:2, dataType) + y = as.integer64(2:3) - delete_intersect_generic = !methods::isGeneric("intersect") - suppressMessages(methods::setGeneric("intersect")) - delete_union_generic = !methods::isGeneric("union") - suppressMessages(methods::setGeneric("union")) - delete_setdiff_generic = !methods::isGeneric("setdiff") - suppressMessages(methods::setGeneric("setdiff")) - - methods::setMethod( - "intersect", - signature=c("TestS4", "integer64"), - function(x, y) "Successfully routed to S4 method A!" - ) - methods::setMethod( - "intersect", - signature=c("TestS4", "TestS4"), - function(x, y) "Successfully routed to S4 method B!" - ) + # S4 + methods::setClass("TestS4", representation(data=dataType)) + delete_intersect_generic = !methods::isGeneric(method) + methods::setGeneric(method) methods::setMethod( - "union", + method, signature=c("TestS4", "integer64"), function(x, y) "Successfully routed to S4 method A!" ) methods::setMethod( - "union", + method, signature=c("TestS4", "TestS4"), function(x, y) "Successfully routed to S4 method B!" ) - methods::setMethod( - "setdiff", - signature=c("TestS4", "integer64"), - function(x, y) "Successfully routed to S4 method A!" - ) - methods::setMethod( - "setdiff", - signature=c("TestS4", "TestS4"), - function(x, y) "Successfully routed to S4 method B!" - ) - withr::defer({ - methods::removeMethod("setdiff", signature=c("TestS4", "integer64")) - methods::removeMethod("union", signature=c("TestS4", "integer64")) - methods::removeMethod("intersect", signature=c("TestS4", "integer64")) - methods::removeClass("TestS4") - if (delete_setdiff_generic) methods::removeGeneric("setdiff") - if (delete_union_generic) methods::removeGeneric("union") - if (delete_intersect_generic) methods::removeGeneric("intersect") - }) - # Instantiate test objects - x = methods::new("TestS4", data = as.integer64(1L)) - y = as.integer64(2L) - - expect_identical(intersect(x, y), "Successfully routed to S4 method A!") - expect_identical(union(x, y), "Successfully routed to S4 method A!") - expect_identical(setdiff(x, y), "Successfully routed to S4 method A!") + xS4 = methods::new("TestS4", data=x) + fun = get(method) + expect_identical(fun(xS4, y), "Successfully routed to S4 method A!") # NB: nanoival class is "complex64" -- it kludges complex to be a pair # of integer64 vectors, but there is no complex64 class, so it just # shows up on the inheritance chain as 'complex' --> need to ensure # S4 gets invoked when possible even if the inputs don't directly test # as being is("integer64"). - expect_identical(intersect(x, x), "Successfully routed to S4 method B!") - expect_identical(union(x, x), "Successfully routed to S4 method B!") - expect_identical(setdiff(x, x), "Successfully routed to S4 method B!") -}) - -test_that("S3 dispatch still happens for classes extending integer64 (#298)", { - x = 1:2 - y = as.integer64(1L) - class(y) = c('foo', 'integer64') - expect_identical(intersect(x, y), as.integer64(1L)) - expect_identical(union(x, y), as.integer64(1:2)) - expect_identical(setdiff(x, y), 2L) -}) + expect_identical(fun(xS4, xS4), "Successfully routed to S4 method B!") + + # S3 + yS3 = y + class(yS3) = c('foo', 'integer64') + if (dataType == "integer" && method == "setdiff") + expect_identical(fun(x, yS3), fun(as.integer(x), as.integer(y))) + else + expect_identical(fun(x, yS3), as.integer64(fun(as.integer(x), as.integer(y)))) + + # cleanup + methods::removeMethod(method, signature=c("TestS4", "integer64")) + methods::removeMethod(method, signature=c("TestS4", "TestS4")) + methods::removeClass("TestS4") + if (delete_intersect_generic) methods::removeGeneric(method) +}, +.cases=expand.grid( + dataType=c("integer", "integer64"), + method=c("intersect", "union", "setdiff"), + stringsAsFactors=FALSE +)) From cdd899fc38af29b502842ab9fc6aec303458a82a Mon Sep 17 00:00:00 2001 From: hcirellu Date: Mon, 23 Mar 2026 17:11:40 +0100 Subject: [PATCH 3/7] refactor test --- tests/testthat/test-setops64.R | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test-setops64.R b/tests/testthat/test-setops64.R index c3daf6bf..dd696c74 100644 --- a/tests/testthat/test-setops64.R +++ b/tests/testthat/test-setops64.R @@ -364,10 +364,11 @@ with_parameters_test_that("S4 and S3 dispatch still happens for classes extendin # S3 yS3 = y class(yS3) = c('foo', 'integer64') - if (dataType == "integer" && method == "setdiff") - expect_identical(fun(x, yS3), fun(as.integer(x), as.integer(y))) - else - expect_identical(fun(x, yS3), as.integer64(fun(as.integer(x), as.integer(y)))) + actual_result = fun(x, yS3) + expected_result = fun(as.integer(x), as.integer(y)) + if (!(dataType == "integer" && method == "setdiff")) + expected_result = as.integer64(expected_result) + expect_identical(actual_result, expected_result) # cleanup methods::removeMethod(method, signature=c("TestS4", "integer64")) From aca0bb9812dc4040933d64233b89451372624f7c Mon Sep 17 00:00:00 2001 From: hcirellu Date: Mon, 23 Mar 2026 17:21:01 +0100 Subject: [PATCH 4/7] add warning in test temporary --- tests/testthat/test-setops64.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/testthat/test-setops64.R b/tests/testthat/test-setops64.R index dd696c74..fbfd821a 100644 --- a/tests/testthat/test-setops64.R +++ b/tests/testthat/test-setops64.R @@ -368,6 +368,8 @@ with_parameters_test_that("S4 and S3 dispatch still happens for classes extendin expected_result = fun(as.integer(x), as.integer(y)) if (!(dataType == "integer" && method == "setdiff")) expected_result = as.integer64(expected_result) + warning(print(actual_result)) + warning(print(expected_result)) expect_identical(actual_result, expected_result) # cleanup From bb9d55d77ccd9e79aafba710576ae2b57fe5ceb4 Mon Sep 17 00:00:00 2001 From: hcirellu Date: Mon, 23 Mar 2026 17:57:54 +0100 Subject: [PATCH 5/7] check test for ubuntu oldrel-1 --- tests/testthat/test-setops64.R | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/testthat/test-setops64.R b/tests/testthat/test-setops64.R index fbfd821a..a25e54ea 100644 --- a/tests/testthat/test-setops64.R +++ b/tests/testthat/test-setops64.R @@ -361,15 +361,19 @@ with_parameters_test_that("S4 and S3 dispatch still happens for classes extendin # as being is("integer64"). expect_identical(fun(xS4, xS4), "Successfully routed to S4 method B!") + warning("fun: ", deparse(fun)) + # S3 yS3 = y class(yS3) = c('foo', 'integer64') + warning("x: ", deparse(x)) + warning("yS3: ", deparse(yS3)) actual_result = fun(x, yS3) expected_result = fun(as.integer(x), as.integer(y)) if (!(dataType == "integer" && method == "setdiff")) expected_result = as.integer64(expected_result) - warning(print(actual_result)) - warning(print(expected_result)) + warning("actual_result: ", deparse(actual_result)) + warning("expected_result: ", deparse(expected_result)) expect_identical(actual_result, expected_result) # cleanup @@ -380,6 +384,7 @@ with_parameters_test_that("S4 and S3 dispatch still happens for classes extendin }, .cases=expand.grid( dataType=c("integer", "integer64"), - method=c("intersect", "union", "setdiff"), + # method=c("intersect", "union", "setdiff"), + method=c("intersect"), stringsAsFactors=FALSE )) From 5ad5279663214cb2a2dbb3a7626be90929eb935b Mon Sep 17 00:00:00 2001 From: hcirellu Date: Mon, 23 Mar 2026 18:10:40 +0100 Subject: [PATCH 6/7] do not removeGeneric --- tests/testthat/test-setops64.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-setops64.R b/tests/testthat/test-setops64.R index a25e54ea..c4c0099e 100644 --- a/tests/testthat/test-setops64.R +++ b/tests/testthat/test-setops64.R @@ -380,7 +380,7 @@ with_parameters_test_that("S4 and S3 dispatch still happens for classes extendin methods::removeMethod(method, signature=c("TestS4", "integer64")) methods::removeMethod(method, signature=c("TestS4", "TestS4")) methods::removeClass("TestS4") - if (delete_intersect_generic) methods::removeGeneric(method) +# if (delete_intersect_generic) methods::removeGeneric(method) }, .cases=expand.grid( dataType=c("integer", "integer64"), From 4a98c04f0f37075ad13021d689c05391a4936abf Mon Sep 17 00:00:00 2001 From: hcirellu Date: Mon, 23 Mar 2026 18:19:15 +0100 Subject: [PATCH 7/7] fix test --- tests/testthat/test-setops64.R | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/tests/testthat/test-setops64.R b/tests/testthat/test-setops64.R index c4c0099e..0b86b257 100644 --- a/tests/testthat/test-setops64.R +++ b/tests/testthat/test-setops64.R @@ -330,15 +330,15 @@ test_that("S3 dispatch happens for classes extending integer64 (#298)", { expect_identical(setdiff(x, y), 1L) }) -# This test has to be the last test, because it removes the generics (e.g. intersect) during R CMD CHECK, -# such that the following test have base::intersect instead of bit64::intersect as 'generic'. +# This test has to be the last test, because it adds a generic (e.g. intersect), which cannot be removed properly during R CMD CHECK. +# If removeGeneric() is called the following test have base::intersect instead of bit64::intersect as 'generic'. +# This even applies for the two runs per 'method' within the test. with_parameters_test_that("S4 and S3 dispatch still happens for classes extending {dataType} (#301)", { x = as(1:2, dataType) y = as.integer64(2:3) # S4 methods::setClass("TestS4", representation(data=dataType)) - delete_intersect_generic = !methods::isGeneric(method) methods::setGeneric(method) methods::setMethod( method, @@ -361,30 +361,22 @@ with_parameters_test_that("S4 and S3 dispatch still happens for classes extendin # as being is("integer64"). expect_identical(fun(xS4, xS4), "Successfully routed to S4 method B!") - warning("fun: ", deparse(fun)) - # S3 yS3 = y class(yS3) = c('foo', 'integer64') - warning("x: ", deparse(x)) - warning("yS3: ", deparse(yS3)) actual_result = fun(x, yS3) expected_result = fun(as.integer(x), as.integer(y)) if (!(dataType == "integer" && method == "setdiff")) expected_result = as.integer64(expected_result) - warning("actual_result: ", deparse(actual_result)) - warning("expected_result: ", deparse(expected_result)) expect_identical(actual_result, expected_result) # cleanup methods::removeMethod(method, signature=c("TestS4", "integer64")) methods::removeMethod(method, signature=c("TestS4", "TestS4")) methods::removeClass("TestS4") -# if (delete_intersect_generic) methods::removeGeneric(method) }, .cases=expand.grid( dataType=c("integer", "integer64"), - # method=c("intersect", "union", "setdiff"), - method=c("intersect"), + method=c("intersect", "union", "setdiff"), stringsAsFactors=FALSE ))