test_that("Error requesting conflicting package versions", { local_edition(3) # dry run before snapshot tests, so download progress updates aren't # in the snapshot try(uv_get_or_create_env()) expect_snapshot(r_session(attach_namespace = TRUE, { py_require("numpy<2") py_require("numpy>=2") uv_get_or_create_env() })) }) test_that("Setting py_require(python_version) after initializing Python ", { test_py_require_reset() local_edition(3) # dry run to avoid installation messages in snapshot try(uv_get_or_create_env(c("numpy", "pandas"), "3.11")) try(uv_get_or_create_env(c("numpy", "pandas", "requests"), "3.11")) expect_snapshot(r_session({ Sys.unsetenv("RETICULATE_PYTHON") Sys.setenv("RETICULATE_USE_MANAGED_VENV" = "yes") # Sys.setenv("RETICULATE_PYTHON"="managed") pkg_py_require <- function(...) reticulate::py_require(...) pkg_py_require <- rlang::zap_srcref(pkg_py_require) environment(pkg_py_require) <- asNamespace("stats") library(reticulate) # multiple requests are fine py_require(python_version = ">=3.9", "pandas") py_require(python_version = ">=3.8,<3.14") py_require(python_version = "3.11") pkg_py_require(packages = c("pandas", "numpy"), python_version = ">=3.10") # initialize python, ensure packages are there prefix <- import("sys")$prefix import("numpy") import("pandas") stopifnot(py_version() == "3.11") # already satisfied requests are no-ops py_require(python_version = ">=3.9.1") py_require(python_version = ">=3.8.1,<3.14") py_require(python_version = "3.11") pkg_py_require(python_version = ">=3.10") py_require("numpy") py_require("pandas") py_require(c("numpy", "pandas"), action = "set") py_require(c("notexist"), action = "remove") try(import("requests")) # additional packages requests result in a new venv being activated py_require("requests") import("requests") prefix2 <- import("sys")$prefix stopifnot(prefix != prefix2) # unsatisfied requests from a package generate a warning # (it might make sense to narrow this to target just .onLoad() calls) pkg_py_require(python_version = ">=3.12") pkg_py_require("pandas", action = "remove") # unsatisfied requests called from outisde a package error try(py_require(exclude_newer = "2020-01-01")) try(py_require(python_version = ">=3.12")) try(py_require("pandas", action = "remove")) })) }) test_that("Error requesting newer package version against an older snapshot", { session <- r_session(attach_namespace = TRUE, { uv_get_or_create_env( packages = "tensorflow==2.18.*", exclude_newer = "2024-10-20" ) }) expect_match(session, "Call `py_require()` to remove or replace conflicting requirements", fixed = TRUE, all = FALSE ) expect_true(attr(session, "status", TRUE) != 0L) }) test_that("Error requesting a package that does not exists", { local_edition(3) expect_snapshot(r_session(attach_namespace = TRUE, { py_require(c("pandas", "numpy", "notexists")) uv_get_or_create_env() })) }) test_that("Error requesting conflicting Python versions", { local_edition(3) expect_snapshot(r_session(attach_namespace = TRUE, { py_require(python_version = ">=3.10") py_require(python_version = "<3.10") uv_get_or_create_env() })) }) test_that("Simple tests", { local_edition(3) expect_snapshot(r_session(attach_namespace = TRUE, { py_require("pandas") py_require("numpy==2") py_require() })) expect_snapshot(r_session(attach_namespace = TRUE, { py_require("pandas") py_require("numpy==2") py_require("numpy==2", action = "remove") py_require() })) expect_snapshot(r_session(attach_namespace = TRUE, { py_require("pandas") py_require("numpy==2") py_require("numpy==2", action = "remove") py_require(exclude_newer = "1990-01-01") py_require() })) expect_snapshot(r_session(attach_namespace = TRUE, { py_require("pandas") py_require("numpy==2") py_require("numpy==2", action = "remove") py_require(exclude_newer = "1990-01-01") py_require(python_version = c("<=3.11", ">=3.10")) py_require() })) }) test_that("can bootstrap install uv in reticulate cache", { # This test needs rethinking. It assumes that uv is not already installed on the users system, # and fails if it is. if (Sys.which("uv") != "" || file.exists("~/.local/bin/uv")) skip("uv installed by user") local_edition(3) test_py_require_reset() uv_exec <- ifelse(is_windows(), "uv.exe", "uv") target_path <- reticulate_cache_dir("uv", "bin", uv_exec) expect_equal( normalizePath(target_path), normalizePath(uv_binary()) ) }) test_that("Multiple py_require() calls from package are shows in one row", { local_edition(3) expect_snapshot(r_session(attach_namespace = TRUE, { gr_package <- function() { py_require(paste0("package", 1:20)) py_require(paste0("package", 1:10), action = "remove") py_require(python_version = c("<=3.11", ">=3.10")) } environment(gr_package) <- asNamespace("graphics") gr_package() py_require() })) })