Skip to content

Commit aa9f799

Browse files
authored
Merge pull request #287 from python/feature/packages-distributions
Add 'packages_distributions'.
2 parents 73cf0a9 + 466cd3c commit aa9f799

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

CHANGES.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
v3.7.0
2+
======
3+
4+
* #131: Added ``packages_distributions`` to conveniently
5+
resolve a top-level package or module to its distribution(s).
6+
17
v3.6.0
28
======
39

docs/using.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,17 @@ function::
182182
["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"]
183183

184184

185+
Package distributions
186+
---------------------
187+
188+
A convience method to resolve the distribution or
189+
distributions (in the case of a namespace package) for top-level
190+
Python packages or modules::
191+
192+
>>> packages_distributions()
193+
{'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...}
194+
195+
185196
Distributions
186197
=============
187198

importlib_metadata/__init__.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import functools
1313
import itertools
1414
import posixpath
15-
import collections
15+
import collections.abc
1616

1717
from ._compat import (
1818
NullFinder,
@@ -28,7 +28,7 @@
2828
from importlib import import_module
2929
from importlib.abc import MetaPathFinder
3030
from itertools import starmap
31-
from typing import Any, List, Optional, TypeVar, Union
31+
from typing import Any, List, Mapping, Optional, TypeVar, Union
3232

3333

3434
__all__ = [
@@ -796,3 +796,19 @@ def requires(distribution_name):
796796
packaging.requirement.Requirement.
797797
"""
798798
return distribution(distribution_name).requires
799+
800+
801+
def packages_distributions() -> Mapping[str, List[str]]:
802+
"""
803+
Return a mapping of top-level packages to their
804+
distributions.
805+
806+
>>> pkgs = packages_distributions()
807+
>>> all(isinstance(dist, collections.abc.Sequence) for dist in pkgs.values())
808+
True
809+
"""
810+
pkg_to_dist = collections.defaultdict(list)
811+
for dist in distributions():
812+
for pkg in (dist.read_text('top_level.txt') or '').split():
813+
pkg_to_dist[pkg].append(dist.metadata['Name'])
814+
return dict(pkg_to_dist)

0 commit comments

Comments
 (0)