quizcomp.model.errors

 1import typing
 2
 3import edq.util.json
 4
 5class ContextObject(typing.Protocol):
 6    """
 7    Any object that can provide context to errors.
 8    """
 9
10    base_dir: str
11    """ The base directory used when processing something the lead to an error. """
12
13    source_path: typing.Union[str, None]
14    """ The path being processed when an error occurred. """
15
16class QuizValidationError(ValueError):
17    """ An error that comes up when validating a quiz element. """
18
19    def __init__(self,
20            message: str,
21            context: typing.Union[ContextObject, None] = None,
22            base_dir: typing.Union[str, None] = None,
23            **kwargs: typing.Any) -> None:
24        self.context: typing.Union[ContextObject, None] = context
25        """ The context that this error occurred within. """
26
27        self.base_dir: typing.Union[str, None] = base_dir
28        """ Context for where the error came from. """
29
30        extra_info = {}
31
32        if ((self.context is not None) and (self.context.base_dir is not None)):
33            extra_info['base_dir'] = self.context.base_dir
34
35        if ((self.context is not None) and (self.context.source_path is not None)):
36            extra_info['source_path'] = self.context.source_path
37
38        if (self.base_dir is not None):
39            extra_info['base_dir'] = self.base_dir
40
41        if (len(extra_info) > 0):
42            message = f"{message} (Additional Context: {edq.util.json.dumps(extra_info)})"
43
44        super().__init__(message)
45
46class QuestionValidationError(QuizValidationError):
47    """ An error that comes up when validating a question. """
48
49    def __init__(self, message: str, **kwargs: typing.Any) -> None:
50        super().__init__(message, **kwargs)
51
52def check_type(
53        value: typing.Any,
54        expected_type: typing.Type,
55        label: str,
56        context: typing.Union[ContextObject, None] = None,
57        base_dir: typing.Union[str, None] = None,
58        ) -> None:
59    """ Check that the given value has the expected type. """
60
61    if (isinstance(value, expected_type)):
62        return
63
64    raise QuestionValidationError(
65            f"{label} must be of type '{expected_type}', found '{value}' of type ({type(value)}).",
66            context = context,
67            base_dir = base_dir)
class ContextObject(typing.Protocol):
 6class ContextObject(typing.Protocol):
 7    """
 8    Any object that can provide context to errors.
 9    """
10
11    base_dir: str
12    """ The base directory used when processing something the lead to an error. """
13
14    source_path: typing.Union[str, None]
15    """ The path being processed when an error occurred. """

Any object that can provide context to errors.

ContextObject(*args, **kwargs)
1953def _no_init_or_replace_init(self, *args, **kwargs):
1954    cls = type(self)
1955
1956    if cls._is_protocol:
1957        raise TypeError('Protocols cannot be instantiated')
1958
1959    # Already using a custom `__init__`. No need to calculate correct
1960    # `__init__` to call. This can lead to RecursionError. See bpo-45121.
1961    if cls.__init__ is not _no_init_or_replace_init:
1962        return
1963
1964    # Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`.
1965    # The first instantiation of the subclass will call `_no_init_or_replace_init` which
1966    # searches for a proper new `__init__` in the MRO. The new `__init__`
1967    # replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent
1968    # instantiation of the protocol subclass will thus use the new
1969    # `__init__` and no longer call `_no_init_or_replace_init`.
1970    for base in cls.__mro__:
1971        init = base.__dict__.get('__init__', _no_init_or_replace_init)
1972        if init is not _no_init_or_replace_init:
1973            cls.__init__ = init
1974            break
1975    else:
1976        # should not happen
1977        cls.__init__ = object.__init__
1978
1979    cls.__init__(self, *args, **kwargs)
base_dir: str

The base directory used when processing something the lead to an error.

source_path: Optional[str]

The path being processed when an error occurred.

class QuizValidationError(builtins.ValueError):
17class QuizValidationError(ValueError):
18    """ An error that comes up when validating a quiz element. """
19
20    def __init__(self,
21            message: str,
22            context: typing.Union[ContextObject, None] = None,
23            base_dir: typing.Union[str, None] = None,
24            **kwargs: typing.Any) -> None:
25        self.context: typing.Union[ContextObject, None] = context
26        """ The context that this error occurred within. """
27
28        self.base_dir: typing.Union[str, None] = base_dir
29        """ Context for where the error came from. """
30
31        extra_info = {}
32
33        if ((self.context is not None) and (self.context.base_dir is not None)):
34            extra_info['base_dir'] = self.context.base_dir
35
36        if ((self.context is not None) and (self.context.source_path is not None)):
37            extra_info['source_path'] = self.context.source_path
38
39        if (self.base_dir is not None):
40            extra_info['base_dir'] = self.base_dir
41
42        if (len(extra_info) > 0):
43            message = f"{message} (Additional Context: {edq.util.json.dumps(extra_info)})"
44
45        super().__init__(message)

An error that comes up when validating a quiz element.

QuizValidationError( message: str, context: Optional[ContextObject] = None, base_dir: Optional[str] = None, **kwargs: Any)
20    def __init__(self,
21            message: str,
22            context: typing.Union[ContextObject, None] = None,
23            base_dir: typing.Union[str, None] = None,
24            **kwargs: typing.Any) -> None:
25        self.context: typing.Union[ContextObject, None] = context
26        """ The context that this error occurred within. """
27
28        self.base_dir: typing.Union[str, None] = base_dir
29        """ Context for where the error came from. """
30
31        extra_info = {}
32
33        if ((self.context is not None) and (self.context.base_dir is not None)):
34            extra_info['base_dir'] = self.context.base_dir
35
36        if ((self.context is not None) and (self.context.source_path is not None)):
37            extra_info['source_path'] = self.context.source_path
38
39        if (self.base_dir is not None):
40            extra_info['base_dir'] = self.base_dir
41
42        if (len(extra_info) > 0):
43            message = f"{message} (Additional Context: {edq.util.json.dumps(extra_info)})"
44
45        super().__init__(message)
context: Optional[ContextObject]

The context that this error occurred within.

base_dir: Optional[str]

Context for where the error came from.

class QuestionValidationError(QuizValidationError):
47class QuestionValidationError(QuizValidationError):
48    """ An error that comes up when validating a question. """
49
50    def __init__(self, message: str, **kwargs: typing.Any) -> None:
51        super().__init__(message, **kwargs)

An error that comes up when validating a question.

QuestionValidationError(message: str, **kwargs: Any)
50    def __init__(self, message: str, **kwargs: typing.Any) -> None:
51        super().__init__(message, **kwargs)
def check_type( value: Any, expected_type: Type, label: str, context: Optional[ContextObject] = None, base_dir: Optional[str] = None) -> None:
53def check_type(
54        value: typing.Any,
55        expected_type: typing.Type,
56        label: str,
57        context: typing.Union[ContextObject, None] = None,
58        base_dir: typing.Union[str, None] = None,
59        ) -> None:
60    """ Check that the given value has the expected type. """
61
62    if (isinstance(value, expected_type)):
63        return
64
65    raise QuestionValidationError(
66            f"{label} must be of type '{expected_type}', found '{value}' of type ({type(value)}).",
67            context = context,
68            base_dir = base_dir)

Check that the given value has the expected type.