Skip to content
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

Support pip wheel subcommand #1681

Open
kvelicka opened this issue Feb 19, 2024 · 19 comments
Open

Support pip wheel subcommand #1681

kvelicka opened this issue Feb 19, 2024 · 19 comments
Labels
compatibility Compatibility with a specification or another tool enhancement New feature or request

Comments

@kvelicka
Copy link

I've been trying uv on work projects to assess its coverage and suitability of being a full pip/pip-tools replacement for us. One of the features of pip that we use is pip wheel, which seems to not be supported by uv currently and I couln't find an open ticket discussing it, so I'm making one here.

@zanieb
Copy link
Member

zanieb commented Feb 19, 2024

We have all the plumbing to do this, I'm not sure where it fits on our roadmap though.

I'm curious how this would relate to

@henryiii
Copy link
Contributor

henryiii commented Feb 19, 2024

Pip would prefer to remove the wheel subcommand AFIAK, and has refused adding a matching sdist command. I think uv build --wheel (along with uv build --sdist and uv build, which builds both) would be better than adding uv pip wheel.

pip wheel does one thing differently, by the way - it includes any wheels it also builds (but not just downloads), while build --wheel only gives you the wheel you asked for. But most of the time that's actually a bug (trying to upload wheels you don't own), and pip download is there if you want to actually get existing files from PyPI (not in uv yet though).

@zanieb
Copy link
Member

zanieb commented Feb 19, 2024

Thanks for the additional context. I wonder what we can provide for people who want to generate wheels for all their dependencies though. It makes sense for pre-building and sharing when they aren't distributed by the original package.

@zanieb zanieb added enhancement New feature or request compatibility Compatibility with a specification or another tool labels Feb 19, 2024
@sbidoul
Copy link

sbidoul commented Feb 21, 2024

I wonder what we can provide for people who want to generate wheels for all their dependencies though. It makes sense for pre-building and sharing when they aren't distributed by the original package.

I echo this. pip wheel is useful to download and build all parts of an app for deployment. For instance in a multi-stage Dockerfile it is common to have a fat build stage with all build tools to create the wheels, then a slim stage which only installs the wheels built in the previous stage.

@henryiii
Copy link
Contributor

But it doesn’t actually put wheels in the wheelhouse if there’s already a built wheel, IIRC? Pip download will get everything you need then you can loop over any SDists and build them if you need them?

@sbidoul
Copy link

sbidoul commented Feb 21, 2024

But it doesn’t actually put wheels in the wheelhouse if there’s already a built wheel, IIRC?

@henryiii I'm not entirely sure what you mean with that?

Pip download will get everything you need then you can loop over any SDists and build them if you need them?

Sure. pip wheel is convenient because it does exactly that for you.

Actually pip wheel is quite easy to implement and maintain because, it basically does everything pip install does except it stores the wheels (whether they are downloaded or built locally) into a directory instead of unpacking them in site-packages. I'd argue it is simpler than pip download, from my experience with that part of the pip code base.

@sbidoul
Copy link

sbidoul commented Feb 21, 2024

That said, build, wheel and download are all useful, they are for different use cases.

@henryiii
Copy link
Contributor

because it does exactly that for you ... whether they are downloaded or built locally

That's the problem, it does not store wheels that are downloaded. So if you depend on numpy, you will not get a numpy wheel in your wheelhouse unless there is no numpy wheel for that platform. This causes twine wheelhouse/* to work until you build on a platform without numpy wheels, then it crashes because you can't push numpy to PyPI. We have to work around that in cibuildwheel, as well as all the other builders that have an option to use pip wheel.

@sbidoul
Copy link

sbidoul commented Feb 21, 2024

That's the problem, it does not store wheels that are downloaded. So if you depend on numpy, you will not get a numpy wheel in your wheelhouse unless there is no numpy wheel for that platform.

