Skip to content

uv venv's runtime import patching hooks are unexpected #6426

@edmorley

Description

@edmorley

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 venv to behave more like python -m venv (which doesn't add these hooks) than the virtualenv project, given (a) the venv subcommand name, (b) the virtualenv project to me is more commonly associated with older Python versions (prior to the venv module 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 ensurepip or venv, 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:

  1. Do the issues that these hooks aim to fix still exist? If they really were still a widespread problem, then surely the stdlib's venv feature would include these hooks too?
  2. 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+)
  3. Should uv venv provide an option to opt-out of the hooks?
  4. Should uv venv skip installing these hooks on Python 3.12+, given that setuptools is more likely to not be installed there (due to the upstream ensurepip and venv changes)?
  5. More generally, should uv venv be 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 a python -m venv .venv && uv ... with uv venv && uv ... and for there to be no change in functionality. I haven't used the separate virtualenv project to directly create an environment for years.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    virtualenvRelated to virtual environments

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions