@@ -271,15 +271,39 @@ py_list_packages <- function(envname = NULL,
271271# ' ephemeral, it writes a fully resolved manifest via `pip freeze`.
272272# '
273273# ' - `py_read_requirements()` reads `requirements.txt` and `.python-version`, and
274- # ' applies them with [py_require()]. By default, entries are added (`action =
275- # ' "add"`).
274+ # ' applies them with [py_require()]. By default, entries are added (`action
275+ # ' = "add"`).
276276# '
277- # ' These are primarily an alternative interface to `py_require()`, but can also
278- # ' work with non-ephemeral virtual environments.
277+ # ' These are primarily an alternative interface to `py_require()`, but can
278+ # ' also work with non-ephemeral virtual environments.
279279# '
280280# ' @note
281- # ' You can create a local virtual environment from `requirements.txt` and
282- # ' `.python-version` using [virtualenv_create()]:
281+ # '
282+ # ' To continue using `py_require()` locally while keeping a
283+ # ' `requirements.txt` up-to-date for deployments, you can register
284+ # ' an exit handler in `.Rprofile` like this:
285+ # '
286+ # ' ```r
287+ # ' reg.finalizer(
288+ # ' asNamespace("reticulate"),
289+ # ' function(ns) {
290+ # ' if (
291+ # ' reticulate::py_available() &&
292+ # ' isTRUE(reticulate::py_config()$ephemeral)
293+ # ' ) {
294+ # ' reticulate::py_write_requirements(quiet = TRUE)
295+ # ' }
296+ # ' },
297+ # ' onexit = TRUE
298+ # ' )
299+ # ' ```
300+ # '
301+ # ' This approach is only recommended if you are using `git`.
302+ # '
303+ # ' Alternatively, you can transition away from using ephemeral python
304+ # ' environemnts via `py_require()` to using a persistent local virtual
305+ # ' environment you manage. You can create a local virtual environment from
306+ # ' `requirements.txt` and `.python-version` using [virtualenv_create()]:
283307# '
284308# ' ```r
285309# ' # Note: '.venv' in the current directory is auto-discovered by reticulate.
@@ -291,31 +315,37 @@ py_list_packages <- function(envname = NULL,
291315# ' )
292316# ' ```
293317# '
318+ # ' If you run into issues, be aware that `requirements.txt` and
319+ # ' `.python-version` may not contain all the information necessary to
320+ # ' reproduce the Python environment if the R code sets environment variables
321+ # ' like `UV_INDEX` or `UV_CONSTRAINT`.
322+ # '
294323# ' @name py_requirements_files
295324# '
296325# ' @param packages Path to the package requirements file. Defaults to
297326# ' `"requirements.txt"`. Use `NULL` to skip.
298327# ' @param python_version Path to the Python version file. Defaults to
299328# ' `".python-version"`. Use `NULL` to skip.
300- # ' @param freeze Logical. If `TRUE`, writes a fully resolved list of installed
301- # ' packages using `pip freeze`. If `FALSE`, writes only the requirements
302- # ' tracked by [py_require()].
329+ # ' @param freeze Logical. If `TRUE`, writes a fully resolved list of
330+ # ' installed packages using `pip freeze`. If `FALSE`, writes only the
331+ # ' requirements tracked by [py_require()].
303332# ' @param python Path to the Python executable to use.
304333# ' @param action How to apply requirements read by `py_read_requirements()`:
305334# ' `"add"` (default) adds to existing requirements, `"set"` replaces them,
306- # ' `"remove"` removes matching entries, or `"none"` skips applying them and
307- # ' returns the read values.
335+ # ' `"remove"` removes matching entries, or `"none"` skips applying them
336+ # ' and returns the read values.
308337# ' @param ... Unused; must be empty.
309- # ' @param quiet Logical; if `TRUE`, suppresses the informational messages that
310- # ' print `wrote '<path>'` for each file written.
338+ # ' @param quiet Logical; if `TRUE`, suppresses the informational messages
339+ # ' that print `wrote '<path>'` for each file written.
311340# '
312341# ' @return Invisibly, a list with two named elements:
313342# ' \describe{
314343# ' \item{`packages`}{Character vector of package requirements.}
315344# ' \item{`python_version`}{String specifying the Python version.}
316345# ' }
317346# '
318- # ' To get just the return value without writing any files, you can pass `NULL` for file paths, like this:
347+ # ' To get just the return value without writing any files, you can pass
348+ # ' `NULL` for file paths, like this:
319349# '
320350# ' ```r
321351# ' py_write_requirements(NULL, NULL)
0 commit comments