From 0988d23e590ce788d8754d555f1c7b4c0c50ba03 Mon Sep 17 00:00:00 2001 From: Tomasz Kalinowski Date: Wed, 12 Aug 2026 13:50:32 -0400 Subject: [PATCH 1/2] Default RETICULATE_PYTHON to managed for ir run --- docs/run.qmd | 3 +++ src/quickstart.txt | 2 ++ src/runtime.rs | 2 ++ tests/run.rs | 31 +++++++++++++++++++++++++++++++ tests/snapshots/quickstart.stdout | 2 ++ 5 files changed, 40 insertions(+) diff --git a/docs/run.qmd b/docs/run.qmd index a17fd58..032f338 100644 --- a/docs/run.qmd +++ b/docs/run.qmd @@ -82,6 +82,9 @@ Use `python-packages` or `python-version` to ask `ir run` for a Python environme - It sets `RETICULATE_PYTHON` to the resolved Python executable. Declare `reticulate` under `packages` when the R script loads reticulate. +When Python metadata is absent, `ir run` sets `RETICULATE_PYTHON=managed` if `RETICULATE_PYTHON` is unset. +This lets reticulate create its lazy managed environment from `py_require()` declarations made by R packages. +Set `RETICULATE_PYTHON` explicitly to keep another Python selection. ```r #!/usr/bin/env -S ir run diff --git a/src/quickstart.txt b/src/quickstart.txt index 98ab0a9..4d2f7b9 100644 --- a/src/quickstart.txt +++ b/src/quickstart.txt @@ -39,6 +39,8 @@ Python: `ir preview` also set QUARTO_PYTHON and inject jupyter. Add `reticulate` under `packages` when R code loads reticulate; `ir render` and `ir preview` add it for knitr-backed Quarto documents with Python chunks. + Without Python metadata, `ir run` defaults an unset RETICULATE_PYTHON to + managed; set it explicitly to keep another Python selection. `exclude-newer` also applies to Python unless `python-exclude-newer` is set. Bioconductor: diff --git a/src/runtime.rs b/src/runtime.rs index aa122bb..5dd38ea 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -876,6 +876,8 @@ fn run_script( if let Some(python) = python { cmd.env("RETICULATE_PYTHON", python); activate_python_env(&mut cmd, python)?; + } else if env::var_os("RETICULATE_PYTHON").is_none() { + cmd.env("RETICULATE_PYTHON", "managed"); } if isolated { diff --git a/tests/run.rs b/tests/run.rs index 71ee2b9..1d7b7e6 100644 --- a/tests/run.rs +++ b/tests/run.rs @@ -546,6 +546,37 @@ cat("frontmatter.user_library=", Sys.getenv("R_LIBS_USER", unset = ""), " assert_stdout_contains(&out, "frontmatter.user_library=NULL"); } +#[test] +fn run_without_python_metadata_defaults_reticulate_python_to_managed() { + let script = temp_path("ir-run-reticulate-python-default", "R"); + fs::write( + &script, + r#"cat("reticulate_python=", Sys.getenv("RETICULATE_PYTHON", unset = ""), "\n", sep = "") +"#, + ) + .unwrap(); + + let out = ir() + .env_remove("RETICULATE_PYTHON") + .args(["run", "--vanilla"]) + .arg(&script) + .output() + .unwrap(); + + assert_success(&out); + assert_stdout_contains(&out, "reticulate_python=managed"); + + let out = ir() + .env("RETICULATE_PYTHON", "configured-python") + .args(["run", "--vanilla"]) + .arg(&script) + .output() + .unwrap(); + + assert_success(&out); + assert_stdout_contains(&out, "reticulate_python=configured-python"); +} + #[cfg(unix)] #[test] fn run_script_frontmatter_sets_reticulate_python_and_activates_env() { diff --git a/tests/snapshots/quickstart.stdout b/tests/snapshots/quickstart.stdout index 98ab0a9..4d2f7b9 100644 --- a/tests/snapshots/quickstart.stdout +++ b/tests/snapshots/quickstart.stdout @@ -39,6 +39,8 @@ Python: `ir preview` also set QUARTO_PYTHON and inject jupyter. Add `reticulate` under `packages` when R code loads reticulate; `ir render` and `ir preview` add it for knitr-backed Quarto documents with Python chunks. + Without Python metadata, `ir run` defaults an unset RETICULATE_PYTHON to + managed; set it explicitly to keep another Python selection. `exclude-newer` also applies to Python unless `python-exclude-newer` is set. Bioconductor: From f3d7fa9a72db453202c48d031ad9741b92b0a72e Mon Sep 17 00:00:00 2001 From: Tomasz Kalinowski Date: Wed, 12 Aug 2026 14:22:14 -0400 Subject: [PATCH 2/2] Document managed Python ownership --- docs/run.qmd | 3 ++- src/runtime.rs | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/run.qmd b/docs/run.qmd index 032f338..bf79932 100644 --- a/docs/run.qmd +++ b/docs/run.qmd @@ -84,7 +84,8 @@ Use `python-packages` or `python-version` to ask `ir run` for a Python environme Declare `reticulate` under `packages` when the R script loads reticulate. When Python metadata is absent, `ir run` sets `RETICULATE_PYTHON=managed` if `RETICULATE_PYTHON` is unset. This lets reticulate create its lazy managed environment from `py_require()` declarations made by R packages. -Set `RETICULATE_PYTHON` explicitly to keep another Python selection. +This portable default intentionally takes precedence over reticulate's other Python selectors. +To opt out, set `RETICULATE_PYTHON` to a concrete interpreter before launch, or unset it in the script before configuring reticulate. ```r #!/usr/bin/env -S ir run diff --git a/src/runtime.rs b/src/runtime.rs index 5dd38ea..6c1f651 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -877,6 +877,11 @@ fn run_script( cmd.env("RETICULATE_PYTHON", python); activate_python_env(&mut cmd, python)?; } else if env::var_os("RETICULATE_PYTHON").is_none() { + // `ir run` owns Python selection by default so package-level + // `py_require()` declarations produce portable scripts. This + // intentionally outranks reticulate's other selectors and requires a + // reticulate release that supports `managed`; do not add runtime probes + // for older releases or externally managed environments here. cmd.env("RETICULATE_PYTHON", "managed"); }