Hi,
Perhaps it is not wise but currently as a quick fix I use reticulate::source_python to load a Python function in .onLoad part. My problem is that function is not callable when the package is loaded...unless I define the environment (using envir parameter of source_python) as globalenv().
Is it possible to have the function in the package namespace?
I am very new to this package by the way. Though I needed a Python function and needed a quick fix.
I would recommend bundling your Python files within the inst/python folder of your package, and explicitly importing + using them as necessary. For example:
path <- system.file("python", package = "<pkg>")
module <- reticulate::import_from_path(<module>, path = path)
You could also add your package path to the Python module path, so it's looked up automagically:
library(reticulate)
path <- system.file("python", package = "<pkg>")
sys <- import("sys", convert = FALSE)
sys$path$append(path)
import("<module>")
That modification of the Python path could occur within your .onLoad() as well.
I was actually calling a custom defined function in a very lame way (by calling the whole python script). But, it will probably be the only python function and that's ok. I think a MWE is due.
I keep my py files in inst/py folder of my package. Let's call it my_fun.py.
import sys
def my_function():
print("Hello dear.")
And then,
.onLoad <- function(libname, pkgname) {
reticulate::source_python(system.file("py/my_fun.py",package="<mypackage>"),envir=globalenv())
}
Now, if the envir parameter stays as the default value parent.frame(), I cannot reach my_function. But if I set it to globalenv(), I can reach it.
My pedantery is to keep it in the package namespace. Though, my knowledge about the internals of R is limited at this scope.
Correct me if I'm wrong, but the functions you refer to import Python modules not custom functions. If source_python doesn't work. I am very new to reticulate and not a very amazing Python developer.
I'm in the same seat. The solution @berkorbay suggests above works, but it doesn't seem like it's the cleanest solution for those namespace reasons.
@berkorbay Try importing your script as a module with reticulate::import_from_path using the .onLoad method:
In ./R/zzz.R:
my_fun <- NULL
.onLoad <- function(libname, pkgname) {
the_module <- reticulate::import_from_path(module = "my_fun", path = system.file("py", package = packageName()))
my_fun <<- the_module$my_fun
}
Then export your function in your package NAMESPACE with export(my_fun)
Original Post here: https://community.rstudio.com/t/build-package-namespace-dynamically-during-onload/4101
Most helpful comment
@berkorbay Try importing your script as a module with
reticulate::import_from_pathusing the.onLoadmethod:In
./R/zzz.R:Then export your function in your package
NAMESPACEwithexport(my_fun)Original Post here: https://community.rstudio.com/t/build-package-namespace-dynamically-during-onload/4101