Skip to content

Commit

Permalink
Merge pull request #1718 from rstudio/py_require-improvements
Browse files Browse the repository at this point in the history
Updates to `py_require()`
  • Loading branch information
t-kalinowski authored Jan 27, 2025
2 parents 37c5af7 + f4a5779 commit 4a50238
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 219 deletions.
8 changes: 4 additions & 4 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

- Fixed an issue with using Python 3.12 on Linux (#1712, #1714).

- Fixed an issue where `virtualenv_starter()` would not discover a
- Fixed an issue where `virtualenv_starter()` would not discover a
custom built Python (#1704).

# reticulate 1.40.0
Expand All @@ -26,7 +26,7 @@
- Fixed error when attempting to use a python venv created with `uv` (#1678)

- Resolved an issue where `py_discover_config()` attempted to detect
Windows App Store Python installations. These are now excluded from
Windows App Store Python installations. These are now excluded from
discovery by both `py_discover_config()` and `virtualenv_starter()` (#1656, #1673).

- Fixed an error when converting an empty NumPy char array to R (#1662).
Expand All @@ -35,10 +35,10 @@

- Fixed a segfault encountered when running the Python session finalizer (#1663, #1664).

- Resolved a segfault in RStudio when rapidly switching between
- Resolved a segfault in RStudio when rapidly switching between
R and Python chunks in a Quarto document (#1665).

- Improved behavior when the conda binary used to create an environment
- Improved behavior when the conda binary used to create an environment
cannot be resolved (contributed by @tl-hbk, #1654, #1659).

- Added Positron support for the Variables Pane and `repl_python()`
Expand Down
61 changes: 27 additions & 34 deletions R/config.R
Original file line number Diff line number Diff line change
Expand Up @@ -301,45 +301,38 @@ py_discover_config <- function(required_module = NULL, use_environment = NULL) {
forced = "RETICULATE_PYTHON_FALLBACK")))
}

# Look for a "r-reticulate" venv or condaenv. if found, use that.
python <- tryCatch(py_resolve("r-reticulate", type = "virtualenv"), error = identity)
if (!inherits(python, "error"))
try(return(python_config(python, required_module)))

## At this point, the user, (and package authors on behalf of the user), has
## expressed no preference for any particular python installation, or the
## preference expressed is for a python environment that don't exist.
## preference expressed is for a python environment that does not exist.
##
## In other words,
## - no use_python(), use_virtualenv(), use_condaenv()
## - no use_python(), use_virtualenv(), use_condaenv() calls
## - no RETICULATE_PYTHON, RETICULATE_PYTHON_ENV, or RETICULATE_PYTHON_FALLBACK env vars
## - no existing venv in the current working directory named: venv .venv virtualenv or .virtualenv
## - no env named 'r-bar' if there was a call like `import('foo', delay_load = list(environment = "r-bar"))`
## - no env named 'r-foo' if there was a call like `import('foo')`
## - we're not running under an already activated venv (i.e., no VIRTUAL_ENV env var)
## - no configured poetry or pipfile or venv in the current working directory

# Look for a "r-reticulate" venv or condaenv. if found, use that.
# If not found, try to get permission to create one.
# This is the default in the absence of any expressed preference by the user.
python <- tryCatch(py_resolve("r-reticulate"), error = function(e) {
envpath <- try_create_default_virtualenv(package = "reticulate")
if (!is.null(envpath))
virtualenv_python(envpath)
else
e
})

uv_python <- uv_get_or_create_env()
if(!is.null(uv_python)) {
return(
python_config(uv_python)
)
## - no env named 'r-reticulate'

## Default to using a reticulate-managed ephemeral venv that satisfies
## the Python requirements declared via `py_require()`.
user_opted_out <- tolower(Sys.getenv("RETICULATE_USE_MANAGED_VENV")) %in% c("false", "0", "no")
if (!user_opted_out) {
if (isTRUE(getOption("reticulate.python.initializing"))) {
python <- try(uv_get_or_create_env())
if (!is.null(python) && !inherits(python, "try-error"))
try(return(python_config(python, required_module, forced = "py_require()")))
}
# most likely called from py_exe()
return(NULL)
}

if (!inherits(python, "error"))
try(return(python_config(python, required_module)))


# At this point, user has expressed no preference, and we do not have user permission
# to create the "r-reticulate" venv

# fall back to using the PATH python, or fail.
# We intentionally do not go on a fishing expedition for every possible python,
# for two reasons:
Expand Down Expand Up @@ -493,14 +486,14 @@ try_create_default_virtualenv <- function(package = "reticulate", ...) {

if (permission == "") {
return(NULL)
# if (is_interactive()) {
# permission <- utils::askYesNo(sprintf(
# "Would you like to create a default Python environment for the %s package?",
# package))
# if (!isTRUE(permission))
# return(NULL)
# permission <- "true"
# }
if (is_interactive()) {
permission <- utils::askYesNo(sprintf(
"Would you like to create a default Python environment for the %s package?",
package))
if (!isTRUE(permission))
return(NULL)
permission <- "true"
}
}

if (!permission %in% c("true", "yes", "1"))
Expand Down
2 changes: 1 addition & 1 deletion R/install.R
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ py_install <- function(packages,
check_forbidden_install("Python packages")

if (is_python_initialized() &&
is_uv_reticulate_managed_env(py_exe()) &&
is_ephemeral_reticulate_uv_env(py_exe()) &&
is.null(envname)) {
if (!is.null(python_version)) {
stop(
Expand Down
Loading

0 comments on commit 4a50238

Please sign in to comment.