diff --git a/src/docc/__init__.py b/src/docc/__init__.py index 4c9a33d..fa8699b 100644 --- a/src/docc/__init__.py +++ b/src/docc/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2025 Ethereum Foundation +# Copyright (C) 2022-2026 Ethereum Foundation # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,5 +17,5 @@ The documentation compiler. """ -__version__ = "0.4.0" +__version__ = "0.4.1" "Current version of docc" diff --git a/src/docc/plugins/html/__init__.py b/src/docc/plugins/html/__init__.py index f9b8c41..4e7b694 100644 --- a/src/docc/plugins/html/__init__.py +++ b/src/docc/plugins/html/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2022-2023 Ethereum Foundation +# Copyright (C) 2022-2026 Ethereum Foundation # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -62,7 +62,7 @@ Visitor, ) from docc.plugins import references -from docc.plugins.loader import PluginError +from docc.plugins.loader import PluginError, entry_points_by_group from docc.plugins.references import Index, ReferenceError from docc.plugins.resources import ResourceSource from docc.plugins.search import Search @@ -71,9 +71,9 @@ from docc.transform import Transform if sys.version_info < (3, 10): - from importlib_metadata import EntryPoint, entry_points + from importlib_metadata import EntryPoint else: - from importlib.metadata import EntryPoint, entry_points + from importlib.metadata import EntryPoint RenderResult = Optional[Union["HTMLTag", "HTMLRoot"]] @@ -425,8 +425,7 @@ class HTMLVisitor(Visitor): def __init__(self, context: Context) -> None: # Discover render functions. - found = entry_points(group="docc.plugins.html") - self.entry_points = {entry.name: entry for entry in found} + self.entry_points = entry_points_by_group("docc.plugins.html") self.root = HTMLRoot(context) self.stack = [self.root] self.renderers = {} diff --git a/src/docc/plugins/loader.py b/src/docc/plugins/loader.py index 98e8c7f..466aa5a 100644 --- a/src/docc/plugins/loader.py +++ b/src/docc/plugins/loader.py @@ -18,6 +18,7 @@ """ import sys +from functools import cache from inspect import isabstract from typing import Callable, Dict, Type, TypeVar @@ -33,6 +34,18 @@ class PluginError(Exception): """ +@cache +def entry_points_by_group(group: str) -> Dict[str, EntryPoint]: + """ + Find [entry points][p] belonging to `group`, permanently caching the + result. + + [p]: https://packaging.python.org/en/latest/specifications/entry-points/ + """ + found = entry_points(group=group) + return {entry.name: entry for entry in found} + + L = TypeVar("L") @@ -47,8 +60,7 @@ def __init__(self) -> None: """ Create an instance and populate it with the discovered plugins. """ - found = set(entry_points(group="docc.plugins")) - self.entry_points = {entry.name: entry for entry in found} + self.entry_points = entry_points_by_group("docc.plugins") def load(self, base: Type[L], name: str) -> Callable[..., L]: """