Module scrolls.errors

Errors not dependent on any specific Scrolls types.

Typically, you won't need to instantiate any of these yourself. The base exception for all Scrolls errors is ScrollError. Any error that occurs while validating script syntax or interpreting scripts will inherit from PositionalError.

Expand source code
"""
Errors not dependent on any specific Scrolls types.

Typically, you won't need to instantiate any of these yourself. The base exception
for _all_ Scrolls errors is `ScrollError`. Any error that occurs while validating
script syntax or interpreting scripts will inherit from `PositionalError`.
"""

import functools
import math

__all__ = (
    "format_positional_error",
    "ScrollError",
    "PositionalError"
)


@functools.lru_cache(128)
def format_positional_error(
    line: int,
    pos: int,
    string: str,
    message: str,
    prior_lines: int = 3
) -> str:
    """Format a positional error generated by Scrolls.

    Args:
        line: The line the error was generated on.
        pos: The character the error was generated on.
        string: The script that generated the error.
        message: The message associated with the error.

        prior_lines: The number of lines that should be printed before the line
            the error occurred on. The line containing the error will always
            be printed.

    Returns:
        The formatted error message.

        For example:
        ```text
        ...
        1 print "World"
        2 print "Foo"
        3 print "Bar"
        4 print "bad string
                           ^
        line 4 - Unexpected EOF while parsing string literal.
        ```

        If there are more than `prior_lines` lines before the error, `...` will be
        prepended to the output.
    """
    zfill = max(1, int(math.log10(len(string))))
    lines = [f"{n:0{zfill}} {l}" for n, l in enumerate(string.splitlines())]

    printed_lines = lines[max(0, line - prior_lines): line + 1]

    output_lines = [
        *(["..."] if line - prior_lines >= 1 else []),
        *printed_lines,
        " "*(pos + 1 + zfill) + "^",
        f"line {line}: {message}"
    ]

    return "\n".join(output_lines)


class ScrollError(Exception):
    """Base class for all Scrolls-related errors."""
    pass


class PositionalError(ScrollError):
    """Generic error that happened somewhere in a script.

    Any error in tokenizing, parsing, or interpreting should inherit from this.
    Typically you'll never need to instantiate one of these yourself, just catch it
    and call `str` on it. This will return a formatted error message pointing to
    where the error happened. See `format_positional_error` for more details.

    Example usage:

    ```
    try:
        some_scrolls_function(...)
    except PositionalError as e:
        print("error:")
        print(str(e))
    ```

    Note that this will apply to any error that inherits from `PositionalError` as well.
    If you want to do your own formatting, you can use the instance variables below to
    generate your own messages.
    """
    def __init__(
        self,
        line: int,
        pos: int,
        string: str,
        message: str
    ):
        self.line = line
        """The line the error occurred on."""

        self.pos = pos
        """The character along `line` the error occurred at."""

        self.string = string
        """The string that triggered the error. In all normal cases, this is a script."""

        self.message = message
        """The message associated with this error."""

    def __str__(self) -> str:
        """
        Return a formatted error string pointing out in the script where this error
        happened.
        """
        return format_positional_error(
            self.line,
            self.pos,
            self.string,
            self.message
        )

Functions

def format_positional_error(line: int, pos: int, string: str, message: str, prior_lines: int = 3) ‑> str

Format a positional error generated by Scrolls.

Args

line
The line the error was generated on.
pos
The character the error was generated on.
string
The script that generated the error.
message
The message associated with the error.
prior_lines
The number of lines that should be printed before the line the error occurred on. The line containing the error will always be printed.

Returns

The formatted error message.

For example:

...
1 print "World"
2 print "Foo"
3 print "Bar"
4 print "bad string
                   ^
line 4 - Unexpected EOF while parsing string literal.

If there are more than prior_lines lines before the error, will be prepended to the output.

Expand source code
@functools.lru_cache(128)
def format_positional_error(
    line: int,
    pos: int,
    string: str,
    message: str,
    prior_lines: int = 3
) -> str:
    """Format a positional error generated by Scrolls.

    Args:
        line: The line the error was generated on.
        pos: The character the error was generated on.
        string: The script that generated the error.
        message: The message associated with the error.

        prior_lines: The number of lines that should be printed before the line
            the error occurred on. The line containing the error will always
            be printed.

    Returns:
        The formatted error message.

        For example:
        ```text
        ...
        1 print "World"
        2 print "Foo"
        3 print "Bar"
        4 print "bad string
                           ^
        line 4 - Unexpected EOF while parsing string literal.
        ```

        If there are more than `prior_lines` lines before the error, `...` will be
        prepended to the output.
    """
    zfill = max(1, int(math.log10(len(string))))
    lines = [f"{n:0{zfill}} {l}" for n, l in enumerate(string.splitlines())]

    printed_lines = lines[max(0, line - prior_lines): line + 1]

    output_lines = [
        *(["..."] if line - prior_lines >= 1 else []),
        *printed_lines,
        " "*(pos + 1 + zfill) + "^",
        f"line {line}: {message}"
    ]

    return "\n".join(output_lines)

Classes

class PositionalError (line: int, pos: int, string: str, message: str)

Generic error that happened somewhere in a script.

Any error in tokenizing, parsing, or interpreting should inherit from this. Typically you'll never need to instantiate one of these yourself, just catch it and call str on it. This will return a formatted error message pointing to where the error happened. See format_positional_error() for more details.

Example usage:

try:
    some_scrolls_function(...)
except PositionalError as e:
    print("error:")
    print(str(e))

Note that this will apply to any error that inherits from PositionalError as well. If you want to do your own formatting, you can use the instance variables below to generate your own messages.

Expand source code
class PositionalError(ScrollError):
    """Generic error that happened somewhere in a script.

    Any error in tokenizing, parsing, or interpreting should inherit from this.
    Typically you'll never need to instantiate one of these yourself, just catch it
    and call `str` on it. This will return a formatted error message pointing to
    where the error happened. See `format_positional_error` for more details.

    Example usage:

    ```
    try:
        some_scrolls_function(...)
    except PositionalError as e:
        print("error:")
        print(str(e))
    ```

    Note that this will apply to any error that inherits from `PositionalError` as well.
    If you want to do your own formatting, you can use the instance variables below to
    generate your own messages.
    """
    def __init__(
        self,
        line: int,
        pos: int,
        string: str,
        message: str
    ):
        self.line = line
        """The line the error occurred on."""

        self.pos = pos
        """The character along `line` the error occurred at."""

        self.string = string
        """The string that triggered the error. In all normal cases, this is a script."""

        self.message = message
        """The message associated with this error."""

    def __str__(self) -> str:
        """
        Return a formatted error string pointing out in the script where this error
        happened.
        """
        return format_positional_error(
            self.line,
            self.pos,
            self.string,
            self.message
        )

Ancestors

  • ScrollError
  • builtins.Exception
  • builtins.BaseException

Subclasses

Instance variables

var line

The line the error occurred on.

var message

The message associated with this error.

var pos

The character along line the error occurred at.

var string

The string that triggered the error. In all normal cases, this is a script.

class ScrollError (*args, **kwargs)

Base class for all Scrolls-related errors.

Expand source code
class ScrollError(Exception):
    """Base class for all Scrolls-related errors."""
    pass

Ancestors

  • builtins.Exception
  • builtins.BaseException

Subclasses