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

pip interop for relative packages #2635

Closed
serjflint opened this issue Mar 23, 2024 · 13 comments
Closed

pip interop for relative packages #2635

serjflint opened this issue Mar 23, 2024 · 13 comments
Labels
compatibility Compatibility with a specification or another tool question Asking for clarification or support

Comments

@serjflint
Copy link

Hi!

FIrst, I wish to say that uv is an amazing tool and works blazingly fast.

I am working with an existing legacy setup and trying to use uv as a local replacement for pip.
The biggest complication with that legacy setup that it requires a package from a local relative path.
I have to use https://peps.python.org/pep-0440/#direct-references for it.

In the issues I have found that I can use ${PROJECT_ROOT} for the uv. But it is not really an environment variable and it is not set at the time of loading 'setup.py' file.

In the end I got something like this

import os
import pathlib
import setuptools
import sys

PACKAGE_PATH = (
    pathlib.Path(__file__).parent.parent / 'dir' / 'package'
)
if sys.argv[0] == '-c':  # uv hack
    PACKAGE_URL = r'file:///${PROJECT_ROOT}/../dir/package'
else:
    PACKAGE_URL = f'file://localhost/{PACKAGE_PATH}#egg=sub_package'

Is there any better way to do this?

@serjflint
Copy link
Author

serjflint commented Mar 23, 2024

When I used PACKAGE_URL = r'file:///${PROJECT_ROOT}/../dir/package#egg=sub_package'
and called python -m pip install -e . I got a following error:
ERROR: Could not install packages due to an OSError: [Errno 2] No such file or directory: '/dir/package'

@charliermarsh
Copy link
Member

We accept relative URLs for direct references, so you can do like foo @ ./bar. Does that work?

@charliermarsh charliermarsh added the question Asking for clarification or support label Mar 23, 2024
@serjflint
Copy link
Author

We accept relative URLs for direct references, so you can do like foo @ ./bar. Does that work?

I tried package @ ../dir/package and got an error with pip

error in main-package setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers; Invalid URL: ../dir/package

The question is how to get a configuration which works with both pip and uv.

@charliermarsh
Copy link
Member

Yeah, unfortunately pip doesn't support relative references. It does expand environment variables, so you could use PROJECT_ROOT like above, but you'd have to "inject" it manually when running pip install commands.

@serjflint
Copy link
Author

Yeah, unfortunately pip doesn't support relative references. It does expand environment variables, so you could use PROJECT_ROOT like above, but you'd have to "inject" it manually when running pip install commands.

Then I have to inject it each time or write a wrapper script. So the easiest way would be to ask pip to add a default for PROJECT_ROOT variable.

@zanieb zanieb added the compatibility Compatibility with a specification or another tool label Mar 25, 2024
@serjflint
Copy link
Author

serjflint commented Mar 25, 2024

When I use f'file://localhost/{PACKAGE_PATH}#egg=sub_package' I get an error

uv pip install -e .
error: Failed to build editables
  Caused by: Failed to parse metadata from built wheel
  Caused by: relative path without a working directory: localhost//abs/path/dir/package#egg=sub_package
package @ file://localhost//abs/path/dir/package#egg=sub_package
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

@serjflint
Copy link
Author

serjflint commented Mar 25, 2024

I assume it is wrongly treated as a relative path by pep508-rs crate even though it is a pep440 link.

let path = if path.is_absolute() {

@charliermarsh
Copy link
Member

Why include localhost/?

@serjflint
Copy link
Author

serjflint commented Mar 25, 2024

Why include localhost/?

It is an assumed default by pep 440 https://peps.python.org/pep-0440/#file-urls

Without it - PACKAGE_URL = f'file:///{PACKAGE_PATH}#egg=sub_package' I got an error

error in main-package setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers; Invalid URL given

P.S.: the value is file:////abs/path/dir/package#egg=sub_package and I get the same error without egg specifier.

@charliermarsh
Copy link
Member

Thanks, we're probably just missing handling for that, although I think the problem is your PACKAGE_PATH has a leading slash...? The resolved URL was file://localhost//abs/path/dir/package#egg=sub_package.

@serjflint
Copy link
Author

serjflint commented Mar 25, 2024

Thanks, we're probably just missing handling for that, although I think the problem is your PACKAGE_PATH has a leading slash...? The resolved URL was file://localhost//abs/path/dir/package#egg=sub_package.

Actually yes. I removed it and it solved the problem. Thank you very much for your time and patience.

P.S.: even the egg part works with uv --version 0.1.24

@charliermarsh
Copy link
Member

I filed an issue for the localhost part here: #2652

@bluss
Copy link
Contributor

bluss commented Mar 25, 2024

Now I don't know your project, but in general about ${PROJECT_ROOT}, there are package systems that support that variable in dependencies and can create packages using it that pip can install, and setuptools is not one of them.
PDM seems to be one of them. In such a PDM defined pyproject, pip reads the project, starts the wheel build, pdm build hooks resolve the dependency to an absolute path and it somehow works.

The general thinking would be to use a package builder that supports relative path references like that. But I'll be careful and say I don't know which way works simultaneously in both pip and uv. The way I would currently do that works in pip but falls afoul of #1808 in uv (for a file URL). (Edit: Now those problems seem to be fixed already 😉 @charliermarsh )

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 question Asking for clarification or support
Projects
None yet
Development

No branches or pull requests

4 participants