-
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
Cannot install a direct reference dependency as an "editable" dependency #10216
Comments
I can reproduce this exact same error with pip 22.0.3. Workaround 2 works but is not as nice when publishing a package. |
"Setuptools should allow you to install a direct-reference package in editable mode" I ran into this limitation as well. Would be great to see a solution. |
Is there anything that can be done to fix this? I'd like to try and contribute a solution, but I'm a bit lost on where to start. |
See my comment on #12533. I think this is the same issue, and my comments there apply here too. Thanks for the explanation of how you ended up in this situation, it's easier to see the issue with a real-world example. But I think the comment I made there remains true - pip can't ensure that the dependencies (the two repositories for the two packages involved) will stay in sync, so it's unable to guarantee that any resolution it comes up with is safe. If you have to use this layout, then I think your two workarounds are your best option. |
Hi @pfmoore, I read your comments in the linked issue, and I understand what you’re saying. I have a couple points I think are worth consideration:
there is one use case for this feature which is more than just questionable, it’s a use case that’s becoming more and more prevalent, barring roadblocks like this: monorepos. I do all of my development in a monorepo, and would dearly love to not have to jump through hoops to make it work with python
my view (and the reason I offered to submit a PR) is that a RequirementsConflicted exception where both requirements point to the same package at the same location is not actually a conflict and should not be treated as a conflict. In the case where one of those two requirements also happens to be editable, there should be some method (command line flag or something) to allow pip to resolve the conflict by choosing either the editable or non-editable variant of that dependency as I said in a previous comment, I’m willing to start work on a PR, I just need some guidance on portions of the code to focus my efforts |
I can't really comment on the monorepo use case, as I don't use them myself, but as far as I'm aware there are a number of difficulties with them, which I think need to be discussed at a higher level, to establish what the "monorepo workflow" is and what needs to change in the packaging ecosystem to properly support them - assuming we want to1. The need to support relative pathnames as a legitimate dependency (or package) specifier is the most obvious example, and this is part of that question.
The problem here is that you'd need to start by looking at how pip decides whether two packages are "the same". That's a very basic decision that impacts a lot of the logic, so you could end up going down something of a rabbit hole. The basic answer is that two "candidates" (to use the term the resolver works with) are the same if they have the same package name and version. However, layered on top of that are a bunch of heuristics around source trees identified by URLs or local paths. And editable installs are another layer on top of all that, which are not really considered in the resolution algorithm at all2. By all means take a look, but please don't be surprised if the problem turns out to be a lot more complex than you'd hoped. Also, when you say "both requirements point to the same package at the same location" you need to consider how you define "the same location" - are Sorry if this sounds negative. It's sort of what I was trying to get at when I said we're "doing the best we can" 🙂 I appreciate the offer of help, it's just that the learning curve is steep, and this isn't an easy place to start... Footnotes
|
@pfmoore thanks so much for all of the details and background on this issue. I've also been working with monorepos more across various languages, and I think this issue was a result of me making a foray into that line of thinking. I think in the future I'll just avoid doing the part that got me into this mess:
I honestly don't really remember what I was trying to accomplish by doing this. Maybe dependency isolation? I think in the future I'll probably just use a single package definition, instead of trying to divide one large package into components. The "optional-dependencies" feature would allow downstream applications to reduce the total number of packages which are installed, based on need. Also there's no reason why the applications themselves couldn't live in the same repository under the same package structure, with different entrypoints defined via The workaround that I actually ended up going with was to not try installing the package(s) in editable mode. If I made changes to one of the underlying packages while working on one of the downstream applications, I just reinstalled the dependencies locally after making changes to them. I also got a new job shortly afterward, which helped as well. |
FYI. @AustinTSchaffer: There are various Ideas how monorepos can be handled and there are various tools supporting them. Many people understand monorepos in various ways. And I think personally that until there is a PEP/standard describing it it's quite good that (Note - I am not a maintainer or heavy contributor to From my research in this area:
Happy to share my experiences, but we have 90+ packages in Airlfow's monorepo with a great development workflow and release process as of apache/airflow#36537 - following all the standard, pyproject.toml only and with nice set of development extras, It requires quite a lot of tooling around, but it works really nicely for Airflow.
I likely miss a few others, but those are the ones I am following very closely and try to contribute where I see possibility to get it more standards. My recommentation is though that until the standards are there, it's good to choose a solution that will not make you "tied" to a particular solution too much but will keep you going and allow you to "catch up" when the others will provide good tooling following standards. Like in our case That's all thanks to the standard developed by Packaging team becoming implemented and followed - creating the situatuions where in the same project you can even mix and match the different tools do the job they are best in. We are currently using |
Description
It seems that you can't install a package in editable mode, while simultaneously installing a package that depends on that package via a direct reference.
I came across this issue when splitting a project into 2 packages that both live in the same repository. Package A now depends on Package B via a direct reference. Since both are in the same repository, I tried installing both in editable mode, but pip came back with:
It seems that this action should be allowed taking the wording of the error message at face value.
I did some debugging and found that
Resolution._add_to_criteria
fromsrc/pip/_vendor/resolvelib/resolvers.py
raises aRequirementsConflicted
exception. The resolver cannot resolve the 2 requirements below. The resolver fails to generate any candidates apparently because both requirements are instances ofExplicitRequirement
.We have 2 workarounds for this:
package_a
, and just havepackage_a
depend on any package namedpackage_b
. This is an issue because Package A won't know where to get Package B unless you install them both at the same time withpip install -e ./package_a/ -e ./package_b/
. More worrying is if someone registers a package on PyPI that matches the name of our "Package B".Expected behavior
I'm not sure what should be expected in this situation? It seems like one of these should be true:
pip install -e A -e B
when A depends on B via a direct referencePoint 3 doesn't feel right, but just wanted to throw that out there.
pip version
21.3.dev0 (commit: a53f888)
Python version
3.9.5
OS
Ubuntu 21.04 hirsute
How to Reproduce
Create a directory named "package_b". Create a
setup.py
in that directory with the contents:Create a directory named "package_a" in the same directory that contains the "package_b" directory. Create a
setup.py
in that directory with the contents:You should now have:
Now run
pip install -e ./package_a/ -e ./package_b/
.Output
Code of Conduct
The text was updated successfully, but these errors were encountered: