Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@exportS3Method fails when package not imported or already in global namespace #1085

Closed
Tracked by #57
NikNakk opened this issue Apr 28, 2020 · 4 comments · Fixed by #1326
Closed
Tracked by #57

@exportS3Method fails when package not imported or already in global namespace #1085

NikNakk opened this issue Apr 28, 2020 · 4 comments · Fixed by #1326
Labels
bug an unexpected problem or unintended behavior namespace 👩‍🚀
Milestone

Comments

@NikNakk
Copy link

NikNakk commented Apr 28, 2020

With the move to R 4.0.0, I've come across an issue with one of my packages where I wanted to include S3 methods without introducing a dependency on the package that defines the generic. I'd previously done this by @exporting the function without an @importFrom, which meant that an export rather than S3method directive was written to NAMESPACE. However, now that R 4.0.0 doesn't look in the global namespace for S3 methods, this no longer worked.

As per duckmayr's answer to my StackOverflow question, the answer comes from using @exportS3Method package::generic_function without an @importFrom. However, this fails unless the relevant package has already been loaded into the global namespace before a call to roxygen2::roxygenise. Within RStudio, this means that the Document option in the Build pane fails. Is there any chance of modifying the check that leads to the error @exportS3Method and @exportS3Method generic must be used with an S3 method' and therefore fails to include the relevant lines in NAMESPACE?

@hadley
Copy link
Member

hadley commented May 1, 2020

Can you please provide a reprex following the advice in https://github.com/r-lib/roxygen2/blob/master/.github/SUPPORT.md#making-a-reprex?

@hadley hadley added the reprex needs a minimal reproducible example label May 1, 2020
@NikNakk
Copy link
Author

NikNakk commented May 2, 2020

Thanks @hadley. I couldn't make this work using roc_proc_text so I've created a minimal package which is here on GitHub.

There is only a single R file which has the contents:

#' @exportS3Method knitr::knit_print
knit_print.s3example <- function(x, ...) {
}

There are three workarounds. Firstly, if the second (optional) parameter is provided to @exportS3Method, i.e. @exportS3Method knitr::knit_print s3example, then it seems to work ok. Secondly, if the package is in the global namespace and devtools::document() is called from within that R session (rather than through the RStudio build tab), then it works fine. Thirdly, if the package is added to the 'Imports' section of DESCRIPTION and the `@importFrom' directive is used, then it also works (but in the process creates a dependency on the package providing the generic).

It may be that the best option for now is to direct package authors to use the two parameter form of @exportS3Method when they don't want to import the generic package. However, I would have thought it should be possible for roxygen2 to work out the correct S3method directive for NAMESPACE without needing to have the package loaded.

@hadley hadley added bug an unexpected problem or unintended behavior namespace 👩‍🚀 and removed reprex needs a minimal reproducible example labels May 2, 2020
@hadley
Copy link
Member

hadley commented May 2, 2020

(Note to self: when fixing this, also make sure to update namespace vignette with use of exportS3method)

@hadley
Copy link
Member

hadley commented Apr 6, 2022

Minimal reprex:

library(roxygen2)
roc_proc_text(namespace_roclet(), "
  #' @exportS3Method knitr::knit_print
  knit_print.s3example <- function(x, ...) {
  }
")
#> Warning: [<text>:2] @exportS3Method `@exportS3Method` and `@exportS3Method
#> generic` must be used with an S3 method
#> character(0)

Created on 2022-04-06 by the reprex package (v2.0.1)

Need to use the generic in the tag to find the class name from the generic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug an unexpected problem or unintended behavior namespace 👩‍🚀
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants