Replace pkg_resources with importlib_metadata
See original GitHub issueWhat’s the problem this feature will solve?
Currently, pip uses a vendored version of pkg_resources
in several places.
pkg_resources has a few downsides for our use cases, including:
- unconditional scan of entire
sys.path
on import (pypa/setuptools#510), when we may only need it for a subset of those directories - various issues filed regarding corrupt
METADATA
files in site-packages preventing pip from starting - complicated to vendor vs a standalone library, since we need to extract it from setuptools
- higher barrier of entry for other package management tools that want pip-compatible behavior
Describe the solution you’d like
Replace pkg_resources
with importlib.metadata
(via the importlib-metadata
backport for Python < 3.8).
Our current usages for pkg_resources
are:
build_env.BuildEnvironment
: identify the set of packages available/conflicting in the isolated environment directoriesreq.req_install.InstallRequirement
: locate an already-installed packagecommands.search
,commands.show
: iterate over the set of installed packages and access metadatawheel
:- parse entrypoints
- check wheel version of unpacked Wheel
- ad-hoc usage of parsing/canonicalization functions
A combination of importlib_metadata
and packaging
can satisfy these requirements:
importlib.metadata.distributions(path=["dir1", "dir2"])
then comparison of the version usingpackaging.specifiers.SpecifierSet
importlib.metadata.distribution("package_name")
orimportlib.metadata.distributions(path=["..."], name="package_name")
[d.metadata["..."] for d in importlib.metadata.distributions()]
-
importlib.metadata.Distribution.at(info_dir).entry_points
next(importlib.metadata.distributions(path=["..."])).read_text("WHEEL")
packaging.utils.canonicalize_name
, etc
As a vendored library, importlib-metadata
would have the following characteristics:
- Apache-2.0 license
- Several backports for Python 2:
contextlib2
, which we already vendorpathlib2
- we have looked at for tests. There is one issue we need to investigate the impact of: mcmtroffaes/pathlib2#56 - MIT licensed, pure Python with no dependenciesconfigparser
-configparser
backport - MIT licensed, pure Python with no dependencies
- One dependency otherwise:
zipp
for making thezipfile
modulePath
-aware - MIT licensed, pure Python with no dependencies
Alternative Solutions
- Continue using
pkg_resources
- this approach has the downsides mentioned above - Use another metadata-providing library - none researched, I don’t imagine we’d choose something else over either of these two
See also
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:14 (14 by maintainers)
Top Results From Across the Web
Using importlib.metadata — Python 3.11.1 documentation
Built in part on Python's import system, this library intends to replace similar functionality in the entry point API and metadata API of...
Read more >Replace pkg_resources.iter_entry_points with importlib ...
The older pkg_resources package has some performance deficiencies when it comes to handling entry_points. The newer importlib.metadata ...
Read more >importlib-metadata - PyPI
This package supplies third-party access to the functionality of importlib.metadata including improvements added to subsequent Python versions.
Read more >python-xyz.scm - Ricardo Wurmus
... (delay python2-importlib-metadata-bootstrap)) ("python-importlib-resources" (delay ... (or (%python2-replacement (package-name package)) (assq-ref ...
Read more >switch to importlib.metadata package · d5297167e0 - stevedore
Load entry points using 'importlib.metadata' instead of 'pkg_resources'. ... not modify these files, except by changing the list of entry points in.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Yup,
read_text()
is the one to use, thanks for the pointer!Yeah I think everything is in place, the only thing we need now is for time to take over.