Skip to content

Exceptions

yex.exception #

YexError(*args, **kwargs) #

Bases: Exception

Something that went wrong.

Attributes:

Name Type Description
form

the message displayed to the user. This can contain variables which will be substituted from the kwargs of the constructor. It may not contain three apostrophes in a row. I would check for that, but I trust you not to be silly.

If you wrap one of these variables in t(), I will add " (which is a <whatever>)" after the value. For more information, see the _t() function in this file.

If the form attribute is not defined, the constructor will fail. This is to stop you raising exceptions of superclasses like YexParseError or YexError itself. Be specific.

Arguments to the constructor

(anything): can be referred to in curly brackets in the "form" attribute; see above

log (boolean, default False): if True, the details of the exception will be logged as a debug message. This will happen when you instantiate the exception, not when you raise it-- but that's generally at about the same time.

reason (str): if defined, this will be appended to the message with a newline between them

Source code in yex/exception.py
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def __init__(self, *args, **kwargs):
    super().__init__(self, *args)

    self.kwargs = kwargs

    if not hasattr(self, 'form'):
        raise ValueError(
                "The code tried to raise an exception "
                f"of type {self.__class__.__name__}, "
                "which has no form and therefore can't be raised. "
                "Did you intend to raise one of its subclasses?")
        return

    if 't' not in kwargs:
        kwargs['t'] = _t

    if kwargs.get('log', True):
        logger.debug("%s: %s",
                self.__class__.__name__,
                self)

mark_as_possible_rvalue(name) #

Adds a note to the message about a possible lvalue/rvalue mixup.

In TeΧ, writing the name of a variable means you want to set that variable. So when we see that, we bounce merrily along to find the value you want to write into it. (You can write an equals sign if you like, but it's optional.) This is what compiler theorists call an lvalue-- L for things which appear on the Left of assignment operators in languages like C.

The trouble is that you might just have meant to mention the variable in some other context, like as a parameter to a different command. This is known as an rvalue. Getting them confused is always easy, sometimes difficult to find, and occasionally catastrophic.

Therefore, we use this method to mark lvalues which might have been intended as rvalues.

Source code in yex/exception.py
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
def mark_as_possible_rvalue(self, name):
    """
    Adds a note to the message about a possible lvalue/rvalue mixup.

    In TeX, writing the name of a variable means you want to
    set that variable. So when we see that, we bounce merrily along
    to find the value you want to write into it. (You can write an
    equals sign if you like, but it's optional.) This is what
    compiler theorists call an lvalue-- L for things which appear
    on the Left of assignment operators in languages like C.

    The trouble is that you might just have meant to mention the
    variable in some other context, like as a parameter to a
    different command. This is known as an rvalue. Getting them
    confused is always easy, sometimes difficult to find,
    and occasionally catastrophic.

    Therefore, we use this method to mark lvalues which might
    have been intended as rvalues.
    """

    self.form = self.form or 'Something went wrong.'
    self.form += '\n\n'
    self.form += (
            f'This happened while I was trying '
            f'to find a value to write into {name}. '
            f"It's possible that you intended to *read* "
            f'the value of {name} instead.'
            )