pkgload icon indicating copy to clipboard operation
pkgload copied to clipboard

Error in `unregister` for a package that contains an S3 method when there is an object in the global environment with the same name

Open AlexisDerumigny opened this issue 2 months ago • 0 comments

Thanks for the package, it is very useful! As I was developing a package, I encountered some issues with roxygen2 which I tracked down to pkgload::unregister.

When unregistering S3 methods, an error occur if there exists already an object in the global environment with the same name as the S3 method that pkgload is trying to unregister. The problem is at these lines: https://github.com/r-lib/pkgload/blob/7556a3f0a74e37afd5286b126b6b2321e563e761/R/unload.R#L135-L140

In my case, I defined a log-likelihood method for an object of class A called logLik.A but I had already an object called logLik in the environment. I solved the problem by cleaning up the environment, but I think this bug can be solved by testing whether generics is a function just after line 140.

Here is a reprex that shows this issue (tested on Windows 10, R 4.3.3, pkgload 1.3.4). The expected behavior is that there is no error, or that there is a more explicit error pointing to the name logLik which hides the S3 method with the same name.

mydir = normalizePath(tempdir())
package.skeleton(path = mydir)
#> Creating directories ...
#> Creating DESCRIPTION ...
#> Creating NAMESPACE ...
#> Creating Read-and-delete-me ...
#> Saving functions and data ...
#> Making help files ...
#> Done.
#> Further steps are described in 'C:\Users\aderumigny\AppData\Local\Temp\Rtmp0Yz0js/anRpackage/Read-and-delete-me'.
# Removing documentation to make it later with roxygen.
unlink(paste0(normalizePath(mydir), "\\anRpackage\\NAMESPACE"))
unlink(paste0(normalizePath(mydir), "\\anRpackage\\man"), recursive = TRUE)

dir.create(paste0(mydir, "\\anRpackage\\R"))
file.create(paste0(mydir, "\\anRpackage\\R\\a.R"))
#> [1] TRUE
cat("
#' An S3 method
#' @export
logLik.A <- function(object, ...){
  return (0)
}
", file = paste0(mydir, "\\anRpackage\\R\\a.R"))
logLik = 0


roxygen2::roxygenize(package.dir = paste0(normalizePath(mydir), "\\anRpackage"))
#> First time using roxygen2. Upgrading automatically...
#> Setting `RoxygenNote` to "7.3.1"
#> ✖ roxygen2 requires "Encoding: UTF-8"
#> ℹ Current encoding is NA
#> ℹ Loading anRpackage
#> Writing 'NAMESPACE'
#> Writing 'logLik.A.Rd'

pkgload::unregister("anRpackage")
#> Error in `fn_env()`:
#> ! `fn` must be a function, not the number 0.

rlang::last_trace()
<error/rlang_error>
Error in `fn_env()`:
! `fn` must be a function, not the number 0.
---
Backtrace:
    ▆
 1. └─pkgload::unregister("anRpackage")
 2.   └─pkgload:::unregister_methods(package)
 3.     └─pkgload:::s3_unregister(package)
 4.       ├─base::topenv(fn_env(generic))
 5.       └─rlang::fn_env(fn = generic)

AlexisDerumigny avatar Apr 08 '24 13:04 AlexisDerumigny