r-lib / roxygen2

Generate R package documentation from inline R comments
https://roxygen2.r-lib.org
Other
592 stars 233 forks source link

roxygenize error: "Caused by error in `basename()`: a character vector argument expected" #1589

Open andrew-schulman opened 8 months ago

andrew-schulman commented 8 months ago

I've been successfully building my package documentation until now, up through roxygen2 7.2.3. But with version 7.3.0 and later, it fails:

> roxygen2::roxygenize(roclets = c('rd','collate','namespace','vignette'))
ℹ Loading DMRI
Error in `map2()`:
ℹ In index: 1.
ℹ With name: log.debug.
Caused by error in `basename()`:
! a character vector argument expected
Run `rlang::last_trace()` to see where the error occurred.
> rlang::last_trace()
<error/purrr_error_indexed>
Error in `map2()`:
ℹ In index: 1.
ℹ With name: log.debug.
Caused by error in `basename()`:
! a character vector argument expected
---
Backtrace:
     ▆
  1. └─roxygen2::roxygenize(...)
  2.   └─base::lapply(...)
  3.     ├─roxygen2 (local) FUN(X[[i]], ...)
  4.     └─roxygen2:::roclet_process.roclet_namespace(X[[i]], ...)
  5.       └─roxygen2:::warn_missing_s3_exports(blocks, env)
  6.         └─purrr::map2(...)
  7.           └─purrr:::map2_("list", .x, .y, .f, ..., .progress = .progress)
  8.             ├─purrr:::with_indexed_errors(...)
  9.             │ └─base::withCallingHandlers(...)
 10.             ├─purrr:::call_with_cleanup(...)
 11.             └─roxygen2 (local) .f(.x[[i]], .y[[i]], ...)
 12.               └─roxygen2:::warn_roxy_function(fun, "S3 method {.arg {name}} needs @export or @exportS3method tag")
 13.                 └─roxygen2:::warn_roxy(file, line, message, parent = parent, envir = envir)
 14.                   ├─cli::style_hyperlink(...)
 15.                   │ └─base::paste0(...)
 16.                   ├─base::paste0(basename(file), ":", line)
 17.                   └─base::basename(file)
Run rlang::last_trace(drop = FALSE) to see 4 hidden frames.

Apparently one of my S3 methods is missing an @export tag, but since the warning message fails, I can't tell which one. Running again with debug helps to show what the trouble is:

> debug(roxygen2:::warn_roxy_function) 
> roxygen2::roxygenize(roclets = c('rd','collate','namespace','vignette'))
Setting `RoxygenNote` to "7.3.1"
ℹ Loading DMRI
debugging in: warn_roxy_function(fun, "S3 method {.arg {name}} needs @export or @exportS3method tag")
debug: {
    srcref <- attr(fun, "srcref")
    file <- attr(srcref, "srcfile")$filename
    line <- as.vector(srcref)[[1]]
    warn_roxy(file, line, message, parent = parent, envir = envir)
}
Browse[2]> attr(fun, "srcref")
NULL

So warn_roxy_function is trying to create a warning message based on attr(fun, "srcref"), but the attribute value is empty, which causes an error further down the line.

PierreENOlivier commented 7 months ago

Same issue here and I can't tell from the error which S3 method is missing a tag.

venpopov commented 7 months ago

I got the same issue, but no methods were missing tags. Restarting the R session made it go away...

PierreENOlivier commented 7 months ago

I got the same issue, but no methods were missing tags. Restarting the R session made it go away...

I restarted several times and it did not work. And then, did some work, restarted and it magically stopped throwing errors. In the meantime, I tried to install the fortran compiler that seemed to be missing. Maybe that fixed it.

GegznaV commented 6 months ago

The same issue is on GitHub Actions. How to solve it? Use the previous version of Roxygen2 where the issue was not present?

andrew-schulman commented 6 months ago

Yes, you can work around it by reverting to roxygen2 version 7.2.3. Or, you can give up and add @export tags (that you probably don't want) to the functions that are missing them. You can tell which functions those are from the error message. The line that says With name: tells you the name of the function that triggered the error.

venpopov commented 6 months ago

I just figured out when this happens for me. If I have a breakpoint setup inside a method, and I run document(), the above error would appear. Removing the breakpoint removes the error. There may be multiple causes of the same error, but this is what was causing it for me.

Reproducible example:

#' @export
summary.myclass <- function(object) {
  cat("This is a summary of myclass\n")
}

running document() produces no errors. However, if I have a breakpoint setup within the Rstudio gui:

image

and I run document() I get this error:

Error in `map2()`:
ℹ In index: 1.
ℹ With name: summary.myclass.
Caused by error in `basename()`:
! a character vector argument expected
Run `rlang::last_trace()` to see where the error occurred.
Warning message:
In class(f) <- c("s3method", "function") :
  Setting class(x) to multiple strings ("s3method", "function", ...); result will no longer be an S4 object  
MGautierINRA commented 4 months ago

I experienced the same problem when building my package with roxygen2 version 7.3.0 and 7.3.1 (everything works fine with version 7.2.3) in Rstudio (v2024.04.1 Build 748). In my case, roxygen2 stops when analyzing a file containing the definition of an S4 class. Strangely, it seems to be related to the name of the class (i.e. fitted.graph). Here is a minimal example that (hopefully) reproduces the error in other systems:

#' S4 class
#'
fitted.graph<-setClass(Class = "fitted.graph",representation("matrix"))

If I add @export (or @exportClass), the error persists. But if I simply change the name of the class (which I am reluctant to do in my whole package) to e.g. f.graph then the error disappears.

#' S4 class
#'
f.graph<-setClass(Class = "f.graph",representation("matrix"))

Additional trial and error testing suggests that the problem is related to the prefix fitted in the name of my class.

jburos commented 4 months ago

This seems related to this section of the release notes for 7.3.0 of roxygen2:

The NAMESPACE roclet now reports if you have S3 methods that are missing an @export tag. All S3 methods need to be @exported (which confusingly really registers the method) even if the generic is not. This avoids rare, but hard to debug, problems (https://github.com/r-lib/roxygen2/issues/1175). You can suppress the warning with @exportS3Method NULL (https://github.com/r-lib/roxygen2/issues/1550).

andrew-schulman commented 4 months ago

Agree, it's related to that. The problem is that in trying to print the error message, roxygenize is itself throwing an error.

MGautierINRA commented 4 months ago

The problem persists even when using "@exportS3Method NULL" (even in the toy example). The way I solved it was to give the generator function created by the SetClass function a name different from the name of the class: i.e. following the above toy example:

#' S4 class
#'
gen.fitted.graph<-setClass(Class = "fitted.graph",representation("matrix"))

Note that this works even without @export tag.