Skip to content

Commit 859d45b

Browse files
committed
replace pkg_resources with importlib.metadata
Importing pkg_resources has a side-effect of scanning every installed distribution on sys.path to load the metadata, especially the entry points defined in the packages. This can have a significant launch-time cost for command line applications when there are a lot of distributions to scan. Since cmd2 is only using pkg_resources to find the version of the installed package, pkg_resources can be replaced with importlib.metadata. The implementation in the new library is significantly faster because it goes immediately to the metadata file for the requested distribution, instead of scanning all of them. There are also no import-time side-effects. importlib.metadata is a new standard library module starting with python 3.8. For earlier versions, a compatible library has been released to PyPI as 'importlib_metadata'. This change adds the new dependency with a qualifier so that it is only applied to older versions of python, and then updates the places that were importing pkg_resources to look for the different versions of the new library instead. The documentation configuration is changed to import cmd2 itself to get its version, since the package has to be installed for the metadata to be available anyway. Signed-off-by: Doug Hellmann <[email protected]>
1 parent 6e19fb1 commit 859d45b

File tree

4 files changed

+22
-12
lines changed

4 files changed

+22
-12
lines changed

cmd2/__init__.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
# flake8: noqa F401
44
"""This simply imports certain things for backwards compatibility."""
55

6-
from pkg_resources import get_distribution, DistributionNotFound
76
try:
8-
__version__ = get_distribution(__name__).version
9-
except DistributionNotFound:
7+
# For python 3.8 and later
8+
import importlib.metadata as importlib_metadata
9+
except ImportError:
10+
# For everyone else
11+
import importlib_metadata
12+
try:
13+
__version__ = importlib_metadata.version(__name__)
14+
except importlib_metadata.PackageNotFoundError:
1015
# package is not installed
1116
pass
1217

docs/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"""
2020
# Import for custom theme from Read the Docs
2121
import sphinx_rtd_theme
22-
from pkg_resources import get_distribution
22+
import cmd2
2323

2424
# -- General configuration -----------------------------------------------------
2525

@@ -57,7 +57,7 @@
5757
# built documents.
5858
#
5959
# version will look like x.y.z
60-
version = get_distribution('cmd2').version
60+
version = cmd2.__version__
6161
# release will look like x.y
6262
release = '.'.join(version.split('.')[:2])
6363

plugins/ext_test/cmd2_ext_test/__init__.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,20 @@
55
An overview of what myplugin does.
66
"""
77

8-
from pkg_resources import DistributionNotFound, get_distribution
8+
try:
9+
# For python 3.8 and later
10+
import importlib.metadata as importlib_metadata
11+
except ImportError:
12+
# For everyone else
13+
import importlib_metadata
14+
try:
15+
__version__ = importlib_metadata.version(__name__)
16+
except importlib_metadata.PackageNotFoundError:
17+
# package is not installed
18+
__version__ = 'unknown'
919

1020
from .cmd2_ext_test import ExternalTestMixin
1121

1222
__all__ = [
1323
'ExternalTestMixin'
1424
]
15-
16-
17-
try:
18-
__version__ = get_distribution(__name__).version
19-
except DistributionNotFound:
20-
__version__ = 'unknown'

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
INSTALL_REQUIRES = [
3737
'attrs >= 16.3.0',
3838
'colorama >= 0.3.7',
39+
'importlib_metadata>=1.7.0;python_version<"3.8"',
3940
'pyperclip >= 1.6',
4041
'setuptools >= 34.4',
4142
'wcwidth >= 0.1.7',

0 commit comments

Comments
 (0)