-
Notifications
You must be signed in to change notification settings - Fork 3
Packages of S4 functions are not identified by packagesOf() #73
Copy link
Copy link
Open
Labels
S4Related to the S4 class system in RRelated to the S4 class system in R
Description
Notice that DBI is not recognized as a required package in fn(). dbConnect() is a function from DBI.
library(globals)
library(DBI)
fn <- function() {
con <- dbConnect(RSQLite::SQLite(), dbname = ":memory:")
dbDisconnect(con)
1
}
# bad - where is DBI?
packagesOf(globalsOf(fn))
#> [1] "base"This causes the following type of failure:
library(DBI)
library(future)
fn <- function() {
# Tries to use `dbConnect()` that future pushes into the global env.
# DBI package is never loaded!
con <- dbConnect(RSQLite::SQLite(), dbname = ":memory:")
dbDisconnect(con)
1
}
fn2 <- function() {
# Forcibly use the `dbConnect()` function found in `DBI::`
con <- DBI::dbConnect(RSQLite::SQLite(), dbname = ":memory:")
DBI::dbDisconnect(con)
1
}
fn3 <- function() {
library(DBI)
# Tries to use `dbConnect()` that future pushes into the global env.
# That still shadows the one loaded by DBI
con <- dbConnect(RSQLite::SQLite(), dbname = ":memory:")
dbDisconnect(con)
1
}
# Failure, because DBI isn't loaded, we can't register methods for it
plan(multisession, workers = 2)
fut <- future(fn(), seed = 123)
value(fut)
#> Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ‘dbConnect’ for signature ‘"SQLiteDriver"’
plan(sequential)
# Works because `DBI::` loads DBI, and because we explicitly use
# the dbConnect() from `DBI::`, not the global env one
plan(multisession, workers = 2)
fut <- future(fn2(), seed = 123)
value(fut)
#> [1] 1
plan(sequential)
# DBI gets loaded by `library(DBI)`, but the `dbConnect()` that is
# present in the global env (put there by future) overshadows the
# DBI::dbConnect() function
plan(multisession, workers = 2)
fut <- future(fn3(), seed = 123)
value(fut)
#> Warning: package ‘DBI’ was built under R version 4.0.2
#>
#> Attaching package: ‘DBI’
#> The following objects are masked _by_ ‘.GlobalEnv’:
#>
#> dbConnect, dbDisconnect
#> Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ‘dbConnect’ for signature ‘"SQLiteDriver"’
plan(sequential)Created on 2021-02-01 by the reprex package (v0.3.0.9001)
packagesOf() cannot identify where S4 standard generic functions come from. Here is an example of why, and a guess on what you could look for instead?
fn <- vctrs::vec_slice
fn_s4 <- DBI::dbConnect
# this is what `packagesOf.Globals()` does
environmentName(environment(fn))
#> [1] "vctrs"
# doesn't work for S4 functions!
environmentName(environment(fn_s4))
#> [1] ""
# It is a "standardGeneric" function
class(fn_s4)
#> [1] "standardGeneric"
#> attr(,"package")
#> [1] "methods"
# These have a "package" attribute
attr(fn_s4, "package", exact = TRUE)
#> [1] "DBI"
# And a "generic" attribute, which also has a "package" attribute on it
attr(fn_s4, "generic", exact = TRUE)
#> [1] "dbConnect"
#> attr(,"package")
#> [1] "DBI"Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
S4Related to the S4 class system in RRelated to the S4 class system in R