Skip to content

in a workspace local package A cannot depend on local package B as a build-system requirement #7147

@mmerickel

Description

@mmerickel

This is the same issue as on astral-sh/rye#813 but I'm reproducing it here using uv's new workspace features to replace rye with uv.

Repro Structure

pyproject.toml

[project]
name = "my-workspace"
version = "0.0.0"
dependencies = [
    "my-app",
]

[tool.uv]
package = false

[tool.uv.sources]
my-app = { workspace = true }
my-setuptools-extension = { workspace = true }

[tool.uv.workspace]
members = [
    "src/my-setuptools-extension",
    "src/my-app",
]

src/my-setuptools-extension/pyproject.toml

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

[project]
name = "my-setuptools-extension"
version = "0.0.0"

dependencies = [
    "setuptools",
]

[project.entry-points."distutils.commands"]
build_webassets = "my_setuptools_ext:BuildWebAssetsCommand"

[tool.setuptools]
py-modules = ["my_setuptools_ext"]

src/my-setuptools-extension/my_setuptools_ext.py

from setuptools import Command


class BuildWebAssetsCommand(Command):
    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        print('running!!!')

src/my-app/pyproject.toml

[build-system]
requires = [
    "setuptools",
    "wheel",
    "my-setuptools-extension",
]
build-backend = "setuptools.build_meta"

[project]
name = "my-app"
version = "0.0.0"

src/my-app/setup.py

This step is optional but here for completeness to prove you can use the extension.

import setuptools  # noqa: F401 isort:skip must import before distutils
from distutils.command.build import build as _BuildCommand
from setuptools import setup
from setuptools.command.develop import develop as _DevelopCommand
from setuptools.command.sdist import sdist as _SDistCommand


class SDistCommand(_SDistCommand):
    sub_commands = [('build_webassets', None)] + _SDistCommand.sub_commands


class BuildCommand(_BuildCommand):
    sub_commands = [('build_webassets', None)] + _DevelopCommand.sub_commands


class DevelopCommand(_DevelopCommand):
    def run(self):
        self.run_command('build_webassets')
        _DevelopCommand.run(self)


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

Expected Result

No errors, build the packages and allow my-app to be installed.

Actual Result

❯ uv sync
warning: No `requires-python` value found in the workspace. Defaulting to `>=3.9`.
warning: Missing version constraint (e.g., a lower bound) for `setuptools`
Resolved 4 packages in 2ms
error: Failed to prepare distributions
  Caused by: Failed to fetch wheel: my-app @ file:///Users/michael.merickel/scratch/uv-test/src/my-app
  Caused by: Failed to install requirements from `build-system.requires` (resolve)
  Caused by: No solution found when resolving: setuptools, wheel, my-setuptools-extension
  Caused by: Because my-setuptools-extension was not found in the package registry and you require my-setuptools-extension, we can conclude that your requirements are unsatisfiable.

uv is failing to find my-setuptools-extension which is defined in the workspace. This is only an issue when it's a build requirement.

Version Info

uv 0.4.6 (Homebrew 2024-09-05)
macos 14.6.1 (m1 max)

Additional Info

In our current repo, we do this by running a specific build step on build-requirement packages into a wheelhouse and then install all of the other packages with a find-links to the wheelhouse.

$ env/bin/pip wheel -w wheels src/my-setuptools-extension
$ env/bin/pip install --find-links wheels -e src/my-app

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions