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.

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/NMTZZMVSZ5XIU2BTIFMPU7W734ET5VUA/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to