-
-
Notifications
You must be signed in to change notification settings - Fork 404
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
allow binding between source index and individual dependencies #1645
Comments
Supplying the index with the command line option is not sufficient, we must also encode that in The problem is that we are following PEP 621 and every dependency specification is a string, compared to a table which is the case in Poetry. If we want to add the per-package index, it must reside in a separate table from [project]
dependencies = [
"flake8",
"pytest",
]
[[tool.pdm.source]]
name = "private"
url = "https://private.pypi.com/simple"
packages = [
"flake8", # requested dependency
"pyflakes", # transitive dependency
] Here we have to specify the transitive dependencies explicitly since we can't assume it should inherit the parent's config. If you are working on a large project with hundreds of dependencies and more transitive dependencies, writing that list is a huge pain. But as you can't achieve this with pip+requirements.txt, I'd rather keep this open than hurry to finish an awkward implementation, until an elegant solution was discussed through. |
There is no standard for specifying dependencies like when you do with git+{https,ssh}, like so? [project]
dependencies = [
"flake8",
"pytest @ ${USER}:${PASSWORD}@private/pypi",
] My gut feeling is no, and I also suspect it would not be PEP compliant because the fields in |
yes, we can't put custom fields in project table. |
What if
EDIT: this assumes that once found in an index all the possible package versions will reside in that index. Might not cover all edge cases, but seems reasonable. Also, the first "check to what index the package belongs to and cache it" only applies to the command and is not stored anywhere. |
Just want to chime in that I kinda desperately want this feature, as well, for performance reasons similar to what's described in #1509, though I prefer explicit package->index binding as a solution. Also, in response to @frostming:
IMO, there's no need to assume anything about subdependencies. When adding an index-bound dep, subdependencies should not automatically be bound to the same index.
|
@mikenerone Specifying a transitive dependency as direct dependency muddies the dependency status. Maintainers and tools that detect unused dependencies would suffer. |
I don't disagree - it's not ideal, but assuming that transitive deps should also be index-bound would be even less ideal. A guess a "better" alternative to adding them as direct, at least as far as this concern goes, would be to simply leave it as a manual editing task to add transitive deps to the appropriate |
I guess a PEP proposal came to the rescue? https://peps.python.org/pep-0710/ |
This is extremely cool, thanks! |
Oh, did you review the change? any feedback is welcome. |
I had a look at the source code, did not get a chance to test it yet because I am no longer working with a company with a private index. When I have the time I will try out with a local PyPI server 🚀 EDIT: clever solution by the way! I would add a couple of recommendations whether such configs should be in pyproject.toml or .pdm.toml and be kept private. |
Nice work! We have the use-case as well, I'll try it today or next week. I agree with @baggiponte, the recommendations on where to put the config (global? pyproject.toml?) would be nice to have. |
Same here - haven't had the time yet to test it out, but I am so happy for this. Hopefully I'll find the time this week and leave a feedback here after. Thank you |
@frostming I have tested it. I observe that perhaps [[tool.pdm.source]]
include_packages = [
"torch-cuda80",
"torch-model-archiver",
"torch-tb-profiler",
"torch",
"torchaudio",
"torchcsprng",
"torchdata",
"torchdistx",
"torchmetrics",
"torchrec-cpu",
"torchrec",
"torchserve",
"torchtext",
"torchvision",
]
name = "PyTorch"
url = "https://download.pytorch.org/whl/cpu"
verify_ssl = true
|
@sanmai-NL I would open a new issue to help Frost triage as this feature request ticket is closed as complete. I just installed [[tool.pdm.source]]
name = "PyTorch"
url = "https://download.pytorch.org/whl/cu118"
include_packages = ["torch"] This achieves the same result as the official PyTorch: Start Locally help page suggests via pip install torch --index-url https://download.pytorch.org/whl/cu118 I also note that when I publish this as a package, and other '2nd degree' packages include my package as a dependency, those 2nd degree packages don't 'inherit' the index URL config (i.e. they pull Also, for reference this was discussed on the official Python discussion forum: https://discuss.python.org/t/how-to-specify-extra-index-in-a-pyproject-toml-for-pip-and-pip-tools/23592/6 |
https://pdm-project.org/en/latest/usage/config/#respect-the-order-of-the-sources [tool.pdm.resolution]
respect-source-order = true
This will also affect some other behaviours in PDM such as |
do you include the torch package in the project.dependents list or is it only in the source section? |
Thanks, @lmmx! This is exactly what I wanted to find. Search results only pointed me to #1032, #2982 but this is really the answer I needed. Works great! More details in the documentation. |
Scenario
It is already possible to define more then one pypi-like index source. Since v2.4.0 there are 2 ways to do that (AFAIK). In
pyproject.toml
and inconfig.toml
.It is also possible to define priority for these sources to some extend. In case of pyproject.toml, it is possible to utilize the order resolution. In case of config.toml, it is possible to inverse priority by defining internal/alternative source within
[pypi]
section and pypi itself in[pypi.extra]
section.This is insufficient, because there are lot of deficiencies in the dependency resolution process.
Consider this:
Lets use v2.4.0 and define internal server in config.toml in
[pypi.extra]
section. If the internal python package shares its name with some public package on pypi, pdm will resolve and download against pypi, which is wrong for the company. Naming differently is not the right approach, because it is not deterministic -> even though the company chooses unique name, there is no certainty, that the same name will not be published to pypi later.So we swap the sections and define internal server in
[pypi]
instead. This solves the priority problem, but introduces http-rest flood problem. If the project uses 100 public packages and only 1 internal, then 99 packages will be first resolved against internal server with no success and only then against public pypi. Which is waste of network resources.There are more subtle quirks as well. E.g. if access token for internal server expires, pdm resolution against internal server fails with credentials error, but the resolution continues and if there is public package on pypi with the same name, it falls-back to it and download and install it, which is adverse.
Describe the solution you'd like
All problems mentioned above and possibly even more edge cases I haven't bumped into yet, would be solved, if there was a way how to bind individual dependencies against specific (array of) indexes.
E.g.
pdm add <package> --only-source=internal
Such flag would cause all related actions to be bonded exclusively to that source. So,
pdm install
;pdm lock
; etc. would fail if that package was not found on that source, or if credentials didn't work, etc..The text was updated successfully, but these errors were encountered: