Skip to content

re-running "uv pip install -e ..." does not re-invoke the build system on the package #2844

@mmerickel

Description

@mmerickel

uv version: 0.1.29
platform: macos 14.4.1 (m1 max)

Setup a simple project using the below pyproject.toml and setup.py files. With those created, observe some differences between .venv/bin/pip install -e . and uv pip install -e . in how setup.py is invoked:

example using pip as expected baseline

$ python3 -m venv .venv
$ .venv/bin/pip install -e .
$ cat /tmp/foo
setup.py 1712355322.544586 ['/Users/michael.merickel/scratch/uv-test/.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py', 'egg_info']
setup.py 1712355323.1131861 ['/Users/michael.merickel/scratch/uv-test/.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py', 'dist_info', '--output-dir', '/private/var/folders/0b/gyxh16fx56d7hd_nqbxj1mxc0000gp/T/pip-modern-metadata-g5m4gr57', '--keep-egg-info']
setup.py 1712355323.9759429 ['/Users/michael.merickel/scratch/uv-test/.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py', 'editable_wheel', '--dist-dir', '/private/var/folders/0b/gyxh16fx56d7hd_nqbxj1mxc0000gp/T/pip-wheel-3imq0g2d/.tmp-b981_kcm']
editable_wheel 1712355324.003723
$ .venv/bin/pip install -e .
$ cat /tmp/foo
setup.py 1712355322.544586 ['/Users/michael.merickel/scratch/uv-test/.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py', 'egg_info']
setup.py 1712355323.1131861 ['/Users/michael.merickel/scratch/uv-test/.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py', 'dist_info', '--output-dir', '/private/var/folders/0b/gyxh16fx56d7hd_nqbxj1mxc0000gp/T/pip-modern-metadata-g5m4gr57', '--keep-egg-info']
setup.py 1712355323.9759429 ['/Users/michael.merickel/scratch/uv-test/.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py', 'editable_wheel', '--dist-dir', '/private/var/folders/0b/gyxh16fx56d7hd_nqbxj1mxc0000gp/T/pip-wheel-3imq0g2d/.tmp-b981_kcm']
editable_wheel 1712355324.003723
setup.py 1712355340.953567 ['/Users/michael.merickel/scratch/uv-test/.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py', 'egg_info']
setup.py 1712355341.528934 ['/Users/michael.merickel/scratch/uv-test/.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py', 'dist_info', '--output-dir', '/private/var/folders/0b/gyxh16fx56d7hd_nqbxj1mxc0000gp/T/pip-modern-metadata-ipk6za2b', '--keep-egg-info']
setup.py 1712355341.7226088 ['/Users/michael.merickel/scratch/uv-test/.venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py', 'editable_wheel', '--dist-dir', '/private/var/folders/0b/gyxh16fx56d7hd_nqbxj1mxc0000gp/T/pip-wheel-_y_0b5q7/.tmp-2qq74dsf']
editable_wheel 1712355341.753067

example using uv as problematic

$ rm -rf myapp.egg-info /tmp/foo .venv
$ uv venv
$ uv pip install -e .
$ cat /tmp/foo
setup.py 1712355432.5460742 ['-c', 'egg_info']
setup.py 1712355432.703499 ['-c', 'editable_wheel', '--dist-dir', '/Users/michael.merickel/Library/Caches/uv/.tmp8VJ4yj/.tmpdHFyuf/.tmp-b485ccgd']
editable_wheel 1712355432.751647
$ uv pip install -e .
$ cat /tmp/foo
setup.py 1712355432.5460742 ['-c', 'egg_info']
setup.py 1712355432.703499 ['-c', 'editable_wheel', '--dist-dir', '/Users/michael.merickel/Library/Caches/uv/.tmp8VJ4yj/.tmpdHFyuf/.tmp-b485ccgd']
editable_wheel 1712355432.751647

Discussion

uv pip install is not invoking editable_wheel (or any other commands) if it determines that the package is already installed. It only re-invokes things if I change setup.py or pyproject.toml, but not other files in the project. I have also tested adding a MANIFEST.in and related files, and when I change any of those files the edit is not run.

Why is this a problem?

The issue is we are hooking the commands below to invoke other builds (yarn build to generate webassets for our projects), and if uv does not invoke the install, we have to go into each project and do this, circumventing setuptools as our build system.

uv appears to be too aggressive in caching here, it should re-invoke editable_wheel on any editable install every time it is passed to uv pip install -e ....

Other notes

I tried using uv pip install --refresh -e . and it has no effect on the result.

Repro example files

pyproject.toml

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "myapp"
version = "0.0.0"
classifiers = [
    "Private :: Do Not Upload",
]

setup.py

from setuptools import setup
from setuptools.command.build import build as _BuildCommand
from setuptools.command.develop import develop as _DevelopCommand
from setuptools.command.sdist import sdist as _SDistCommand
from setuptools.command.editable_wheel import editable_wheel as _EditableWheelCommand
import sys
import time


with open('/tmp/foo', 'a+') as fp:
    fp.write(f'setup.py {time.time()} {sys.argv}\n')

class SDistCommand(_SDistCommand):
    def run(self):
        super().run()
        with open('/tmp/foo', 'a+') as fp:
            fp.write(f'sdist {time.time()}\n')


class BuildCommand(_BuildCommand):
    def run(self):
        super().run()
        with open('/tmp/foo', 'a+') as fp:
            fp.write(f'build {time.time()}\n')


class DevelopCommand(_DevelopCommand):
    def run(self):
        super().run()
        with open('/tmp/foo', 'a+') as fp:
            fp.write(f'develop {time.time()}\n')


class EditableWheelCommand(_EditableWheelCommand):
    def run(self):
        super().run()
        with open('/tmp/foo', 'a+') as fp:
            fp.write(f'editable_wheel {time.time()}\n')


setup(
    cmdclass={
        'sdist': SDistCommand,
        'develop': DevelopCommand,
        'build': BuildCommand,
        'editable_wheel': EditableWheelCommand,
    }
)

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-decisionUndecided if this should be done

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions