Source code for httk.core.register.members

"""The project-member-kind registry: which module owns which member kind."""

#
#    The high-throughput toolkit (httk)
#    Copyright (C) 2012-2024 the httk AUTHORS
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation; either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
from collections.abc import Callable
from typing import Any

from ._base import PluginRegistry, resolve_callable

#: Registered member kinds, keyed by kind name. A registered handler is a lazy
#: ``"module:callable"`` reference (or a callable) that, when called with no
#: arguments, yields an object implementing
#: :class:`httk.core.project.members.ProjectMemberHandler`.
[docs] project_member_kinds = PluginRegistry()
[docs] def register_project_member_kind(kind: str, handler: str | Callable[..., Any]) -> None: """Register the handler that implements one project-member *kind*. A *handler* is either a callable or a lazy ``"module:callable"`` reference that takes no arguments and returns an object implementing :class:`~httk.core.project.members.ProjectMemberHandler`. Registering a kind is how an installed module teaches the core seal, manifest, and repair verbs to delegate that member's internals to it. This mirrors :func:`~httk.core.register.entries.register_entry_provider`. :param kind: The member kind name to register. :param handler: The handler callable or lazy ``"module:callable"`` reference. """ project_member_kinds.register(key=kind, handler=handler, name=kind)
[docs] def known_project_member_kinds() -> list[str]: """Return the registered member-kind names. :return: Registered member-kind names in sorted order. """ return project_member_kinds.keys()
[docs] def project_member_handler(kind: str) -> Any: """Return the handler object for one project-member *kind*. The registered reference is resolved lazily and called with no arguments to build the handler, so a module contributes a kind without core importing it until a member of that kind is actually acted on. :param kind: The member kind whose handler to resolve. :return: The handler object implementing the member protocol. :raises LookupError: If no module has registered a handler for the kind. """ spec = project_member_kinds.get(kind) if spec is None: known = ", ".join(project_member_kinds.keys()) or "(none)" raise LookupError( f"no handler is registered for project member kind {kind!r}; " f"install the module that provides it. Known kinds: {known}" ) return resolve_callable(spec.handler)()