Source code for protokolo.exceptions

# SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER <carmen@carmenbianca.eu>
#
# SPDX-License-Identifier: EUPL-1.2+

"""Exception classes."""

from operator import attrgetter
from typing import Any

from .i18n import _


[docs] class ProtokoloError(Exception): """Common exception class for all custom errors raised by the :mod:`protokolo` module. """
[docs] class DictTypeError(TypeError, ProtokoloError): """Expected a value of a different type for a given key.""" def __init__(self, *args: Any): if (args_count := len(args)) > 4: raise TypeError( _( "Function takes no more than 4 arguments ({args_count}" " given)" ).format(args_count=args_count) ) super().__init__(*args) self.key: str = self._get_item_default(args, 0) self.expected_type: type = self._get_item_default(args, 1) self.got: Any = self._get_item_default(args, 2) self.source: str = self._get_item_default(args, 3) def __str__(self) -> str: """Custom str output.""" amount = len(self.args) if amount <= 0: return super().__str__() text = self._key_text() if amount >= 2: attrs = [ attrgetter("__name__"), # str attrgetter("__args__"), # str | None attrgetter("__class__.__name__"), # "hello" ] for attr in attrs: try: name = attr(self.expected_type) # Get the nice str representation of UnionTypes. if isinstance(name, tuple): name = self.expected_type break except AttributeError: continue else: raise TypeError( _("Expected a type, got {type}").format( type=repr(self.expected_type) ) ) text += " " text += _("Expected {name}.").format(name=name) if amount >= 3: text += " " text += _("Got {value}.").format(value=repr(self.got)) if amount >= 4: text = _("{source}: {text}").format(source=self.source, text=text) return text def _key_text(self) -> str: return _("'{key}' does not have the correct type.").format(key=self.key) @staticmethod def _get_item_default( args: tuple[Any, ...], index: int, default: Any = None ) -> Any: try: return args[index] except IndexError: return default
[docs] class DictTypeListError(DictTypeError): """Like :class:`DictTypeError`, but the item is in a list (inside of a dictionary) instead of in a dictionary. """ def _key_text(self) -> str: return _( "List '{key}' contains an element with the wrong type." ).format(key=self.key)
[docs] class ProtokoloTOMLError(ProtokoloError): """An exception that pertains to ``.protokolo.toml.``"""
[docs] class AttributeNotPositiveError(ValueError, ProtokoloTOMLError): """A value in :class:`.config.SectionAttributes` is expected to be a positive integer. """
[docs] class ProtokoloTOMLNotFoundError(FileNotFoundError, ProtokoloTOMLError): """Couldn't find a ``.protokolo.toml`` file."""
[docs] class ProtokoloTOMLIsADirectoryError(IsADirectoryError, ProtokoloTOMLError): """``.protokolo.toml`` is not a file."""
[docs] class HeadingFormatError(ValueError, ProtokoloError): """Could not create heading."""