-
Notifications
You must be signed in to change notification settings - Fork 3k
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 doesn't support relative paths in direct URL references #6658
Comments
Okay, I see the problem. In However, in everything else, it's the following (I'm not sure which is the "newer" one, but the following logic is very limiting and not fully compliant as per RFC 3986 as if req.url:
parsed_url = urlparse.urlparse(req.url)
if not (parsed_url.scheme and parsed_url.netloc) or (
not parsed_url.scheme and not parsed_url.netloc):
raise InvalidRequirement("Invalid URL given") 🙄 That means since my filepath has Here is the complete solution: import os
from setuptools import setup
PKG_DIR = os.path.dirname(os.path.abspath(__file__))
setup(
install_requires=[
f'foo @ file://localhost{PKG_DIR}/foo/bar'
]
) This is pretty bad UX mixed in with ambiguous and time-wasting errors. How can we improve this situation? |
@Qix- glad you found this! I was beating my head against the wall trying all the same formats. This is my alternative option to #6162 and the deprecation of dependency_links. We're trying to set up a private repo and don't have our own internal server. Our solution is to publish packages to s3 and then to consume them we download them, put them in a local folder, then add them to I'm sure there are many other uses cases that would benefit from an intuitive way to install local packages. |
@ryanaklein I would actually suggest ignoring all of the unresearch negativity towards git submodules and try them out (assuming you're using Git). If you stop thinking about them as branches and start thinking about them as tags (or releases), they begin to work really well. They're very frequently used in the C/C++ world, and we vendored Python packages using them pretty successfully (aside from the above bug, of course!). Might cut down on the network/$$ costs of S3 :) |
For the direct URL reference (
The latter wouldn't be acceptable per PEP 508, so it would be hard to justify supporting much less get it working across all tools.
#5204 should help with this general question from a pip standpoint. |
I think this is due to the CPython bug raised in issue 22852 – "urllib.parse wrongly strips empty #fragment, ?query, //netloc" That bug seems to cause also issue #3783 – see this comment. |
What is the status of this issue? A solution for resolving local dependencies that are not on PyPI is urgently needed, for example in the context of monolithic repositories. Note that npm has implemented this feature in a similar way and |
Please see this comment above to know what needs to happen before this has a chance to be implmenented. pip can do nothing before that. |
FYI Hatch now supports relative paths using the new context formatting capability https://hatch.pypa.io/latest/config/dependency/#local |
Environment
Description
I'm not sure if this is a
six
bug or a Pip bug. Excuse me if it belongs tosix
.Pip seems to allow local paths in
install_requires
vianame @ ./some/path
, but the URL parsing is terribly broken.pip/src/pip/_internal/download.py
Lines 670 to 690 in a38a0ea
In this function, it uses
urlsplit
to get the individual components of the incoming URL.Here's what that looks like with a few pieces of input:
Notice the last one results in the
netloc
being.
instead of empty and thepath
being absolute, not local. This trips the error regarding non-local paths. That's all fine and well - I can use the second form to satisfy the conditional logic (though it really ought to support the first as well).However, there's conflicting logic elsewhere...
pip/src/pip/_vendor/packaging/requirements.py
Lines 103 to 106 in 169eebd
This is the logic that fails even though we satisfy the prior logic.
Here's a test function that shows the problem:
Here's the output for
./foo/bar
:All good, though it doesn't satisfy the first function's logic of requiring a scheme of
file:
.Here's the output for
file:./foo/bar
:Oops! Notice how, when we "unparse" the result from the first parse call, our
path
becomes absolutefile:///...
.This is why the second mentioned check fails - the path is not local. I believe this to be a bug in
six
but can be mitigated in Pip by allowingscheme in ['file', '']
and instructing users to use the./foo/bar
URI form.Given these two contradictory pieces of logic, it's impossible to use local paths in
install_requires
keys in eitherdistutils
orsetuptools
configurations.Expected behavior
I should be able to do
name @ ./some/path
(or, honestly, simply./some/path
) to specify a vendored package local to my codebase.How to Reproduce
Output
From the first
pip install
:From the second
pip install
:EDIT:
Just found out that RFC 3986 specifies that relative path URIs are not permitted with the
file:
scheme, so technicallysix
should be erroring out onfile:./foo/bar
.However, that means, technically, I should be able to do the following in my setup.py:
However, pip seems to be creating a "clean" copy of the package in
/tmp
, so we get something likefile:///tmp/pip-req-build-9u3z545j/foo/bar
.Running that through our test function, we satisfy the second function's conditional:
Everything is good there. The "unparse" yields the same result, and the
netloc
requirements are met for the first function's conditional.However, we're still met with an
Invalid URL
error, even though the second function's logic is satisfied.Since
pip
(or distutils or setuptools or whatever) swallows output, I went ahead and did the following in my setup.pyWhich verifies that all of the files are there, as expected - so it can't be a file missing or something. The line above that has
"Invalid URL given"
is the only place in the codebase that string shows up.At this point, I'm not sure what the problem is.
The text was updated successfully, but these errors were encountered: