Replace pkg_resources with importlib_metadata

This is using the new "selection interface" ( by calling `entry_points` with
the `group` parameter) that is being introduced in `importlib.metadata` of
Python 3.10 (currently in alpha). While the backport (`importlib_metadata`)
introduced the same change in version 3.6, various improvements have been made
up through the current release (3.10). Therefore we require
`importlib_metadata>=3.10` for all supported versions of Python (3.6-3.9).
This commit is contained in:
Waylan Limberg
2021-04-06 11:51:45 -04:00
committed by GitHub
parent 21b3d1d431
commit ec64ab40a5
7 changed files with 36 additions and 34 deletions

View File

@@ -4,8 +4,8 @@ Implements the plugin API for MkDocs.
"""
import pkg_resources
import logging
import importlib_metadata
from collections import OrderedDict
from mkdocs.config.base import Config
@@ -22,9 +22,9 @@ EVENTS = (
def get_plugins():
""" Return a dict of all installed Plugins by name. """
""" Return a dict of all installed Plugins as {name: EntryPoint}. """
plugins = pkg_resources.iter_entry_points(group='mkdocs.plugins')
plugins = importlib_metadata.entry_points(group='mkdocs.plugins')
return {plugin.name: plugin for plugin in plugins}

View File

@@ -210,7 +210,7 @@ MockEntryPoint = mock.Mock()
MockEntryPoint.configure_mock(**{'name': 'sample', 'load.return_value': DummyPlugin})
@mock.patch('pkg_resources.iter_entry_points', return_value=[MockEntryPoint])
@mock.patch('importlib_metadata.entry_points', return_value=[MockEntryPoint])
class TestPluginConfig(unittest.TestCase):
def test_plugin_config_without_options(self, mock_class):

View File

@@ -251,17 +251,17 @@ class UtilsTests(unittest.TestCase):
sorted(utils.get_theme_names()),
['mkdocs', 'readthedocs'])
@mock.patch('pkg_resources.iter_entry_points', autospec=True)
@mock.patch('importlib_metadata.entry_points', autospec=True)
def test_get_theme_dir(self, mock_iter):
path = 'some/path'
theme = mock.Mock()
theme.name = 'mkdocs2'
theme.dist.key = 'mkdocs2'
theme.dist.name = 'mkdocs2'
theme.load().__file__ = os.path.join(path, '__init__.py')
mock_iter.return_value = iter([theme])
mock_iter.return_value = [theme]
self.assertEqual(utils.get_theme_dir(theme.name), os.path.abspath(path))
@@ -269,53 +269,51 @@ class UtilsTests(unittest.TestCase):
self.assertRaises(KeyError, utils.get_theme_dir, 'nonexistanttheme')
@mock.patch('pkg_resources.iter_entry_points', autospec=True)
@mock.patch('importlib_metadata.entry_points', autospec=True)
def test_get_theme_dir_importerror(self, mock_iter):
theme = mock.Mock()
theme.name = 'mkdocs2'
theme.dist.key = 'mkdocs2'
theme.dist.name = 'mkdocs2'
theme.load.side_effect = ImportError()
mock_iter.return_value = iter([theme])
mock_iter.return_value = [theme]
self.assertRaises(ImportError, utils.get_theme_dir, theme.name)
@mock.patch('pkg_resources.iter_entry_points', autospec=True)
@mock.patch('importlib_metadata.entry_points', autospec=True)
def test_get_themes_warning(self, mock_iter):
theme1 = mock.Mock()
theme1.name = 'mkdocs2'
theme1.dist.key = 'mkdocs2'
theme1.dist.name = 'mkdocs2'
theme1.load().__file__ = "some/path1"
theme2 = mock.Mock()
theme2.name = 'mkdocs2'
theme2.dist.key = 'mkdocs3'
theme2.dist.name = 'mkdocs3'
theme2.load().__file__ = "some/path2"
mock_iter.return_value = iter([theme1, theme2])
mock_iter.return_value = [theme1, theme2]
self.assertEqual(
sorted(utils.get_theme_names()),
sorted(['mkdocs2', ]))
@mock.patch('pkg_resources.iter_entry_points', autospec=True)
@mock.patch('pkg_resources.get_entry_map', autospec=True)
def test_get_themes_error(self, mock_get, mock_iter):
@mock.patch('importlib_metadata.entry_points', autospec=True)
def test_get_themes_error(self, mock_iter):
theme1 = mock.Mock()
theme1.name = 'mkdocs'
theme1.dist.key = 'mkdocs'
theme1.dist.name = 'mkdocs'
theme1.load().__file__ = "some/path1"
theme2 = mock.Mock()
theme2.name = 'mkdocs'
theme2.dist.key = 'mkdocs2'
theme2.dist.name = 'mkdocs2'
theme2.load().__file__ = "some/path2"
mock_iter.return_value = iter([theme1, theme2])
mock_get.return_value = {'mkdocs': theme1, }
mock_iter.return_value = [theme1, theme2]
self.assertRaises(exceptions.ConfigurationError, utils.get_theme_names)

View File

@@ -8,13 +8,13 @@ and structure of the site and pages in the site.
import logging
import os
import pkg_resources
import shutil
import re
import yaml
import fnmatch
import posixpath
import functools
import importlib_metadata
from datetime import datetime, timezone
from urllib.parse import urlparse
from yaml_env_tag import construct_env_tag
@@ -316,23 +316,24 @@ def get_theme_dir(name):
def get_themes():
""" Return a dict of all installed themes as (name, entry point) pairs. """
""" Return a dict of all installed themes as {name: EntryPoint}. """
themes = {}
builtins = pkg_resources.get_entry_map(dist='mkdocs', group='mkdocs.themes')
eps = importlib_metadata.entry_points(group='mkdocs.themes')
builtins = [ep.name for ep in eps if ep.dist.name == 'mkdocs']
for theme in pkg_resources.iter_entry_points(group='mkdocs.themes'):
for theme in eps:
if theme.name in builtins and theme.dist.key != 'mkdocs':
if theme.name in builtins and theme.dist.name != 'mkdocs':
raise exceptions.ConfigurationError(
"The theme {} is a builtin theme but {} provides a theme "
"with the same name".format(theme.name, theme.dist.key))
f"The theme '{theme.name}' is a builtin theme but the package '{theme.dist.name}' "
"attempts to provide a theme with the same name."
)
elif theme.name in themes:
multiple_packages = [themes[theme.name].dist.key, theme.dist.key]
log.warning("The theme %s is provided by the Python packages "
"'%s'. The one in %s will be used.",
theme.name, ','.join(multiple_packages), theme.dist.key)
log.warning(
f"A theme named '{theme.name}' is provided by the Python packages '{theme.dist.name}'"
f"and '{themes[theme.name].dist.name}'. The one in '{theme.dist.name}' will be used."
)
themes[theme.name] = theme

View File

@@ -8,3 +8,4 @@ mdx_gh_links==0.2
ghp-import==1.0
pyyaml_env_tag==0.1
mkdocs-redirects==1.0.1
importlib_metadata==3.10.0

View File

@@ -8,3 +8,4 @@ mdx_gh_links>=0.2
ghp-import>=1.0
pyyaml_env_tag>=0.1
mkdocs-redirects>=1.0.1
importlib_metadata>=3.10

View File

@@ -59,7 +59,8 @@ setup(
'PyYAML>=3.10',
'tornado>=5.0',
'ghp-import>=1.0',
'pyyaml_env_tag>=0.1'
'pyyaml_env_tag>=0.1',
'importlib_metadata>=3.10'
],
python_requires='>=3.6',
entry_points={