-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Hi
When a virtual environment is created using uv venv, it adds run-time import hooks in the created site-packages, which patch distutils.dist and/or setuptools.dist:
$ uv --version
uv 0.3.1 (Homebrew 2024-08-21)
$ uv venv
Using Python 3.12.5 interpreter at: /opt/homebrew/opt/[email protected]/bin/python3.12
Creating virtualenv at: .venv
Activate with: source .venv/bin/activate
$ ls -1 .venv/lib/python3.12/site-packages/
_virtualenv.pth
_virtualenv.py
See:
https://github.com/astral-sh/uv/blob/0.3.1/crates/uv-virtualenv/src/virtualenv.rs#L401-L403
https://github.com/astral-sh/uv/blob/0.3.1/crates/uv-virtualenv/src/_virtualenv.py
It turns out these hooks are copied from the virtualenv project:
https://github.com/pypa/virtualenv/blob/20.26.3/src/virtualenv/create/via_global_ref/_virtualenv.py
This was surprising to me, since:
- I had expected
uv venvto behave more likepython -m venv(which doesn't add these hooks) than thevirtualenvproject, given (a) thevenvsubcommand name, (b) thevirtualenvproject to me is more commonly associated with older Python versions (prior to thevenvmodule existing) or niche use-cases for seeding or API usage. - There's no mention of these hooks on https://docs.astral.sh/uv/reference/cli/#uv-venv or https://docs.astral.sh/uv/pip/environments/#creating-a-virtual-environment
- Native support for virtual environments has existed since Python 3.3 (see PEP 405), so at first glance it seems unlikely that any issues wouldn't have already been fixed upstream by now, making these patches redundant? Sadly there's no link to an upstream distutils issues in _virtualenv.py with history or steps to reproduce.
- Distuils has been removed in Python 3.12, and whilst a copy of it lives on in setuptools:
- this isn't really mentioned in code comments in _virtualenv.py, requiring people to have that knowledge,
- for Python 3.12 setuptools is no longer installed by default by
ensurepiporvenv, and so it feels odd to be installing pre-emptive hooks for it.
- I generally have a negative association with packages that inject custom import hooks into site-packages, having seen performance and compatibility issues with them over the years (eg some of setuptools' hooks).
Some thoughts:
- Do the issues that these hooks aim to fix still exist? If they really were still a widespread problem, then surely the stdlib's
venvfeature would include these hooks too? - Could the fixes be upstreamed to distutils instead? (If only for setuptool's copy of distutils, where it would be easier to have changes be accepted, and would at least mean the hooks could be dropped for Python 3.12+)
- Should
uv venvprovide an option to opt-out of the hooks? - Should
uv venvskip installing these hooks on Python 3.12+, given that setuptools is more likely to not be installed there (due to the upstreamensurepipandvenvchanges)? - More generally, should
uv venvbe looking to align itself with the behaviour of the stdlib's venv module, or the virtualenv project? Which would be least surprising for end-users? (Personally, I would expect to be able to substitute apython -m venv .venv && uv ...withuv venv && uv ...and for there to be no change in functionality. I haven't used the separatevirtualenvproject to directly create an environment for years.)