-
Notifications
You must be signed in to change notification settings - Fork 738
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
Allow customizing the project environment path with UV_PROJECT_ENVIRONMENT
#6834
Conversation
// Even if there's a `pyproject.toml` | ||
uv_snapshot!(context.filters(), context.venv().env("UV_PROJECT_ENVIRONMENT", "foo"), @r###" | ||
success: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will change in #6835
I tested installation into a system environment with: FROM python:3.11.9-slim-bookworm
# Add my locally built binary
ADD uv /bin/uv
RUN chmod +x /bin/uv
# Create a project
RUN uv init example
WORKDIR example
# Use the system Python environment
ENV UV_PROJECT_ENVIRONMENT="/usr/local/"
# Add httpx to the project
RUN uv add httpx
# Import it using the system Python
RUN python -c "import httpx" |
@edmorley please let me know if this will work for CNBs — I find that use-case particularly compelling. I also plan to validate this approach works well for multi-stage Docker builds. |
To clarify, since my Rust is not quite up there: given that |
Yes |
Hello! Since it is called UV_PROJECT_ENVIRONMENT (emphasis on project), would it be too much of a stretch to have it be also set in pyproject.toml or uv.toml? I understand you are focusing on docker where it is standard to set environment variables, but there are much more wide use cases for this. Thank you for providing this. It is better than the VIRTUAL_ENV variable, but the reason that is an env variable is because of the activation script. Otherwise a config file might be extremely useful |
I'm not sure this makes semantically: if you're cooperating with others on a project, you're dictating on them where to put their venv. If you're working on it yourself, it would be very repetitive and a better solution would be a global config that allows to set some template or something. Env variables aren't just a Docker thing; people use them locally for exactly these kinds customizations using
Yeah I figured, and I'm not arguing for the contrary. I just think it's a potential footgun to keep in mind. |
I think it would make sense to respect |
Unfortunately this is a reality in some projects (think about python has been around for 25 years). This prevents uv add/sync from being the norm by not providing a way to migrating while being compatible. Then it might be finally possible for projects just forget about this need when uv is the norm. Being in a transition stage we need features that might not make sense if you are just trying to be purist about what is right and wrong. |
This solution works for me. Thanks for the responsive turnaround and the docs on the docker dev environment too. |
I think the suggestion here is to use |
This won't change |
No, it won't have any effect on |
I've been thinking more and more about this statement. UV does dictate where the venv is located. As if it prevents a "project maintainer" from deciding it because it was already decided and enforced for all users. Seems contradictory.
Sure, thank you! I'm in favor of any command line option or env variable being configurable in .toml files because it allows me to give users a project ready to use where they just need to learn the minimal commands and not care about extra steps. I used to work only in mac/linux environments, but for the past 2 years I moved to windows and there are way more challenges than in a unix based system to make things simply work |
First off, thank you for putting so much effort into this project, and keeping up with all the requests & issues. Couple of stupid questions:
I guess I can do something like
Would it be easy / How does the dev team feel about having a
What is the reason behind this? Isn't it advantageous to explicitly define which environment a user is using? Otherwise how can I feel safe I'm not modifying my global environment? |
Responding to the above
|
@zanieb Sorry for the delayed reply. This new env var will work well for our use-case (#5229 (comment)) - thank you! We'll likely also set
So this probably something you've already considered/are aware of (and were instead talking mainly about the host-machine development use-case), but in a container context, it will be reasonably common to exclude |
Yeah totally agree — but that use-case doesn't require uv to read and mutate an "active" virtual environment. |
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [astral-sh/uv](https://github.com/astral-sh/uv) | patch | `0.4.0` -> `0.4.4` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>astral-sh/uv (astral-sh/uv)</summary> ### [`v0.4.4`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#044) [Compare Source](astral-sh/uv@0.4.3...0.4.4) ##### Enhancements - Allow customizing the project environment path with `UV_PROJECT_ENVIRONMENT` ([#​6834](astral-sh/uv#6834)) - Warn when `VIRTUAL_ENV` is set but will not be respected in project commands ([#​6864](astral-sh/uv#6864)) - Add `--no-hashes` to `uv export` ([#​6954](astral-sh/uv#6954)) - Make HTTP headers title case for backward compatibility ([#​6887](astral-sh/uv#6887)) - Pin `.python-version` in `uv init` ([#​6869](astral-sh/uv#6869)) - Support `file://` URLs for `UV_PYTHON_INSTALL_MIRROR` ([#​6950](astral-sh/uv#6950)) - Introduce more docker tags for uv ([#​6053](astral-sh/uv#6053)) ##### Bug fixes - Avoid canonicalizing the cache directory ([#​6949](astral-sh/uv#6949)) - Show all PyPy versions in `uv python list --all-versions` ([#​6917](astral-sh/uv#6917)) - Avoid incorrect `requires-python` marker simplifications ([#​6268](astral-sh/uv#6268)) ##### Documentation - Add documentation for `UV_PROJECT_ENVIRONMENT` ([#​6987](astral-sh/uv#6987)) - Add optional dependencies section to the lockfile document ([#​6982](astral-sh/uv#6982)) - Document use of the `file://` scheme in Python installation mirrors ([#​6984](astral-sh/uv#6984)) - Fix outdated references to the help menu documentation in the first steps page ([#​6980](astral-sh/uv#6980)) - Show env option in CLI reference documentation ([#​6863](astral-sh/uv#6863)) - Add bind mount example to `docker.md` ([#​6921](astral-sh/uv#6921)) ### [`v0.4.3`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#043) [Compare Source](astral-sh/uv@0.4.2...0.4.3) ##### Enhancements - Show build backend output when `--verbose` is provided ([#​6903](astral-sh/uv#6903)) - Allow `uv sync --frozen --package` without copying member `pyproject.toml` ([#​6943](astral-sh/uv#6943)) ##### Bug fixes - Avoid panic with missing temporary directory ([#​6929](astral-sh/uv#6929)) - Avoid updating incorrect dependencies for sorted `uv add` ([#​6939](astral-sh/uv#6939)) - Use lower-bound semantics for all Python compatibility comparisons ([#​6882](astral-sh/uv#6882)) ### [`v0.4.2`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#042) [Compare Source](astral-sh/uv@0.4.1...0.4.2) ##### Enhancements - Adding support for `.pyc` files in `uv run` ([#​6886](astral-sh/uv#6886)) - Treat missing `top_level.txt` as non-fatal ([#​6881](astral-sh/uv#6881)) ##### Bug fixes - Fix `is_disjoint` check for supported environments ([#​6902](astral-sh/uv#6902)) - Remove dangling archives in `uv cache clean ${package}` ([#​6915](astral-sh/uv#6915)) - Error when discovered Python is incompatible with `--isolated` workspace ([#​6885](astral-sh/uv#6885)) - Warn when discovered Python is incompatible with PEP 723 script ([#​6884](astral-sh/uv#6884)) ### [`v0.4.1`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#041) [Compare Source](astral-sh/uv@0.4.0...0.4.1) ##### Enhancements - Add `uv export --format requirements-txt` ([#​6778](astral-sh/uv#6778)) - Allow `@` references in `uv tool install --from` ([#​6842](astral-sh/uv#6842)) - Normalize version specifiers by sorting ([#​6333](astral-sh/uv#6333)) - Respect the user's upper-bound in `requires-python` ([#​6824](astral-sh/uv#6824)) - Use Windows registry to discover Python on Windows directly ([#​6761](astral-sh/uv#6761)) - Hint at `--no-workspace` in `uv init` failures ([#​6815](astral-sh/uv#6815)) - Update to last PyPy releases ([#​6784](astral-sh/uv#6784)) ##### Bug fixes - Avoid deadlocks when multiple uv processes lock resources ([#​6790](astral-sh/uv#6790)) - Expand tildes when matching against `PATH` ([#​6829](astral-sh/uv#6829)) - Fix `uv init --no-project` alias ([#​6837](astral-sh/uv#6837)) - Ignore pre-release segments when discovering via `requires-python` ([#​6813](astral-sh/uv#6813)) - Support inline optional tables in `uv add` and `uv remove` ([#​6787](astral-sh/uv#6787)) - Update default `hello.py` to pass `ruff format` ([#​6811](astral-sh/uv#6811)) - Avoid stripping root for user path display ([#​6865](astral-sh/uv#6865)) - Error when user-provided environments are disjoint with Python ([#​6841](astral-sh/uv#6841)) - Retain alphabetical sorting for `pyproject.toml` in `uv add` operations ([#​6388](astral-sh/uv#6388)))) ##### Documentation - Add a link to the multiple index docs in the alternative index guide ([#​6826](astral-sh/uv#6826)) - Add docs for inline exclude newer in PEP 723 scripts ([#​6831](astral-sh/uv#6831)) - Enumerate available Docker tags ([#​6768](astral-sh/uv#6768)) - Omit `[pip]` section from configuration file docs ([#​6814](astral-sh/uv#6814)) - Update `project.urls` in `pyproject.toml` ([#​6844](astral-sh/uv#6844)) - Add docs for AWS CodeArtifact usage ([#​6816](astral-sh/uv#6816)) ##### Other changes </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40NDAuNyIsInVwZGF0ZWRJblZlciI6IjM3LjQ0MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
Allows configuration of the (currently hard-coded) path to the virtual environment in projects using the
UV_PROJECT_ENVIRONMENT
environment variable.If empty, we'll ignore it. If a relative path, it will be resolved relative to the workspace root. If an absolute path, we'll use that.
This feature targets use in Docker images and CI. The variable is intended to be set once in an isolated system and used for all uv operations.
We do not expose a CLI option or configuration file setting — we may pursue those later but I see them as lower priority. I think a system-level environment variable addresses the most pressing use-cases here.
This doesn't special-case the system environment. Which means that you can use this to write to the system Python environment. I would generally strongly recommend against doing so. The insightful comment from @edmorley at #5229 (comment) provides some context on why. More generally,
uv sync
will remove packages from the environment by default. This means that if the system environment contains any packages relevant to the operation of the system (that are not dependencies of your project),uv sync
will break it. I'd only use this in Docker or CI, if anywhere. Virtual environments have lots of benefits, and it's only one line to "activate" them.If you are considering using this feature to use Docker bind mounts for developing in containers, I would highly recommend reading our Docker container development documentation first. If the solutions there do not work for you, please open an issue describing your use-case and why.
We do not read
VIRTUAL_ENV
and do not have plans to at this time. ReadingVIRTUAL_ENV
is high-risk, because users can easily leave an environment active and use the uv project interface today. ReadingVIRTUAL_ENV
would be a breaking change. Additionally, uv is intentionally moving away from the concept of "active environments" and I don't think syncing to an "active" environment is the right behavior while managing projects. I plan to add a warning ifVIRTUAL_ENV
is set, to avoid confusion in this area (see #6864).This does not directly enable centrally managed virtual environments. If you set
UV_PROJECT_ENVIRONMENT
to an absolute path and use it across multiple projects, they will clobber each other's environments. However, you could use this with something likedirenv
to achieve "centrally managed" environments. I intend to build a prototype of this eventually. See #1495 for more details on this use-case.Lots of discussion about this feature in:
uv sync
#5229uv add
/uv sync
/... do not respect the active virtualenv, should they? #6612Follow-ups:
uv venv
#6835VIRTUAL_ENV
is set but will not be respected in project commands #6864Closes #6669
Closes #5229
Closes #6612