Module peprock.subclasses
Class hierarchy helpers.
Examples
>>> sorted(get(int), key=lambda t: t.__name__) # doctest: +SKIP
[<enum 'IntEnum'>, <enum 'IntFlag'>, <class 'sre_constants._NamedIntConstant'>, <class 'bool'>]
>>> get_by_name(int, name="bool")
<class 'bool'>
>>> len(get(object)) # doctest: +SKIP
280
Expand source code
"""Class hierarchy helpers.
Examples
--------
>>> sorted(get(int), key=lambda t: t.__name__) # doctest: +SKIP
[<enum 'IntEnum'>, <enum 'IntFlag'>, <class 'sre_constants._NamedIntConstant'>, <class 'bool'>]
>>> get_by_name(int, name="bool")
<class 'bool'>
>>> len(get(object)) # doctest: +SKIP
280
"""
from __future__ import annotations
import inspect
import typing
# noinspection PyProtectedMember
from peprock._version import __version__
if typing.TYPE_CHECKING:
T_co = typing.TypeVar("T_co", covariant=True)
def get(
base_class: type[T_co],
*,
exclude_abstract: bool = False,
recursive: bool = False,
) -> set[type[T_co]]:
"""Identify subclasses of base_class and return a set."""
subclasses: set[type[T_co]] = set()
for subclass in base_class.__subclasses__():
if recursive:
subclasses |= get(
subclass,
exclude_abstract=exclude_abstract,
recursive=recursive,
)
if exclude_abstract and inspect.isabstract(subclass):
continue
subclasses.add(subclass)
return subclasses
def get_by_name(
base_class: type[T_co],
name: str,
*,
recursive: bool = False,
) -> type[T_co] | None:
"""Identify subclass of base_class with given name."""
for subclass in base_class.__subclasses__():
if subclass.__name__ == name:
return subclass
if recursive and (
subclass_ := get_by_name(
base_class=subclass,
name=name,
recursive=recursive,
)
):
return subclass_
return None
__all__ = [
"__version__",
"get",
"get_by_name",
]
Functions
def get(base_class: type[T_co], *, exclude_abstract: bool = False, recursive: bool = False) ‑> set[type[T_co]]
-
Identify subclasses of base_class and return a set.
Expand source code
def get( base_class: type[T_co], *, exclude_abstract: bool = False, recursive: bool = False, ) -> set[type[T_co]]: """Identify subclasses of base_class and return a set.""" subclasses: set[type[T_co]] = set() for subclass in base_class.__subclasses__(): if recursive: subclasses |= get( subclass, exclude_abstract=exclude_abstract, recursive=recursive, ) if exclude_abstract and inspect.isabstract(subclass): continue subclasses.add(subclass) return subclasses
def get_by_name(base_class: type[T_co], name: str, *, recursive: bool = False) ‑> type[T_co] | None
-
Identify subclass of base_class with given name.
Expand source code
def get_by_name( base_class: type[T_co], name: str, *, recursive: bool = False, ) -> type[T_co] | None: """Identify subclass of base_class with given name.""" for subclass in base_class.__subclasses__(): if subclass.__name__ == name: return subclass if recursive and ( subclass_ := get_by_name( base_class=subclass, name=name, recursive=recursive, ) ): return subclass_ return None