You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
(Apologies if this is a duplicate: I have searched for issues that combine Rcpp modules with devtools/pkgload but did not find anything from recent years.)
I've noticed some behavior with Rcpp modules and package loading with devtools::load_all where the expected class name does not seem to be visible in the namespace in ways I would expect, i.e. if we export a class in the NAMESPACE then <pkg_name>::<class_name> should exist.
I am able to trigger the issue with the rcpp-modules-student example, but I have also found it when working with the source code of CRAN packages such as RcppHNSW and RcppAnnoy which also use Rcpp modules to expose C++ classes.
To be concrete, in the rcpp-modules-student example, where RcppStudent is the package name and Student is the exported class, I would expect RcppStudent::Student to exist.
When loading the package via devtools::load_all(".") the name of the class doesn't seem to be present in the namespace the first time, load_all is called. Here's a sample output (based on opening an R terminal in a git checkout of rcpp-modules-student), where after the first load_all, RcppStudent::Student does not exist, but after a second load_all, it does:
If I install the package via devtools::install_local, by e.g. opening an R shell in a sibling folder and running devtools::install_local("../rcpp-modules-student") then RcppStudent::Studentis available straight away.
I don't claim to understand how the name lookup works in R, but if I ignore the warning that Student isn't exported and try to create a new instance with new(Student) after load_all that works:
# check there is no Student before loading:> str(new(Student))
Errorin .getClassesFromCache(Class) :object'Student'notfound# load the first time>devtools::load_all(".")
ℹ LoadingRcppStudentWarningmessage:Objectslistedasexports, butnotpresentinnamespace:
• Student# create a Student anyway> str(new(Student))
Referenceclass'Rcpp_Student' [package"RcppStudent"] with0fieldslist()
and21methods, ofwhich7arepossiblyrelevant:finalize, GetAge, GetFavoriteNumbers, GetName, initialize, IsMale, LikesBlue
...but Student is still not in the RcppStudent namespace.
>RcppStudent::StudentError:'Student'isnotanexportedobjectfrom'namespace:RcppStudent'Errorduringwrapup:Expectinganexternalpointer: [type=environment].Error:nomoreerrorhandlers available (recursiveerrors?); invoking'abort'restart
I am not sure if those errors are relevant (I ran this in RStudio). I see this on Windows as well as Linux. I don't know when this started, but I just tried it with R 3.6, 4.0, 4.1 and 4.2 and they all show the same behavior. I am sure I had been happily using devtools::load_all with Rcpp modules on at least R 3.6, but I may not have tried it with R 4.x until recently. So maybe there has been a change in how pkgload and Rcpp interact with more recent versions of those libraries? Also, this doesn't affect C++ functions, only when wrapping classes.
Other things:
new(Student) works but new("Student") does not.
from running str(new(Student)) the output says Reference class 'Rcpp_Student'.
calling new("Rcpp_Student")does work.
but there is no RcppStudent::Rcpp_Student.
and there is nothing in the rcpp-modules-student project that uses the identifier Rcpp_Student.
so is there some confusion occurring between the name of the C++ class Student and the reference class Rcpp_Student?
Here is a sample sessionInfo for when I am using devtools::load_all("."):
Thanks for the detailed write-up. Better interaction with Rcpp module classes is not on the short or medium term road map. If you want to take a stab at improving support in pkgload, I'd be happy to review a PR though!
Thanks for taking a look @lionel. I think it's safe to assume that this isn't a problem that is affecting many people, so I will close this.
FWIW my workaround was to not use roxygen2 and its @export feature to generate the NAMESPACE. Instead, I manually export classes and functions with exportPattern. For my package, the functions I want to export begin with hnsw_ and the classes with Hnsw, so this was fairly straightforward and low-risk:
(Apologies if this is a duplicate: I have searched for issues that combine Rcpp modules with devtools/pkgload but did not find anything from recent years.)
I've noticed some behavior with Rcpp modules and package loading with
devtools::load_all
where the expected class name does not seem to be visible in the namespace in ways I would expect, i.e. if we export a class in theNAMESPACE
then<pkg_name>::<class_name>
should exist.I am able to trigger the issue with the rcpp-modules-student example, but I have also found it when working with the source code of CRAN packages such as RcppHNSW and RcppAnnoy which also use Rcpp modules to expose C++ classes.
To be concrete, in the
rcpp-modules-student
example, whereRcppStudent
is the package name andStudent
is the exported class, I would expectRcppStudent::Student
to exist.When loading the package via
devtools::load_all(".")
the name of the class doesn't seem to be present in the namespace the first time,load_all
is called. Here's a sample output (based on opening an R terminal in a git checkout ofrcpp-modules-student
), where after the firstload_all
,RcppStudent::Student
does not exist, but after a secondload_all
, it does:If I install the package via
devtools::install_local
, by e.g. opening an R shell in a sibling folder and runningdevtools::install_local("../rcpp-modules-student")
thenRcppStudent::Student
is available straight away.I don't claim to understand how the name lookup works in R, but if I ignore the warning that
Student
isn't exported and try to create a new instance withnew(Student)
afterload_all
that works:...but Student is still not in the RcppStudent namespace.
I am not sure if those errors are relevant (I ran this in RStudio). I see this on Windows as well as Linux. I don't know when this started, but I just tried it with R 3.6, 4.0, 4.1 and 4.2 and they all show the same behavior. I am sure I had been happily using
devtools::load_all
with Rcpp modules on at least R 3.6, but I may not have tried it with R 4.x until recently. So maybe there has been a change in howpkgload
andRcpp
interact with more recent versions of those libraries? Also, this doesn't affect C++ functions, only when wrapping classes.Other things:
new(Student)
works butnew("Student")
does not.str(new(Student))
the output saysReference class 'Rcpp_Student'
.new("Rcpp_Student")
does work.RcppStudent::Rcpp_Student
.rcpp-modules-student
project that uses the identifierRcpp_Student
.Student
and the reference classRcpp_Student
?Here is a sample
sessionInfo
for when I am usingdevtools::load_all(".")
:For the sibling folder where
devtools::install_local
works:The text was updated successfully, but these errors were encountered: