Session watcher not respecting reticulate delayed load, and other issues
There seems to be some weirdness happening with reticulate when working with the VSCode-R extension. It looks like VSCode-R is evaluating the reticulate/Python code in a different way than the standard R GUI console. The obvious example when using the delay_load flag when importing modules:
standard R GUI Console
library(reticulate)
start = Sys.time()
re <- import("re", delay_load = TRUE)
end = Sys.time()
end - start
#> Time difference of 0.01495004 secs
re
#> <pointer: 0x0> # the module has not been loaded yet because delay_load = TRUE
start = Sys.time()
re$match # trigger loading of module
#> <function match at 0x000002EA31AE8B80>
end = Sys.time()
end - start
#> Time difference of 12.2005 secs
VSCode-R Console
library(reticulate)
start = Sys.time()
re <- import("re", delay_load = TRUE)
end = Sys.time()
end - start
#> Time difference of 12.08285 secs
re
#> Module(re) # module has been loaded
start = Sys.time()
re$match # trigger loading of module
#> <function match at 0x000001C7AD980AF0>
end = Sys.time()
end - start
#> Time difference of 0.03116894 secs # fast because module was already loaded
I have also been encountering cases where reticulate will throw Python errors in VSCode but not in the R GUI, and will continuously re-throw the error with every new command. However, I do not yet have a reprex for this (it most commonly occurs with the arcpy module, which is not available unless you have an ArcGIS Pro license). I'll post again here if I can reproduce the issue with a publicly-available module.
This seems to be caused by the setting r.session.watchGlobalEnvironment. Setting this to false results in import("re", delay_load = TRUE) working as expected. It also resolved the continuous error throw issue in my last paragraph.
It seems that the session watcher is not working quite right with reticulate connections to Python modules and objects.
The issue is encountered in the VSCode-R session watcher function, and specifically this line triggers the evaluation. This code gets evaluated because is_promise() and is_active() both return FALSE for a delayed-load module (and thus the "else" part of the if-else statement is evaluated).
Perhaps the most straightforward solution is to add a condition in inspect_env()for checking if the object is a python.builtin.module and/or python.builtin.object object, and if so to avoid inspecting it.
Thanks for the detailed writeup @mkoohafkan.
Your solution definitely works, and I'm happy to write a PR soon to remedy this. It would be nice to have non-delayed modules still be evaluated, but I haven't found a way of inspecting that from within R.