Source code for pytools.data.taxonomy._category

"""
Implementation of ``MyClass``.
"""

from __future__ import annotations

import functools
import logging
from abc import ABCMeta, abstractmethod
from collections.abc import Iterable
from typing import Any, cast, final

from typing_extensions import Self

from pytools.api import as_tuple

log = logging.getLogger(__name__)

__all__ = [
    "Category",
]


#
# Classes
#


[docs] @functools.total_ordering class Category(metaclass=ABCMeta): """ A category. Implements the "composite" pattern in one single abstract class. """ _children: tuple[Category, ...] def __init__(self, *, children: Self | Iterable[Self] | None = None) -> None: """ :param children: the subcategories of the category (optional) """ self._children = as_tuple( children, element_type=type(self), arg_name="subcategories", optional=True ) @property @abstractmethod def name(self) -> str: """ The name of the category. """ @property @final def children(self) -> tuple[Self, ...]: """ The subcategories of this category. """ return cast(tuple[Self, ...], self._children) @property @final def has_children(self) -> bool: """ ``True`` if this category is a group, ``False`` otherwise. """ return bool(self._children)
[docs] def traverse(self) -> Iterable[Self]: """ Yield this category and all its subcategories, recursively and depth-first. :return: an iterator that yields this category and all its subcategories """ yield self for child in self.children: yield from child.traverse()
def __eq__(self, other: Any) -> bool: return ( type(self) is type(other) and self.name == other.name and self.children == other.children ) def __lt__(self, other: Category) -> bool: return self.name < other.name def __hash__(self) -> int: return hash(self.name) def __repr__(self) -> str: return repr(self.name) def __str__(self) -> str: return self.name