That's strange. It is not my understanding of how pip wheel works. I use it daily and it always stores a wheel for each top level requirement and all their dependencies, whether dependent wheels exist in the index (in which case it will download them to the wheelhouse) or not (in which case it will download the sdists, build them and store the resulting wheels in the wheelhouse).

Now if the purpose is uploading wheels to an index, I'd use build -w, or pip wheel --no-deps, which are more or less equivalent?

@henryiii
Copy link
Contributor

I’ll investigate, maybe it changed or there’s an another reason it was behaving like that.

@akx
Copy link
Contributor

akx commented Mar 27, 2024

I'd like an uv pip wheel sort of command; it's very useful for multi-stage Docker image builds where you might need e.g. the full Python dev kit to build wheels, and then want to just use those cached wheels in a subsequent stage, á la

FROM python:3.12 AS requirements
COPY requirements.txt /wheels/requirements.txt
RUN cd /wheels && pip wheel --no-cache-dir -r requirements.txt

FROM python:3.12-slim AS runtime
RUN --mount=type=cache,ro,from=requirements,source=/wheels,target=/wheels pip install --no-cache-dir --no-index --find-links /wheels /wheels/*.whl

@potiuk
Copy link

potiuk commented Mar 27, 2024

I'd like an uv pip wheel sort of command; it's very useful for multi-stage Docker image builds where you might need e.g. the full Python dev kit to build wheels, and then want to just use those cached wheels in a subsequent stage, á la

Small comment on that one (I do not contest the need for pip wheel of course just explaining how we are doing it in Airflow). I found that you can do quite a bit better than that by just copying the whole venv installed in the "build stage". If you keep it in the same location, this will work out of the box as well.

Smthing like:

FROM python:3.12 AS requirements
COPY requirements.txt /requirements.txt
RUN python -m venv /home/user/.venv && /home/user/.ven/bin/python -m pip install -r /requirements.txt

FROM python:3.12-slim AS runtime
COPY --from=requirements ~/home/user/.venv /home/user/.venv

That saves the hassle of running pip/uv install twice.

@mmerickel
Copy link

Just to second this issue, my pipeline is dependent on the recursive nature of pip wheel to download all dependencies into a wheelhouse which we can then install offline. Using pip download is possible but would require another loop to build wheels for everything into a proper wheelhouse and I'd really be looking for the uv equivalent to support the full cycle directly from requirements file -> wheelhouse.

@pradyunsg
Copy link

pradyunsg commented Apr 6, 2024

I tend to think of pip wheel as being useful for multiple roles:

  • "give me a bunch of wheels" by default.
  • "give me a wheel for this package" via an opt-in (--no-deps).

The default is not the most common operation during development, and the functional behaviour provided by pypa/build is better suited to the right behaviours during package development workflows. Ideally, these two should be under a logically different commands in uv.

None the less, my two cents would be that this shim should not be provided and uv should instead focus on its own dedicated CLI outside of the pip namespace; keeping these two "consumer" and "publisher" pieces separated.

@vigneshmanick
Copy link

To second this issue, In our usecase we build the wheel once (pip wheel . -w dist)and store it as an artifact which is then used by subsequent pipelines. This helps us to ensure that the production and ci environments are consistent and also helps to manually check the wheel contents without having to resort to additional commands.

@mmerickel
Copy link

FWIW I added a concrete example of how I use pip wheel to #7148 if it's helpful in motivating this feature.

@notatallshaw
Copy link
Contributor

notatallshaw commented Sep 6, 2024

The command uv build now exists, does this not cover this requirement?

@mmerickel
Copy link

The issue is that the new command doesn’t build the dependencies. Neither the local dependencies in the workspace nor the remote dependencies from the package index.

@Ralith
Copy link

Ralith commented Sep 16, 2024

This would be useful for packaging Blender extensions, which need their dependencies bundled as wheels in a subdirectory: https://docs.blender.org/manual/en/dev/advanced/extensions/python_wheels.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility Compatibility with a specification or another tool enhancement New feature or request
Projects
None yet
Development

No branches or pull requests