-
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
Add support for outputting a list of extras and their requirements. #4824
Comments
An alternative would be to create a |
This seems to be deeply related and a better alternative to #3797. |
An even better alternative would be to use importlib_metadata, which has an API.
|
And use packaging to parse them:
|
The lack of this feature is an increasingly troublesome annoyance for Twisted. Since python packaging is allegedly Good Now, Actually™ (thanks for that, by the way!), we're starting to rely more on asking our users to install e.g. However, how is the user supposed to know if it's Thanks for reading! |
Given that, as @jaraco mentioned, the data is available via I'm sympathetic to the idea that making the information available via pip aids discoverability, but given that it's possible to get the information the OP needed already, it seems less than ideal to block any progress on this until it can be added to pip. (If nothing else, a standalone script could be the basis of a future PR for pip). |
The OP posted the issue a year and a half ago. I hope they already found a way to not be blocked in their endeavours. :) This is the pip issue tracker though. It seems appropriate to focus on how to support this use-case in pip here. |
One thing to note is that the OP seems to have been discussing gathering this information for programmatic consumption ("I'm trying to write a script to automatically ...") but this comment from @glyph is firmly focused on user education and so probably manual usage by a human. These are both good and interesting use-cases but they may not have the same solution. |
while it might be a slight different enhancement than what OP meant, I think we all would be glad to have a Using the |
Okay, this feature makes sense and we'd want to include it in pip. We welcome folks to submit a PR for implementing this functionality. Note that this does not mean that the said PR would be accepted - it would still be subject to our regular code reviews as with every other PR in pip. The relevant bit of code is likely in |
There are actually two features this thread talks about. The top post describes showing showing extras in But that does not really help the discovery problem mentioned by @glyph, since A more workable solution would be to let I hope this thought dump would be marginally helpful for anyone interesting in implementing this feature. |
The main suggestions provided in #8008 (review) which is the documentation PR for #7967 (Adding json format display to |
+1 for listing the extras of a package We want to split our package into smaller packages linked as extras and it would be nice to see what are all the available extras. Also I have open a stackoverflow question about that before finding this thread |
For anyone here looking for something to copy/paste: from importlib.metadata import metadata
from collections import defaultdict
from pprint import pprint
def get_extras(package_name):
extras = metadata(package_name).get_all("Provides-Extra")
required_dists = metadata(package_name).get_all("Requires-Dist")
result = defaultdict(list)
for extra in extras:
for required_dist in required_dists:
suffix = f" ; extra == '{extra}'"
if required_dist.endswith(suffix):
result[extra].append(required_dist.replace(suffix, ""))
return result
pprint(get_extras("package_name_goes_here")) This will output the extras, and the packages that each extra will install. E.g. for the {
"accelerate": ["accelerate (>=0.10.0)"],
"audio": ["librosa", "pyctcdecode (>=0.3.0)", "phonemizer"],
"codecarbon": ["codecarbon (==1.2.0)"],
"deepspeed": ["deepspeed (>=0.6.5)", "accelerate (>=0.10.0)"],
...
} I have no idea how robust this is vis-a-vis the layout of the |
@davidgilbertson You can use |
Something like… |
'pip inspect' is ok, and gives pypa devs full liberty to change/improve anything. |
It would be ideal if an implementation for #7122 had an error-message similar to: |
Here's a one-liner based on @stonebig's answer that uses
|
Built on top of @glyph's and @kratsg's answers I came up with a jq query that filters out all the deps from pip inspect | jq ".installed[] | select(.metadata.name == \"aiogram\").metadata.requires_dist
| map(select(contains(\"; extra ==\")) | capture(\"(?<dep>.+); extra == (\\\"|')(?<extra>[^']+)(\\\"|')\" ) )
| group_by(.extra)
| map( { (.[0].extra) : map(.dep) } )
| add"
{
"dev": [
"mypy",
"typing_extensions",
"types-psutil",
"pycodestyle",
"ruff",
"cython-lint>=0.12.2",
"rich-click",
"click",
"doit>=0.36.0",
"pydevtool"
],
"doc": [
"sphinx!=4.1.0",
"pydata-sphinx-theme==0.9.0",
"sphinx-design>=0.2.0",
"matplotlib>2",
"numpydoc",
"jupytext",
"myst-nb",
"pooch"
],
"test": [
"pytest",
"pytest-cov",
"pytest-timeout",
"pytest-xdist",
"asv",
"mpmath",
"gmpy2",
"threadpoolctl",
"scikit-umfpack",
"pooch"
]
}
And if you want to put it in a script and are too lazy to add the necessary bits XD here you go: #!/usr/bin/env sh
python -m pip inspect | jq ".installed[] | select(.metadata.name == \"$1\").metadata.requires_dist
| map(select(contains(\"; extra ==\")) | capture(\"(?<dep>.+); extra == (\\\"|')(?<extra>[^']+)(\\\"|')\" ) )
| group_by(.extra)
| map( { (.[0].extra) : map(.dep) } )
| add" |
## Summary Follow-up for 395be44 adds `Requires` field to pip show output. I've aimed to make it behave exactly the same as `pip` does for now, but there seem to be subtle issues that may require some discussion going forward: - Should `uv pip show` support extras? `pip` has an open issue for it, but currently does not support pypa/pip#4824. - Relatedly, `Requred-by` field (not implemented in this PR) in `pip show` currently doesn't take the extras into account transparently, i.e. when `PySocks` has been installed as an extra for `requests[socks]`, `pip show PySocks` doesn't have `requests` or `requests[socks]` under `Requred-by` field. Should `uv pip show` for now just replicate `pip`'s behavior for now for simplicity and parity or try to cover the extras for completeness? ## Test Plan Added a couple of tests: 1. `requests==2.31.0` has four dependencies that would be ordered differently unless sorted. Additionally, it has two dependencies that are optionally included for extras. 2. `pandas==2.1.3` depends on different versions of `numpy` depending on the python version used.
I have create a tiny Python gist to print out package extras' requirements: get_package_extras.py. |
Do we still want a dedicated feature for this, now that |
@uranusjr Indeed, all information is available with |
You may close this old thread, and the idea may come back when a fundamental change will happen, like 'uv' integration |
I do. Parsing hundreds of lines of JSON is "real work". The most-promising solution (thanks @mierzejk !) is 25 lines of python, not exactly fodder for a bash alias. I'm here on this thread again in late 2024 because I've searched for how to do this, and been led here from a (now useless) StackOverflow answer. When it's faster to look in the source, understand I'd be way more willing to take a stab at a PR if a concrete goal was outlined here. Like: what does the option or subcommand look like? (For me personally, I'd really like to have something like what #7122 asks for -- both an error and helpful message when installing and unknown extra -- but that thread also doesn't appear to have consensus. Since this has come up for me several times recently, I'd love to have some "pip developer / ux guidance" on what to do here, what might be most-acceptable: a command asking for valid extras, or an error-message like 7122 wants? Does anyone have a few more hints towards what pip developers or other users would find acceptable here?). For the purposes of spurring discussion, what about:
|
This 100% what I'm looking for |
Description:
I'm trying to write a script to automatically generate constraints files(with hashes) and I'd like a way to allow this script to detect any extras, and generate the constraints file for those too.
I have no preference to the command; but it might be nice to put it in
pip show
as another section(depending on compatibility)What I've run:
The text was updated successfully, but these errors were encountered: