# SPDX-FileCopyrightText: 2023 Carmen Bianca BAKKER <carmen@carmenbianca.eu>## SPDX-License-Identifier: EUPL-1.2+"""Exception classes."""fromoperatorimportattrgetterfromtypingimportAnyfrom.i18nimport_
[docs]classProtokoloError(Exception):"""Common exception class for all custom errors raised by the :mod:`protokolo` module. """
[docs]classDictTypeError(TypeError,ProtokoloError):"""Expected a value of a different type for a given key."""def__init__(self,*args:Any):if(args_count:=len(args))>4:raiseTypeError(_("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)ifamount<=0:returnsuper().__str__()text=self._key_text()ifamount>=2:attrs=[attrgetter("__name__"),# strattrgetter("__args__"),# str | Noneattrgetter("__class__.__name__"),# "hello"]forattrinattrs:try:name=attr(self.expected_type)# Get the nice str representation of UnionTypes.ifisinstance(name,tuple):name=self.expected_typebreakexceptAttributeError:continueelse:raiseTypeError(_("Expected a type, got {type}").format(type=repr(self.expected_type)))text+=" "text+=_("Expected {name}.").format(name=name)ifamount>=3:text+=" "text+=_("Got {value}.").format(value=repr(self.got))ifamount>=4:text=_("{source}: {text}").format(source=self.source,text=text)returntextdef_key_text(self)->str:return_("'{key}' does not have the correct type.").format(key=self.key)@staticmethoddef_get_item_default(args:tuple[Any,...],index:int,default:Any=None)->Any:try:returnargs[index]exceptIndexError:returndefault
[docs]classDictTypeListError(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]classProtokoloTOMLError(ProtokoloError):"""An exception that pertains to ``.protokolo.toml.``"""
[docs]classAttributeNotPositiveError(ValueError,ProtokoloTOMLError):"""A value in :class:`.config.SectionAttributes` is expected to be a positive integer. """
[docs]classProtokoloTOMLNotFoundError(FileNotFoundError,ProtokoloTOMLError):"""Couldn't find a ``.protokolo.toml`` file."""
[docs]classProtokoloTOMLIsADirectoryError(IsADirectoryError,ProtokoloTOMLError):"""``.protokolo.toml`` is not a file."""
[docs]classHeadingFormatError(ValueError,ProtokoloError):"""Could not create heading."""