| from __future__ import annotations |
| |
| from typing import Collection |
| |
| |
| class TOMLKitError(Exception): |
| pass |
| |
| |
| class ParseError(ValueError, TOMLKitError): |
| """ |
| This error occurs when the parser encounters a syntax error |
| in the TOML being parsed. The error references the line and |
| location within the line where the error was encountered. |
| """ |
| |
| def __init__(self, line: int, col: int, message: str | None = None) -> None: |
| self._line = line |
| self._col = col |
| |
| if message is None: |
| message = "TOML parse error" |
| |
| super().__init__(f"{message} at line {self._line} col {self._col}") |
| |
| @property |
| def line(self): |
| return self._line |
| |
| @property |
| def col(self): |
| return self._col |
| |
| |
| class MixedArrayTypesError(ParseError): |
| """ |
| An array was found that had two or more element types. |
| """ |
| |
| def __init__(self, line: int, col: int) -> None: |
| message = "Mixed types found in array" |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class InvalidNumberError(ParseError): |
| """ |
| A numeric field was improperly specified. |
| """ |
| |
| def __init__(self, line: int, col: int) -> None: |
| message = "Invalid number" |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class InvalidDateTimeError(ParseError): |
| """ |
| A datetime field was improperly specified. |
| """ |
| |
| def __init__(self, line: int, col: int) -> None: |
| message = "Invalid datetime" |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class InvalidDateError(ParseError): |
| """ |
| A date field was improperly specified. |
| """ |
| |
| def __init__(self, line: int, col: int) -> None: |
| message = "Invalid date" |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class InvalidTimeError(ParseError): |
| """ |
| A date field was improperly specified. |
| """ |
| |
| def __init__(self, line: int, col: int) -> None: |
| message = "Invalid time" |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class InvalidNumberOrDateError(ParseError): |
| """ |
| A numeric or date field was improperly specified. |
| """ |
| |
| def __init__(self, line: int, col: int) -> None: |
| message = "Invalid number or date format" |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class InvalidUnicodeValueError(ParseError): |
| """ |
| A unicode code was improperly specified. |
| """ |
| |
| def __init__(self, line: int, col: int) -> None: |
| message = "Invalid unicode value" |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class UnexpectedCharError(ParseError): |
| """ |
| An unexpected character was found during parsing. |
| """ |
| |
| def __init__(self, line: int, col: int, char: str) -> None: |
| message = f"Unexpected character: {char!r}" |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class EmptyKeyError(ParseError): |
| """ |
| An empty key was found during parsing. |
| """ |
| |
| def __init__(self, line: int, col: int) -> None: |
| message = "Empty key" |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class EmptyTableNameError(ParseError): |
| """ |
| An empty table name was found during parsing. |
| """ |
| |
| def __init__(self, line: int, col: int) -> None: |
| message = "Empty table name" |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class InvalidCharInStringError(ParseError): |
| """ |
| The string being parsed contains an invalid character. |
| """ |
| |
| def __init__(self, line: int, col: int, char: str) -> None: |
| message = f"Invalid character {char!r} in string" |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class UnexpectedEofError(ParseError): |
| """ |
| The TOML being parsed ended before the end of a statement. |
| """ |
| |
| def __init__(self, line: int, col: int) -> None: |
| message = "Unexpected end of file" |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class InternalParserError(ParseError): |
| """ |
| An error that indicates a bug in the parser. |
| """ |
| |
| def __init__(self, line: int, col: int, message: str | None = None) -> None: |
| msg = "Internal parser error" |
| if message: |
| msg += f" ({message})" |
| |
| super().__init__(line, col, message=msg) |
| |
| |
| class NonExistentKey(KeyError, TOMLKitError): |
| """ |
| A non-existent key was used. |
| """ |
| |
| def __init__(self, key): |
| message = f'Key "{key}" does not exist.' |
| |
| super().__init__(message) |
| |
| |
| class KeyAlreadyPresent(TOMLKitError): |
| """ |
| An already present key was used. |
| """ |
| |
| def __init__(self, key): |
| key = getattr(key, "key", key) |
| message = f'Key "{key}" already exists.' |
| |
| super().__init__(message) |
| |
| |
| class InvalidControlChar(ParseError): |
| def __init__(self, line: int, col: int, char: int, type: str) -> None: |
| display_code = "\\u00" |
| |
| if char < 16: |
| display_code += "0" |
| |
| display_code += hex(char)[2:] |
| |
| message = ( |
| "Control characters (codes less than 0x1f and 0x7f)" |
| f" are not allowed in {type}, " |
| f"use {display_code} instead" |
| ) |
| |
| super().__init__(line, col, message=message) |
| |
| |
| class InvalidStringError(ValueError, TOMLKitError): |
| def __init__(self, value: str, invalid_sequences: Collection[str], delimiter: str): |
| repr_ = repr(value)[1:-1] |
| super().__init__( |
| f"Invalid string: {delimiter}{repr_}{delimiter}. " |
| f"The character sequences {invalid_sequences} are invalid." |
| ) |