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

Created on 2020-11-17 06:56 by s0undt3ch, last changed 2020-11-17 15:03 by jaraco.

Pull Requests
URL Status Linked Edit
PR 23334 open s0undt3ch, 2020-11-17 07:50
Messages (4)
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.
History
Date User Action Args
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