diff --git a/altair/utils/plugin_registry.py b/altair/utils/plugin_registry.py index b03cea76f3..8b33c2538a 100644 --- a/altair/utils/plugin_registry.py +++ b/altair/utils/plugin_registry.py @@ -1,13 +1,26 @@ from typing import Any, Dict, List, Optional, Generic, TypeVar, cast from types import TracebackType -import entrypoints +try: + from importlib.metadata import entry_points +except ImportError: + from importlib_metadata import entry_points + from toolz import curry PluginType = TypeVar("PluginType") +class NoSuchEntryPoint(Exception): + def __init__(self, group, name): + self.group = group + self.name = name + + def __str__(self): + return f"No {self.name!r} entry point found in group {self.group!r}" + + class PluginEnabler(object): """Context manager for enabling plugins @@ -108,9 +121,7 @@ def register(self, name: str, value: Optional[PluginType]) -> Optional[PluginTyp def names(self) -> List[str]: """List the names of the registered and entry points plugins.""" exts = list(self._plugins.keys()) - more_exts = [ - ep.name for ep in entrypoints.get_group_all(self.entry_point_group) - ] + more_exts = [ep.name for ep in entry_points(group=self.entry_point_group)] exts.extend(more_exts) return sorted(set(exts)) @@ -139,12 +150,12 @@ def _set_state(self, state: Dict[str, Any]) -> None: def _enable(self, name: str, **options) -> None: if name not in self._plugins: try: - ep = entrypoints.get_single(self.entry_point_group, name) - except entrypoints.NoSuchEntryPoint: + (ep,) = entry_points(group=self.entry_point_group, name=name) + except ValueError: if name in self.entrypoint_err_messages: raise ValueError(self.entrypoint_err_messages[name]) else: - raise + raise NoSuchEntryPoint(self.entry_point_group, name) value = cast(PluginType, ep.load()) self.register(name, value) self._active_name = name diff --git a/doc/getting_started/installation.rst b/doc/getting_started/installation.rst index 1e31f2e6ca..7b359405ad 100644 --- a/doc/getting_started/installation.rst +++ b/doc/getting_started/installation.rst @@ -24,7 +24,7 @@ Altair has the following dependencies, all of which are installed automatically with the above installation commands: - python 3.6 or newer -- entrypoints_ +- importlib_metadata_ (python<3.8) - jsonschema_ - NumPy_ - Pandas_ @@ -74,7 +74,7 @@ development version directly from GitHub using: .. _Zeppelin: https://zeppelin.apache.org/ .. _IPython: https://github.com/ipython/ipython -.. _entrypoints: https://github.com/takluyver/entrypoints +.. _importlib_metadata: https://github.com/python/importlib_metadata .. _jsonschema: https://github.com/Julian/jsonschema .. _NumPy: http://www.numpy.org/ .. _Pandas: http://pandas.pydata.org diff --git a/doc/user_guide/display_frontends.rst b/doc/user_guide/display_frontends.rst index 4d0173e9d0..284b4cb176 100644 --- a/doc/user_guide/display_frontends.rst +++ b/doc/user_guide/display_frontends.rst @@ -40,7 +40,7 @@ Some of the built-in renderers are: newer versions of JupyterLab_, nteract_, and `VSCode-Python`_, but does not work with the `Jupyter Notebook`_, or with tools like nbviewer_ and nbconvert_. -Other renderers can be installed by third-party packages via Python's entrypoints_ system; +Other renderers can be installed by third-party packages via Python's entrypoints system; see :ref:`renderer-api`. @@ -79,7 +79,7 @@ Optionally, for offline rendering in Jupyter Notebook, you can use the notebook # Optional in Jupyter Notebook: requires an up-to-date vega nbextension. alt.renderers.enable('notebook') - + This renderer is provided by the `ipyvega`_ notebook extension. which can be installed and enabled either using pip: @@ -262,10 +262,9 @@ To register and enable a new renderer:: >>> alt.renderers.register('custom_renderer', custom_renderer) >>> alt.renderers.enable('custom_renderer') -Renderers can also be registered using the `entrypoints`_ API of Python packages. +Renderers can also be registered using the `entrypoints` API of Python packages. For an example, see `ipyvega`_. -.. _entrypoints: https://github.com/takluyver/entrypoints .. _ipyvega: https://github.com/vega/ipyvega/ .. _JupyterLab: http://jupyterlab.readthedocs.io/en/stable/ .. _nteract: https://nteract.io diff --git a/requirements.txt b/requirements.txt index c6925037fd..d6ab9d282d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -entrypoints +importlib_metadata; python_version < "3.8" jinja2 jsonschema>=3.0 numpy