classification
Title: No easy way to get the distribution which provided a importlib.metadata.EntryPoint
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.10
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: jaraco Nosy List: jaraco, s0undt3ch
Priority: normal Keywords: patch

Created on 2020-11-17 06:56 by s0undt3ch, last changed 2021-03-07 22:47 by jaraco. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 23334 closed s0undt3ch, 2020-11-17 07:50
PR 23758 merged jaraco, 2020-12-14 02:48
Messages (8)
msg381211 - (view) Author: Pedro Algarvio (s0undt3ch) * Date: 2020-11-17 06:56
With `pkg_resources` an `EntryPoint` has a dist attribute which allows you to get the distribution that provided that specific entry-point, however, with `importlib.metafata` and `importlib_metadata` that's not an east task.

```python
USE_IMPORTLIB_METADATA_STDLIB = USE_IMPORTLIB_METADATA = False
try:
    # Py3.8+
    import importlib.metadata

    USE_IMPORTLIB_METADATA_STDLIB = True
except ImportError:
    # < Py3.8 backport package
    import importlib_metadata

    USE_IMPORTLIB_METADATA = True


def get_distribution_from_entry_point(entry_point):
    loaded_entry_point = entry_point.load()
    if isinstance(loaded_entry_point, types.ModuleType):
        module_path = loaded_entry_point.__file__
    else:
        module_path = sys.modules[loaded_entry_point.__module__].__file__
    if USE_IMPORTLIB_METADATA_STDLIB:
        distributions = importlib.metadata.distributions
    else:
        distributions = importlib_metadata.distributions

    for distribution in distributions():
        try:
            relative = pathlib.Path(module_path).relative_to(
                distribution.locate_file("")
            )
        except ValueError:
            pass
        else:
            if relative in distribution.files:
                return distribution
```

The above solution has the additional drawback that you're iterating the distributions list, once per EntryPoint, which, was already iterated to get the entry-points listing.

I propose we attach the Distribution instance to each of the found EntryPoint to avoid this low performance workaround.

I don't have an issue with providing a pull-request, but should that pull request be done against `importlib_metadata` or `importlib.metadata`?
msg381235 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2020-11-17 14:12
Pedro - thanks for the detailed report. Pull requests against importlib_metadata are easier to accept because they can be tested more easily, released more rapidly, and there's a straightforward way to port them to CPython. Regardless, I see you've proposed a change to CPython, so I can work with that.
msg381239 - (view) Author: Pedro Algarvio (s0undt3ch) * Date: 2020-11-17 14:36
Guess I jumped too fast :)

Will the changes in CPythom be included in `importlib_metadata`?
msg381243 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2020-11-17 15:03
Yes - I keep both in sync.
msg382605 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2020-12-06 20:13
I've ported the initial patch over to the backport and am exploring options in https://github.com/python/importlib_metadata/pull/266.
msg382610 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2020-12-06 21:54
In discussion, I realized that I don't yet understand what use-cases drive this demand? What code is it that requires resolving a distribution from an entry point?
msg382611 - (view) Author: Pedro Algarvio (s0undt3ch) * Date: 2020-12-06 22:06
Our software uses a plug-in based approach.
Plugins are able to add/modify internal behavior, and, as part of bug submission process we have a CLI flag which provides information about the core app as well as any intervening plugins.

This is where we need to "map" an entry point to it's distribution, so we know the name and version of it to display on this report.
msg384126 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2020-12-31 17:57
New changeset dfdca85dfa64e72df385b3a486f85b773fc0f135 by Jason R. Coombs in branch 'master':
bpo-42382: In importlib.metadata, `EntryPoint` objects now expose `dist` (#23758)
https://github.com/python/cpython/commit/dfdca85dfa64e72df385b3a486f85b773fc0f135
History
Date User Action Args
2021-03-07 22:47:18jaracosetversions: + Python 3.10
2021-03-07 22:43:02jaracosetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2020-12-31 17:57:08jaracosetmessages: + msg384126
2020-12-14 02:48:08jaracosetpull_requests: + pull_request22614
2020-12-06 22:06:39s0undt3chsetmessages: + msg382611
2020-12-06 21:54:12jaracosetmessages: + msg382610
2020-12-06 20:13:00jaracosetmessages: + msg382605
2020-12-06 18:38:53jaracosetassignee: jaraco
2020-11-17 15:03:11jaracosetmessages: + msg381243
2020-11-17 14:36:26s0undt3chsetmessages: + msg381239
2020-11-17 14:12:48jaracosetmessages: + msg381235
2020-11-17 07:50:26s0undt3chsetkeywords: + patch
stage: patch review
pull_requests: + pull_request22222
2020-11-17 06:56:21s0undt3chcreate