On Mon, Apr 26, 2021 at 3:25 PM Stestagg <stest...@gmail.com> wrote: > > > On Mon, Apr 26, 2021 at 10:31 PM Brett Cannon <br...@python.org> wrote: > >> >> >> On Mon, Apr 26, 2021 at 9:37 AM Baptiste Carvello < >> devel2...@baptiste-carvello.net> wrote: >> >>> Hi, >>> >>> sorry for being late to the party, but I may not be the only one >>> wondering… >>> >>> Le 14/04/2021 à 20:56, Barry Warsaw a écrit : >>> > >>> > I’d forgotten that this PEP was in Deferred state. I think it should >>> be rejected and I plan on making that change. importlib.metadata is a much >>> better approach to programmatically determining package versions. >>> > >>> > >>> https://docs.python.org/3/library/importlib.metadata.html#distribution-versions >>> >>> This is indeed the correct approach, thanks for letting me learn this. >>> >>> However, I unsuccessfully searched for the canonical way to look up the >>> distribution name based on either a module name or an imported module >>> object. Is there one? >>> >> >> If you mean how to tie a module back to its name on PyPI, you should be >> able to look up the "Name" in the project's metadata: >> https://docs.python.org/3/library/importlib.metadata.html#distribution-metadata >> . >> >> > The missing bit here, for me, is how do you map a module back to it's > project (distribution)? > > For example: > > ``` > >>> import bs4 > >>> bs4.__version__ > '4.9.1' > >>> importlib.metadata.metadata('bs4') > PackageNotFoundError: bs4 > ``` > > This is because the distribution calls itself 'beautifulsoup4' instead. >
Unfortunately I thought importlib.metadata would have used the module name instead of the metadata details, but in hindsight am guessing that the .dist-info is what it's using to do the lookup and that's based on the package name instead of the project name. This is a long-standing issue with projects that use project names which differ from their module name, but there's no good way without checking what files a project installed (which is what you're doing below). -Brett > > The same goes for another package: `umap`, for which the distribution is > called `umap-learn` > > > This is the best I could come up with from reading the docs: > > import bs4 #<- This is the module we want the version of > > import importlib > import sys > from itertools import chain > from pathlib import Path > > loaders = sys.meta_path > > target_path = Path(bs4.__file__) > > distros = list(chain(*(finder.find_distributions() for finder in > loaders if hasattr(finder, 'find_distributions')))) > distros_files = chain(*(f for f in (d.files for d in distros))) > distro_files = [(d, d.locate_file(f)) for d in distros if d.files for > f in d.files] > matching = [d for d, f in distro_files if f == target_path] > > for match in matching: > print("Found Version:", match.version) > > Steve >
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/ON5SH2F654I7NEMCYXRH253QRN32LQGG/ Code of Conduct: http://python.org/psf/codeofconduct/