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/

Reply via email to