Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uv_get_or_create_env() is not robust against empty resolve_python_version() #1751

Closed
bastistician opened this issue Feb 27, 2025 · 2 comments · Fixed by #1752
Closed

uv_get_or_create_env() is not robust against empty resolve_python_version() #1751

bastistician opened this issue Feb 27, 2025 · 2 comments · Fixed by #1752

Comments

@bastistician
Copy link

The title conveys a very specific issue but there may be a larger problem behind.

With the newly released reticulate 1.41.0, py_config() now gives a confusing error:

error: a value is required for '--python <PYTHON>' but none was supplied

For more information, try '--help'.
uv error code: 2
-- Current requirements -------------------------------------------------
 Python:    (reticulate default)
 Packages: numpy
-------------------------------------------------------------------------
Hint: If you are temporarily offline, try setting `Sys.setenv(UV_OFFLINE=1)`.
Error in uv_get_or_create_env() : 
  Call `py_require()` to remove or replace conflicting requirements.
Error: Installation of Python not found, Python bindings not loaded.
See the Python "Order of Discovery" here: https://rstudio.github.io/reticulate/articles/versions.html#order-of-discovery.

The previous reticulate 1.40.0 shows the following py_config():

Would you like to create a default Python environment for the reticulate package? (Yes/no/cancel) n
python:         /usr/bin/python3
libpython:      /usr/lib/libpython3.12.so.1.0
pythonhome:     //usr://usr
version:        3.12.9 (main, Feb  7 2025, 17:39:29) [GCC 14.2.0]
numpy:           [NOT FOUND]

python versions found: 
 /usr/bin/python3
 /usr/bin/python

Debugging reticulate::py_available(initialize = TRUE) shows that when uv_get_or_create_env() calls resolve_python_version(NULL, uv), where uv = "~/.cache/R/reticulate/uv/bin/uv", it gets back NULL, so the later uv system call contains an unset --python argument.

Indeed, on my Alpine Linux 3.21 system:

~/.cache/R/reticulate/uv/bin/uv python list
cpython-3.12.9-linux-x86_64-musl    /usr/bin/python3.12
cpython-3.12.9-linux-x86_64-musl    /usr/bin/python3 -> python3.12
cpython-3.12.9-linux-x86_64-musl    /usr/bin/python -> python3

but

~/.cache/R/reticulate/uv/bin/uv python list --python-preference only-managed  # as used by reticulate:::uv_python_list()

outputs nothing.

You can reproduce the problem using the rhub/r-minimal image via docker run --rm -it rhub/r-minimal /bin/bash, running:

installr -d -t gfortran reticulate
R -s -e 'reticulate::py_config()'

Is there a setting I could use to let reticulate again find the python installation?

@t-kalinowski
Copy link
Member

Thank you very much for the excellent bug report. I am able to reproduce the error.

The issue is that uv cannot install musl builds of python.
astral-sh/uv#6890 (comment)

A workaround until this is fixed is to point reticulate at a specific python installation using the RETICULATE_PYTHON environment variable.

@t-kalinowski
Copy link
Member

t-kalinowski commented Feb 28, 2025

Thanks again for the great bug report, being able to reproduce with docker was very helpful.

This should be fixed with #1752

On platforms where uv cannot download pre-built binaries of Python, reticulate will now fallback to resolving a system python for creating ephemeral virtualenvs.

Users can now also force uv to always use a system python when creating ephemeral venvs by setting env var UV_PYTHON_PREFERENCE=only-system

This now succeeds:

docker run --rm -it rhub/r-minimal /bin/bash -c \
  "installr -d -t gfortran 'rstudio/reticulate#1752' && \
   R -q -e 'try(reticulate::py_config())'"

Note that a very narrow set of Python version constraints are satisfiable if only the system Python is usable. E.g., if user or package code calls py_require(python_version = "3.13"), then reticulate will not be able to resolve an ephemeral venv with declared package requirements in that minimal Alpine Linux image where only the system Python with version 3.11 is available. In that case reticulate will still throw an error, and you'll want to point reticulate at a preferred self-managed Python installation using one of the methods listed earlier in the order of discovery.

We'll be submitting a new reticulate to CRAN later today next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants