| @@ -1,5 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | |||
| # | |||
| # mwparserfromhell documentation build configuration file, created by | |||
| # sphinx-quickstart on Tue Aug 21 20:47:26 2012. | |||
| # | |||
| @@ -11,8 +9,8 @@ | |||
| # All configuration values have a default; values that are commented out | |||
| # serve to show the default. | |||
| import sys | |||
| import os | |||
| import sys | |||
| # If extensions (or modules to document with autodoc) are in another directory, | |||
| # add these directories to sys.path here. If the directory is relative to the | |||
| @@ -0,0 +1,13 @@ | |||
| [tool.pyright] | |||
| pythonVersion = "3.9" | |||
| venvPath = "." | |||
| venv = ".venv" | |||
| [tool.ruff] | |||
| target-version = "py39" | |||
| [tool.ruff.lint] | |||
| extend-select = [ | |||
| "I", | |||
| "UP", | |||
| ] | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -30,10 +30,12 @@ Actual memory leaks typically leak very large amounts of memory (megabytes) | |||
| and scale with the number of loops. | |||
| """ | |||
| from __future__ import annotations | |||
| import sys | |||
| from locale import LC_ALL, setlocale | |||
| from multiprocessing import Process, Pipe | |||
| from multiprocessing import Pipe, Process | |||
| from os import listdir, path | |||
| import sys | |||
| import psutil | |||
| @@ -80,7 +82,7 @@ class MemoryTest: | |||
| def _load(self): | |||
| def load_file(filename): | |||
| with open(filename, "rU") as fp: | |||
| with open(filename) as fp: | |||
| text = fp.read() | |||
| name = path.split(filename)[1][: 0 - len(extension)] | |||
| self._parse_file(name, text) | |||
| @@ -109,7 +111,7 @@ class MemoryTest: | |||
| tmpl = "{0}LEAKING{1}: {2:n} bytes, {3:.2%} inc ({4:n} bytes/loop)" | |||
| sys.stdout.write(tmpl.format(Color.YELLOW, Color.RESET, d, p, bpt)) | |||
| else: | |||
| sys.stdout.write("{}OK{}".format(Color.GREEN, Color.RESET)) | |||
| sys.stdout.write(f"{Color.GREEN}OK{Color.RESET}") | |||
| def run(self): | |||
| """Run the memory test suite.""" | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -26,6 +26,8 @@ When updating this file, please also update the the C tokenizer version: | |||
| - mwparserfromhell/parser/ctokenizer/definitions.h | |||
| """ | |||
| from __future__ import annotations | |||
| __all__ = [ | |||
| "get_html_tag", | |||
| "is_parsable", | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -27,9 +27,10 @@ the name of a :class:`.Template` is a :class:`.Wikicode` object that can | |||
| contain text or more templates. | |||
| """ | |||
| from __future__ import annotations | |||
| from . import extras | |||
| from ._base import Node | |||
| from .text import Text | |||
| from .argument import Argument | |||
| from .comment import Comment | |||
| from .external_link import ExternalLink | |||
| @@ -37,6 +38,7 @@ from .heading import Heading | |||
| from .html_entity import HTMLEntity | |||
| from .tag import Tag | |||
| from .template import Template | |||
| from .text import Text | |||
| from .wikilink import Wikilink | |||
| __all__ = [ | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,7 +18,10 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from typing import TYPE_CHECKING, Any, Generator, Optional, Callable | |||
| from __future__ import annotations | |||
| from collections.abc import Generator | |||
| from typing import TYPE_CHECKING, Any, Callable | |||
| from ..string_mixin import StringMixIn | |||
| @@ -45,18 +48,18 @@ class Node(StringMixIn): | |||
| def __str__(self) -> str: | |||
| raise NotImplementedError() | |||
| def __children__(self) -> Generator["Wikicode", None, None]: | |||
| def __children__(self) -> Generator[Wikicode, None, None]: | |||
| return | |||
| # pylint: disable=unreachable | |||
| yield # pragma: no cover (this is a generator that yields nothing) | |||
| def __strip__(self, **kwargs: Any) -> Optional[str]: | |||
| def __strip__(self, **kwargs: Any) -> str | None: | |||
| return None | |||
| def __showtree__( | |||
| self, | |||
| write: Callable[[str], None], | |||
| get: Callable[["Wikicode"], None], | |||
| get: Callable[[Wikicode], None], | |||
| mark: Callable[[], None], | |||
| ) -> None: | |||
| write(str(self)) | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,11 +18,13 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| from typing import TYPE_CHECKING, Any, Generator, Optional, Callable | |||
| from collections.abc import Generator | |||
| from typing import TYPE_CHECKING, Any, Callable | |||
| from ._base import Node | |||
| from ..utils import parse_anything | |||
| from ._base import Node | |||
| if TYPE_CHECKING: | |||
| from ..wikicode import Wikicode | |||
| @@ -44,12 +46,12 @@ class Argument(Node): | |||
| return start + "|" + str(self.default) + "}}}" | |||
| return start + "}}}" | |||
| def __children__(self) -> Generator["Wikicode", None, None]: | |||
| def __children__(self) -> Generator[Wikicode, None, None]: | |||
| yield self.name | |||
| if self.default is not None: | |||
| yield self.default | |||
| def __strip__(self, **kwargs: Any) -> Optional[str]: | |||
| def __strip__(self, **kwargs: Any) -> str | None: | |||
| if self.default is not None: | |||
| return self.default.strip_code(**kwargs) | |||
| return None | |||
| @@ -57,7 +59,7 @@ class Argument(Node): | |||
| def __showtree__( | |||
| self, | |||
| write: Callable[[str], None], | |||
| get: Callable[["Wikicode"], None], | |||
| get: Callable[[Wikicode], None], | |||
| mark: Callable[[], None], | |||
| ) -> None: | |||
| write("{{{") | |||
| @@ -69,7 +71,7 @@ class Argument(Node): | |||
| write("}}}") | |||
| @property | |||
| def name(self) -> "Wikicode": | |||
| def name(self) -> Wikicode: | |||
| """The name of the argument to substitute.""" | |||
| return self._name | |||
| @@ -78,7 +80,7 @@ class Argument(Node): | |||
| self._name = parse_anything(value) | |||
| @property | |||
| def default(self) -> Optional["Wikicode"]: | |||
| def default(self) -> Wikicode | None: | |||
| """The default value to substitute if none is passed. | |||
| This will be ``None`` if the argument wasn't defined with one. The | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,6 +18,7 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| from typing import Any | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,11 +18,13 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| from typing import TYPE_CHECKING, Any, Optional, Generator, Callable | |||
| from collections.abc import Generator | |||
| from typing import TYPE_CHECKING, Any, Callable | |||
| from ._base import Node | |||
| from ..utils import parse_anything | |||
| from ._base import Node | |||
| if TYPE_CHECKING: | |||
| from ..wikicode import Wikicode | |||
| @@ -55,12 +57,12 @@ class ExternalLink(Node): | |||
| return "[" + str(self.url) + "]" | |||
| return str(self.url) | |||
| def __children__(self) -> Generator["Wikicode", None, None]: | |||
| def __children__(self) -> Generator[Wikicode, None, None]: | |||
| yield self.url | |||
| if self.title is not None: | |||
| yield self.title | |||
| def __strip__(self, **kwargs: Any) -> Optional[str]: | |||
| def __strip__(self, **kwargs: Any) -> str | None: | |||
| if self.brackets: | |||
| if self.title: | |||
| return self.title.strip_code(**kwargs) | |||
| @@ -70,7 +72,7 @@ class ExternalLink(Node): | |||
| def __showtree__( | |||
| self, | |||
| write: Callable[[str], None], | |||
| get: Callable[["Wikicode"], None], | |||
| get: Callable[[Wikicode], None], | |||
| mark: Callable[[], None], | |||
| ) -> None: | |||
| if self.brackets: | |||
| @@ -82,7 +84,7 @@ class ExternalLink(Node): | |||
| write("]") | |||
| @property | |||
| def url(self) -> "Wikicode": | |||
| def url(self) -> Wikicode: | |||
| """The URL of the link target, as a :class:`.Wikicode` object.""" | |||
| return self._url | |||
| @@ -94,7 +96,7 @@ class ExternalLink(Node): | |||
| self._url = parse_anything(value, contexts.EXT_LINK_URI) | |||
| @property | |||
| def title(self) -> Optional["Wikicode"]: | |||
| def title(self) -> Wikicode | None: | |||
| """The link title (if given), as a :class:`.Wikicode` object.""" | |||
| return self._title | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -23,6 +23,8 @@ This package contains objects used by :class:`.Node`\\ s, but that are not | |||
| nodes themselves. This includes template parameters and HTML tag attributes. | |||
| """ | |||
| from __future__ import annotations | |||
| __all__ = [ | |||
| "Attribute", | |||
| "Parameter", | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,8 +18,9 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| from typing import TYPE_CHECKING, Any, Optional | |||
| from typing import TYPE_CHECKING, Any | |||
| from ...string_mixin import StringMixIn | |||
| from ...utils import parse_anything | |||
| @@ -42,7 +43,7 @@ class Attribute(StringMixIn): | |||
| self, | |||
| name: Any, | |||
| value: Any = None, | |||
| quotes: Optional[str] = '"', | |||
| quotes: str | None = '"', | |||
| pad_first: str = " ", | |||
| pad_before_eq: str = "", | |||
| pad_after_eq: str = "", | |||
| @@ -54,7 +55,7 @@ class Attribute(StringMixIn): | |||
| self._pad_after_eq: str | |||
| self.name = name | |||
| self._quotes: Optional[str] = None | |||
| self._quotes: str | None = None | |||
| self.value = value | |||
| self.quotes = quotes | |||
| self.pad_first = pad_first | |||
| @@ -71,7 +72,7 @@ class Attribute(StringMixIn): | |||
| return result | |||
| @staticmethod | |||
| def _value_needs_quotes(value: "Wikicode") -> Optional[str]: | |||
| def _value_needs_quotes(value: Wikicode) -> str | None: | |||
| """Return valid quotes for the given value, or None if unneeded.""" | |||
| if not value: | |||
| return None | |||
| @@ -95,15 +96,15 @@ class Attribute(StringMixIn): | |||
| setattr(self, attr, value) | |||
| @staticmethod | |||
| def coerce_quotes(quotes: Any) -> Optional[str]: | |||
| def coerce_quotes(quotes: Any) -> str | None: | |||
| """Coerce a quote type into an acceptable value, or raise an error.""" | |||
| coerced_quotes = str(quotes) if quotes else None | |||
| if coerced_quotes not in [None, '"', "'"]: | |||
| raise ValueError("{!r} is not a valid quote type".format(quotes)) | |||
| raise ValueError(f"{quotes!r} is not a valid quote type") | |||
| return coerced_quotes | |||
| @property | |||
| def name(self) -> "Wikicode": | |||
| def name(self) -> Wikicode: | |||
| """The name of the attribute as a :class:`.Wikicode` object.""" | |||
| return self._name | |||
| @@ -112,7 +113,7 @@ class Attribute(StringMixIn): | |||
| self._name = parse_anything(value) | |||
| @property | |||
| def value(self) -> Optional["Wikicode"]: | |||
| def value(self) -> Wikicode | None: | |||
| """The value of the attribute as a :class:`.Wikicode` object.""" | |||
| return self._value | |||
| @@ -128,7 +129,7 @@ class Attribute(StringMixIn): | |||
| self._value = code | |||
| @property | |||
| def quotes(self) -> Optional[str]: | |||
| def quotes(self) -> str | None: | |||
| """How to enclose the attribute value. ``"``, ``'``, or ``None``.""" | |||
| return self._quotes | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,9 +18,10 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from typing import TYPE_CHECKING, Any, Union | |||
| from __future__ import annotations | |||
| import re | |||
| from typing import TYPE_CHECKING, Any | |||
| from ...string_mixin import StringMixIn | |||
| from ...utils import parse_anything | |||
| @@ -52,12 +53,12 @@ class Parameter(StringMixIn): | |||
| return str(self.value) | |||
| @staticmethod | |||
| def can_hide_key(key: Any) -> Union[re.Match, None]: | |||
| def can_hide_key(key: Any) -> re.Match | None: | |||
| """Return whether or not the given key can be hidden.""" | |||
| return re.match(r"[1-9][0-9]*$", str(key).strip()) | |||
| @property | |||
| def name(self) -> "Wikicode": | |||
| def name(self) -> Wikicode: | |||
| """The name of the parameter as a :class:`.Wikicode` object.""" | |||
| return self._name | |||
| @@ -66,7 +67,7 @@ class Parameter(StringMixIn): | |||
| self._name = parse_anything(newval) | |||
| @property | |||
| def value(self) -> "Wikicode": | |||
| def value(self) -> Wikicode: | |||
| """The value of the parameter as a :class:`.Wikicode` object.""" | |||
| return self._value | |||
| @@ -83,5 +84,5 @@ class Parameter(StringMixIn): | |||
| def showkey(self, newval: Any) -> None: | |||
| newval = bool(newval) | |||
| if not newval and not self.can_hide_key(self.name): | |||
| raise ValueError("parameter key {!r} cannot be hidden".format(self.name)) | |||
| raise ValueError(f"parameter key {self.name!r} cannot be hidden") | |||
| self._showkey = newval | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,11 +18,13 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| from typing import TYPE_CHECKING, Any, Generator, Callable, Optional | |||
| from collections.abc import Generator | |||
| from typing import TYPE_CHECKING, Any, Callable | |||
| from ._base import Node | |||
| from ..utils import parse_anything | |||
| from ._base import Node | |||
| if TYPE_CHECKING: | |||
| from ..wikicode import Wikicode | |||
| @@ -39,16 +41,16 @@ class Heading(Node): | |||
| def __str__(self) -> str: | |||
| return ("=" * self.level) + str(self.title) + ("=" * self.level) | |||
| def __children__(self) -> Generator["Wikicode", None, None]: | |||
| def __children__(self) -> Generator[Wikicode, None, None]: | |||
| yield self.title | |||
| def __strip__(self, **kwargs: Any) -> Optional[str]: | |||
| def __strip__(self, **kwargs: Any) -> str | None: | |||
| return self.title.strip_code(**kwargs) | |||
| def __showtree__( | |||
| self, | |||
| write: Callable[[str], None], | |||
| get: Callable[["Wikicode"], None], | |||
| get: Callable[[Wikicode], None], | |||
| mark: Callable[[], None], | |||
| ) -> None: | |||
| write("=" * self.level) | |||
| @@ -56,7 +58,7 @@ class Heading(Node): | |||
| write("=" * self.level) | |||
| @property | |||
| def title(self) -> "Wikicode": | |||
| def title(self) -> Wikicode: | |||
| """The title of the heading, as a :class:`.Wikicode` object.""" | |||
| return self._title | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,8 +18,10 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from typing import Any, Optional | |||
| from __future__ import annotations | |||
| import html.entities as htmlentities | |||
| from typing import Any | |||
| from ._base import Node | |||
| @@ -32,7 +34,7 @@ class HTMLEntity(Node): | |||
| def __init__( | |||
| self, | |||
| value: Any, | |||
| named: Optional[bool] = None, | |||
| named: bool | None = None, | |||
| hexadecimal: bool = False, | |||
| hex_char: str = "x", | |||
| ): | |||
| @@ -58,12 +60,12 @@ class HTMLEntity(Node): | |||
| def __str__(self) -> str: | |||
| if self.named: | |||
| return "&{};".format(self.value) | |||
| return f"&{self.value};" | |||
| if self.hexadecimal: | |||
| return "&#{}{};".format(self.hex_char, self.value) | |||
| return "&#{};".format(self.value) | |||
| return f"&#{self.hex_char}{self.value};" | |||
| return f"&#{self.value};" | |||
| def __strip__(self, **kwargs: Any) -> Optional[str]: | |||
| def __strip__(self, **kwargs: Any) -> str | None: | |||
| if kwargs.get("normalize"): | |||
| return self.normalize() | |||
| return str(self) | |||
| @@ -84,23 +86,21 @@ class HTMLEntity(Node): | |||
| except ValueError: | |||
| if newval not in htmlentities.entitydefs: | |||
| raise ValueError( | |||
| "entity value {!r} is not a valid name".format(newval) | |||
| f"entity value {newval!r} is not a valid name" | |||
| ) from None | |||
| self._named = True | |||
| self._hexadecimal = False | |||
| else: | |||
| if intval < 0 or intval > 0x10FFFF: | |||
| raise ValueError( | |||
| "entity value 0x{:x} is not in range(0x110000)".format(intval) | |||
| f"entity value 0x{intval:x} is not in range(0x110000)" | |||
| ) from None | |||
| self._named = False | |||
| self._hexadecimal = True | |||
| else: | |||
| test = int(newval, 16 if self.hexadecimal else 10) | |||
| if test < 0 or test > 0x10FFFF: | |||
| raise ValueError( | |||
| "entity value {} is not in range(0x110000)".format(test) | |||
| ) | |||
| raise ValueError(f"entity value {test} is not in range(0x110000)") | |||
| self._named = False | |||
| self._value = newval | |||
| @@ -118,16 +118,14 @@ class HTMLEntity(Node): | |||
| def named(self, newval: bool) -> None: | |||
| newval = bool(newval) | |||
| if newval and self.value not in htmlentities.entitydefs: | |||
| raise ValueError("entity value {!r} is not a valid name".format(self.value)) | |||
| raise ValueError(f"entity value {self.value!r} is not a valid name") | |||
| if not newval: | |||
| try: | |||
| int(self.value, 16) | |||
| except ValueError as exc: | |||
| raise ValueError( | |||
| "current entity value {!r} is not a valid Unicode codepoint".format( | |||
| self.value | |||
| ) | |||
| f"current entity value {self.value!r} is not a valid Unicode codepoint" | |||
| ) from exc | |||
| self._named = newval | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,13 +18,15 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| from typing import TYPE_CHECKING, Any, Callable, Optional, List, Generator | |||
| from collections.abc import Generator | |||
| from typing import TYPE_CHECKING, Any, Callable | |||
| from ._base import Node | |||
| from .extras import Attribute | |||
| from ..definitions import is_visible | |||
| from ..utils import parse_anything | |||
| from ._base import Node | |||
| from .extras import Attribute | |||
| if TYPE_CHECKING: | |||
| from ..wikicode import Wikicode | |||
| @@ -39,19 +41,19 @@ class Tag(Node): | |||
| self, | |||
| tag: Any, | |||
| contents: Any = None, | |||
| attrs: Optional[List[Attribute]] = None, | |||
| wiki_markup: Optional[str] = None, | |||
| attrs: list[Attribute] | None = None, | |||
| wiki_markup: str | None = None, | |||
| self_closing: bool = False, | |||
| invalid: bool = False, | |||
| implicit: bool = False, | |||
| padding: str = "", | |||
| closing_tag: Optional["Wikicode"] = None, | |||
| wiki_style_separator: Optional[str] = None, | |||
| closing_wiki_markup: Optional[str] = None, | |||
| closing_tag: Wikicode | None = None, | |||
| wiki_style_separator: str | None = None, | |||
| closing_wiki_markup: str | None = None, | |||
| ): | |||
| super().__init__() | |||
| self._attrs: List[Attribute] | |||
| self._closing_wiki_markup: Optional[str] | |||
| self._attrs: list[Attribute] | |||
| self._closing_wiki_markup: str | None | |||
| self.tag = tag | |||
| self.contents = contents | |||
| @@ -98,7 +100,7 @@ class Tag(Node): | |||
| result += "</" + str(self.closing_tag) + ">" | |||
| return result | |||
| def __children__(self) -> Generator["Wikicode", None, None]: | |||
| def __children__(self) -> Generator[Wikicode, None, None]: | |||
| if not self.wiki_markup: | |||
| yield self.tag | |||
| for attr in self.attributes: | |||
| @@ -110,7 +112,7 @@ class Tag(Node): | |||
| if not self.wiki_markup and self.closing_tag: | |||
| yield self.closing_tag | |||
| def __strip__(self, **kwargs: Any) -> Optional[str]: | |||
| def __strip__(self, **kwargs: Any) -> str | None: | |||
| if self.contents and is_visible(str(self.tag)): | |||
| return self.contents.strip_code(**kwargs) | |||
| return None | |||
| @@ -118,7 +120,7 @@ class Tag(Node): | |||
| def __showtree__( | |||
| self, | |||
| write: Callable[[str], None], | |||
| get: Callable[["Wikicode"], None], | |||
| get: Callable[[Wikicode], None], | |||
| mark: Callable[[], None], | |||
| ) -> None: | |||
| write("</" if self.invalid else "<") | |||
| @@ -140,7 +142,7 @@ class Tag(Node): | |||
| write(">") | |||
| @property | |||
| def tag(self) -> "Wikicode": | |||
| def tag(self) -> Wikicode: | |||
| """The tag itself, as a :class:`.Wikicode` object.""" | |||
| return self._tag | |||
| @@ -149,7 +151,7 @@ class Tag(Node): | |||
| self._tag = self._closing_tag = parse_anything(value) | |||
| @property | |||
| def contents(self) -> "Wikicode": | |||
| def contents(self) -> Wikicode: | |||
| """The contents of the tag, as a :class:`.Wikicode` object.""" | |||
| return self._contents | |||
| @@ -158,7 +160,7 @@ class Tag(Node): | |||
| self._contents = parse_anything(value) | |||
| @property | |||
| def attributes(self) -> List[Attribute]: | |||
| def attributes(self) -> list[Attribute]: | |||
| """The list of attributes affecting the tag. | |||
| Each attribute is an instance of :class:`.Attribute`. | |||
| @@ -166,7 +168,7 @@ class Tag(Node): | |||
| return self._attrs | |||
| @property | |||
| def wiki_markup(self) -> Optional[str]: | |||
| def wiki_markup(self) -> str | None: | |||
| """The wikified version of a tag to show instead of HTML. | |||
| If set to a value, this will be displayed instead of the brackets. | |||
| @@ -176,7 +178,7 @@ class Tag(Node): | |||
| return self._wiki_markup | |||
| @wiki_markup.setter | |||
| def wiki_markup(self, value: Optional[str]) -> None: | |||
| def wiki_markup(self, value: str | None) -> None: | |||
| self._wiki_markup = str(value) if value else None | |||
| if not value or not self.closing_wiki_markup: | |||
| self._closing_wiki_markup = self._wiki_markup | |||
| @@ -235,7 +237,7 @@ class Tag(Node): | |||
| self._padding = value | |||
| @property | |||
| def closing_tag(self) -> "Wikicode": | |||
| def closing_tag(self) -> Wikicode: | |||
| """The closing tag, as a :class:`.Wikicode` object. | |||
| This will usually equal :attr:`tag`, unless there is additional | |||
| @@ -248,7 +250,7 @@ class Tag(Node): | |||
| self._closing_tag = parse_anything(value) | |||
| @property | |||
| def wiki_style_separator(self) -> Optional[str]: | |||
| def wiki_style_separator(self) -> str | None: | |||
| """The separator between the padding and content in a wiki markup tag. | |||
| Essentially the wiki equivalent of the TagCloseOpen. | |||
| @@ -256,11 +258,11 @@ class Tag(Node): | |||
| return self._wiki_style_separator | |||
| @wiki_style_separator.setter | |||
| def wiki_style_separator(self, value: Optional[str]) -> None: | |||
| def wiki_style_separator(self, value: str | None) -> None: | |||
| self._wiki_style_separator = str(value) if value else None | |||
| @property | |||
| def closing_wiki_markup(self) -> Optional[str]: | |||
| def closing_wiki_markup(self) -> str | None: | |||
| """The wikified version of the closing tag to show instead of HTML. | |||
| If set to a value, this will be displayed instead of the close tag | |||
| @@ -273,7 +275,7 @@ class Tag(Node): | |||
| return self._closing_wiki_markup | |||
| @closing_wiki_markup.setter | |||
| def closing_wiki_markup(self, value: Optional[str]) -> None: | |||
| def closing_wiki_markup(self, value: str | None) -> None: | |||
| self._closing_wiki_markup = str(value) if value else None | |||
| def has(self, name: str) -> bool: | |||
| @@ -304,7 +306,7 @@ class Tag(Node): | |||
| self, | |||
| name: Any, | |||
| value: Any = None, | |||
| quotes: Optional[str] = '"', | |||
| quotes: str | None = '"', | |||
| pad_first: str = " ", | |||
| pad_before_eq: str = "", | |||
| pad_after_eq: str = "", | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -17,27 +17,25 @@ | |||
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| import re | |||
| from collections import defaultdict | |||
| from collections.abc import Generator, Mapping | |||
| from typing import ( | |||
| TYPE_CHECKING, | |||
| Any, | |||
| Callable, | |||
| Dict, | |||
| Generator, | |||
| List, | |||
| Mapping, | |||
| Optional, | |||
| TypeVar, | |||
| Union, | |||
| overload, | |||
| ) | |||
| from ..utils import parse_anything | |||
| from ._base import Node | |||
| from .extras import Parameter | |||
| from .html_entity import HTMLEntity | |||
| from .text import Text | |||
| from .extras import Parameter | |||
| from ..utils import parse_anything | |||
| if TYPE_CHECKING: | |||
| from ..wikicode import Wikicode | |||
| @@ -54,10 +52,10 @@ T = TypeVar("T") | |||
| class Template(Node): | |||
| """Represents a template in wikicode, like ``{{foo}}``.""" | |||
| def __init__(self, name: Any, params: Optional[List[Parameter]] = None): | |||
| def __init__(self, name: Any, params: list[Parameter] | None = None): | |||
| super().__init__() | |||
| self.name = name | |||
| self._params: List[Parameter] = params or [] | |||
| self._params: list[Parameter] = params or [] | |||
| def __str__(self) -> str: | |||
| if self.params: | |||
| @@ -65,14 +63,14 @@ class Template(Node): | |||
| return "{{" + str(self.name) + "|" + params + "}}" | |||
| return "{{" + str(self.name) + "}}" | |||
| def __children__(self) -> Generator["Wikicode", None, None]: | |||
| def __children__(self) -> Generator[Wikicode]: | |||
| yield self.name | |||
| for param in self.params: | |||
| if param.showkey: | |||
| yield param.name | |||
| yield param.value | |||
| def __strip__(self, **kwargs: Any) -> Optional[str]: | |||
| def __strip__(self, **kwargs: Any) -> str | None: | |||
| if kwargs.get("keep_template_params"): | |||
| parts = [param.value.strip_code(**kwargs) for param in self.params] | |||
| return " ".join(part for part in parts if part) | |||
| @@ -81,7 +79,7 @@ class Template(Node): | |||
| def __showtree__( | |||
| self, | |||
| write: Callable[[str], None], | |||
| get: Callable[["Wikicode"], None], | |||
| get: Callable[[Wikicode], None], | |||
| mark: Callable[[], None], | |||
| ) -> None: | |||
| write("{{") | |||
| @@ -96,7 +94,7 @@ class Template(Node): | |||
| write("}}") | |||
| @staticmethod | |||
| def _surface_escape(code: "Wikicode", char: str) -> None: | |||
| def _surface_escape(code: Wikicode, char: str) -> None: | |||
| """Return *code* with *char* escaped as an HTML entity. | |||
| The main use of this is to escape pipes (``|``) or equal signs (``=``) | |||
| @@ -109,7 +107,7 @@ class Template(Node): | |||
| code.replace(node, node.replace(char, replacement), False) | |||
| @staticmethod | |||
| def _select_theory(theories: Dict[str, int]) -> Optional[str]: | |||
| def _select_theory(theories: dict[str, int]) -> str | None: | |||
| """Return the most likely spacing convention given different options. | |||
| Given a dictionary of convention options as keys and their occurrence | |||
| @@ -125,7 +123,7 @@ class Template(Node): | |||
| return None | |||
| @staticmethod | |||
| def _blank_param_value(value: "Wikicode") -> None: | |||
| def _blank_param_value(value: Wikicode) -> None: | |||
| """Remove the content from *value* while keeping its whitespace. | |||
| Replace *value*\\ 's nodes with two text nodes, the first containing | |||
| @@ -142,15 +140,15 @@ class Template(Node): | |||
| def _get_spacing_conventions( | |||
| self, use_names: bool | |||
| ) -> tuple[Optional[str], Optional[str]]: | |||
| ) -> tuple[str | None, str | None]: | |||
| """Try to determine the whitespace conventions for parameters. | |||
| This will examine the existing parameters and use | |||
| :meth:`_select_theory` to determine if there are any preferred styles | |||
| for how much whitespace to put before or after the value. | |||
| """ | |||
| before_theories: defaultdict[str, int] = defaultdict(lambda: 0) | |||
| after_theories: defaultdict[str, int] = defaultdict(lambda: 0) | |||
| before_theories: defaultdict[str, int] = defaultdict(int) | |||
| after_theories: defaultdict[str, int] = defaultdict(int) | |||
| for param in self.params: | |||
| if not param.showkey: | |||
| continue | |||
| @@ -205,7 +203,7 @@ class Template(Node): | |||
| return False | |||
| @property | |||
| def name(self) -> "Wikicode": | |||
| def name(self) -> Wikicode: | |||
| """The name of the template, as a :class:`.Wikicode` object.""" | |||
| return self._name | |||
| @@ -214,11 +212,11 @@ class Template(Node): | |||
| self._name = parse_anything(value) | |||
| @property | |||
| def params(self) -> List[Parameter]: | |||
| def params(self) -> list[Parameter]: | |||
| """The list of parameters contained within the template.""" | |||
| return self._params | |||
| def has(self, name: Union[str, Any], ignore_empty: bool = False) -> bool: | |||
| def has(self, name: str | Any, ignore_empty: bool = False) -> bool: | |||
| """Return ``True`` if any parameter in the template is named *name*. | |||
| With *ignore_empty*, ``False`` will be returned even if the template | |||
| @@ -234,17 +232,17 @@ class Template(Node): | |||
| return True | |||
| return False | |||
| def has_param(self, name: Union[str, Any], ignore_empty: bool = False) -> bool: | |||
| def has_param(self, name: str | Any, ignore_empty: bool = False) -> bool: | |||
| """Alias for :meth:`has`.""" | |||
| return self.has(name, ignore_empty) | |||
| @overload | |||
| def get(self, name: Union[str, Any]) -> Parameter: ... | |||
| def get(self, name: str | Any) -> Parameter: ... | |||
| @overload | |||
| def get(self, name: Union[str, Any], default: T) -> Union[Parameter, T]: ... | |||
| def get(self, name: str | Any, default: T) -> Parameter | T: ... | |||
| def get(self, name: Union[str, Any], default: T = _UNSET) -> Union[Parameter, T]: | |||
| def get(self, name: str | Any, default: T = _UNSET) -> Parameter | T: | |||
| """Get the parameter whose name is *name*. | |||
| The returned object is a :class:`.Parameter` instance. Raises | |||
| @@ -261,16 +259,16 @@ class Template(Node): | |||
| raise ValueError(name) | |||
| return default | |||
| def __getitem__(self, name: Union[str, Any]) -> Parameter: | |||
| def __getitem__(self, name: str | Any) -> Parameter: | |||
| return self.get(name) | |||
| def add( | |||
| self, | |||
| name: Any, | |||
| value: Any, | |||
| showkey: Optional[bool] = None, | |||
| before: Optional[Union[Parameter, str]] = None, | |||
| after: Optional[Union[Parameter, str]] = None, | |||
| showkey: bool | None = None, | |||
| before: Parameter | str | None = None, | |||
| after: Parameter | str | None = None, | |||
| preserve_spacing: bool = True, | |||
| ) -> Parameter: | |||
| """Add a parameter to the template with a given *name* and *value*. | |||
| @@ -377,7 +375,7 @@ class Template(Node): | |||
| def __setitem__(self, name: Any, value: Any) -> Parameter: | |||
| return self.add(name, value) | |||
| def remove(self, param: Union[Parameter, str], keep_field: bool = False) -> None: | |||
| def remove(self, param: Parameter | str, keep_field: bool = False) -> None: | |||
| """Remove a parameter from the template, identified by *param*. | |||
| If *param* is a :class:`.Parameter` object, it will be matched exactly, | |||
| @@ -424,5 +422,5 @@ class Template(Node): | |||
| for i in reversed(to_remove): | |||
| self.params.pop(i) | |||
| def __delitem__(self, param: Union[Parameter, str]) -> None: | |||
| def __delitem__(self, param: Parameter | str) -> None: | |||
| return self.remove(param) | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,6 +18,7 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| from typing import TYPE_CHECKING, Any, Callable | |||
| @@ -45,7 +46,7 @@ class Text(Node): | |||
| def __showtree__( | |||
| self, | |||
| write: Callable[[str], None], | |||
| get: Callable[["Wikicode"], None], | |||
| get: Callable[[Wikicode], None], | |||
| mark: Callable[[], None], | |||
| ) -> None: | |||
| write(str(self).encode("unicode_escape").decode("utf8")) | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,11 +18,13 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| from typing import TYPE_CHECKING, Any, Optional, Generator, Callable | |||
| from collections.abc import Generator | |||
| from typing import TYPE_CHECKING, Any, Callable | |||
| from ._base import Node | |||
| from ..utils import parse_anything | |||
| from ._base import Node | |||
| if TYPE_CHECKING: | |||
| from ..wikicode import Wikicode | |||
| @@ -43,12 +45,12 @@ class Wikilink(Node): | |||
| return "[[" + str(self.title) + "|" + str(self.text) + "]]" | |||
| return "[[" + str(self.title) + "]]" | |||
| def __children__(self) -> Generator["Wikicode", None, None]: | |||
| def __children__(self) -> Generator[Wikicode, None, None]: | |||
| yield self.title | |||
| if self.text is not None: | |||
| yield self.text | |||
| def __strip__(self, **kwargs: Any) -> Optional[str]: | |||
| def __strip__(self, **kwargs: Any) -> str | None: | |||
| if self.text is not None: | |||
| return self.text.strip_code(**kwargs) | |||
| return self.title.strip_code(**kwargs) | |||
| @@ -56,7 +58,7 @@ class Wikilink(Node): | |||
| def __showtree__( | |||
| self, | |||
| write: Callable[[str], None], | |||
| get: Callable[["Wikicode"], None], | |||
| get: Callable[[Wikicode], None], | |||
| mark: Callable[[], None], | |||
| ) -> None: | |||
| write("[[") | |||
| @@ -68,7 +70,7 @@ class Wikilink(Node): | |||
| write("]]") | |||
| @property | |||
| def title(self) -> "Wikicode": | |||
| def title(self) -> Wikicode: | |||
| """The title of the linked page, as a :class:`.Wikicode` object.""" | |||
| return self._title | |||
| @@ -77,7 +79,7 @@ class Wikilink(Node): | |||
| self._title = parse_anything(value) | |||
| @property | |||
| def text(self) -> Optional["Wikicode"]: | |||
| def text(self) -> Wikicode | None: | |||
| """The text to display (if any), as a :class:`.Wikicode` object.""" | |||
| return self._text | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -24,6 +24,8 @@ modules: the :mod:`.tokenizer` and the :mod:`.builder`. This module joins them | |||
| together into one interface. | |||
| """ | |||
| from __future__ import annotations | |||
| from .builder import Builder | |||
| from .errors import ParserError | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,9 +18,8 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| from . import tokens | |||
| from .errors import ParserError | |||
| from ..nodes import ( | |||
| Argument, | |||
| Comment, | |||
| @@ -35,6 +34,8 @@ from ..nodes import ( | |||
| from ..nodes.extras import Attribute, Parameter | |||
| from ..smart_list import SmartList | |||
| from ..wikicode import Wikicode | |||
| from . import tokens | |||
| from .errors import ParserError | |||
| __all__ = ["Builder"] | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2019 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -114,6 +114,8 @@ Aggregate contexts: | |||
| """ | |||
| from __future__ import annotations | |||
| # Local contexts: | |||
| TEMPLATE_NAME = 1 << 0 | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2017 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2017 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2021 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2018 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2018 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2017 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,5 +1,5 @@ | |||
| /* | |||
| Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |||
| this software and associated documentation files (the "Software"), to deal in | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,6 +18,8 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| __all__ = ["ParserError"] | |||
| @@ -31,5 +33,5 @@ class ParserError(Exception): | |||
| """ | |||
| def __init__(self, extra): | |||
| msg = "This is a bug and should be reported. Info: {}.".format(extra) | |||
| msg = f"This is a bug and should be reported. Info: {extra}." | |||
| super().__init__(msg) | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2021 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,19 +18,21 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| import html.entities as htmlentities | |||
| from math import log | |||
| import re | |||
| from math import log | |||
| from . import contexts, tokens | |||
| from .errors import ParserError | |||
| from ..definitions import ( | |||
| get_html_tag, | |||
| is_parsable, | |||
| is_scheme, | |||
| is_single, | |||
| is_single_only, | |||
| is_scheme, | |||
| ) | |||
| from . import contexts, tokens | |||
| from .errors import ParserError | |||
| __all__ = ["Tokenizer"] | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -26,6 +26,8 @@ a syntactically valid form by the :class:`.Tokenizer`, and then converted into | |||
| the :class`.Wikicode` tree by the :class:`.Builder`. | |||
| """ | |||
| from __future__ import annotations | |||
| __all__ = ["Token"] | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2019-2020 Yuri Astrakhan <YuriAstrakhan@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| @@ -25,6 +25,8 @@ This module contains the :class:`.SmartList` type, as well as its | |||
| reflect changes made to the main list, and vice-versa. | |||
| """ | |||
| from __future__ import annotations | |||
| __all__ = ["SmartList"] | |||
| from .smart_list import SmartList | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2023 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2019-2020 Yuri Astrakhan <YuriAstrakhan@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| @@ -19,6 +19,8 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| import weakref | |||
| from .utils import _SliceNormalizerMixIn, inheritdoc | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2023 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2019-2020 Yuri Astrakhan <YuriAstrakhan@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| @@ -19,6 +19,8 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| from weakref import ref | |||
| from .list_proxy import ListProxy | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2023 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2019-2020 Yuri Astrakhan <YuriAstrakhan@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| @@ -19,6 +19,8 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| from sys import maxsize | |||
| __all__ = [] | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -23,6 +23,8 @@ This module contains the :class:`.StringMixIn` type, which implements the | |||
| interface for the ``str`` type in a dynamic manner. | |||
| """ | |||
| from __future__ import annotations | |||
| from sys import getdefaultencoding | |||
| __all__ = ["StringMixIn"] | |||
| @@ -95,7 +97,7 @@ class StringMixIn: | |||
| def __getattr__(self, attr): | |||
| if not hasattr(str, attr): | |||
| raise AttributeError( | |||
| "{!r} object has no attribute {!r}".format(type(self).__name__, attr) | |||
| f"{type(self).__name__!r} object has no attribute {attr!r}" | |||
| ) | |||
| return getattr(self.__str__(), attr) | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2023 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,9 +18,12 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| import re | |||
| from collections.abc import Generator, Iterable | |||
| from itertools import chain | |||
| from typing import Any, Callable, Generator, Iterable, Optional, Union, cast, overload | |||
| from typing import Any, Callable, cast, overload | |||
| from .nodes import ( | |||
| Argument, | |||
| @@ -67,9 +70,9 @@ class Wikicode(StringMixIn): | |||
| def _get_children( | |||
| node: Node, | |||
| contexts: bool = False, | |||
| restrict: Optional[type] = None, | |||
| parent: Optional["Wikicode"] = None, | |||
| ) -> Generator[Union[tuple[Optional["Wikicode"], Node], Node], None, None]: | |||
| restrict: type | None = None, | |||
| parent: Wikicode | None = None, | |||
| ) -> Generator[tuple[Wikicode | None, Node] | Node]: | |||
| """Iterate over all child :class:`.Node`\\ s of a given *node*.""" | |||
| yield (parent, node) if contexts else node | |||
| if restrict and isinstance(node, restrict): | |||
| @@ -80,7 +83,7 @@ class Wikicode(StringMixIn): | |||
| yield from sub | |||
| @staticmethod | |||
| def _slice_replace(code: "Wikicode", index: slice, old: str, new: str) -> None: | |||
| def _slice_replace(code: Wikicode, index: slice, old: str, new: str) -> None: | |||
| """Replace the string *old* with *new* across *index* in *code*.""" | |||
| nodes = [str(node) for node in code.get(index)] | |||
| substring = "".join(nodes).replace(old, new) | |||
| @@ -88,11 +91,11 @@ class Wikicode(StringMixIn): | |||
| @staticmethod | |||
| def _build_matcher( | |||
| matches: Union[ | |||
| Callable[[Node], Union[bool, re.Match[str], None]], re.Pattern, str, None | |||
| ], | |||
| matches: ( | |||
| Callable[[Node], bool | re.Match[str] | None] | re.Pattern | str | None | |||
| ), | |||
| flags: int, | |||
| ) -> Callable[[Node], Union[bool, re.Match[str], None]]: | |||
| ) -> Callable[[Node], bool | re.Match[str] | None]: | |||
| """Helper for :meth:`_indexed_ifilter` and others. | |||
| If *matches* is a function, return it. If it's a regex, return a | |||
| @@ -108,10 +111,10 @@ class Wikicode(StringMixIn): | |||
| def _indexed_ifilter( | |||
| self, | |||
| recursive: bool = True, | |||
| matches: Union[Callable[[Node], bool], re.Pattern, str, None] = None, | |||
| matches: Callable[[Node], bool] | re.Pattern | str | None = None, | |||
| flags: int = FLAGS, | |||
| forcetype: Optional[type] = None, | |||
| ) -> Generator[tuple[int, Node], None, None]: | |||
| forcetype: type | None = None, | |||
| ) -> Generator[tuple[int, Node]]: | |||
| """Iterate over nodes and their corresponding indices in the node list. | |||
| The arguments are interpreted as for :meth:`ifilter`. For each tuple | |||
| @@ -124,7 +127,7 @@ class Wikicode(StringMixIn): | |||
| if recursive: | |||
| restrict = forcetype if recursive == self.RECURSE_OTHERS else None | |||
| def getter(i: int, node: Node) -> Generator[tuple[int, Node], None, None]: | |||
| def getter(i: int, node: Node) -> Generator[tuple[int, Node]]: | |||
| for ch in self._get_children(node, restrict=restrict): | |||
| yield (i, cast(Node, ch)) | |||
| @@ -135,7 +138,7 @@ class Wikicode(StringMixIn): | |||
| if (not forcetype or isinstance(node, forcetype)) and match(node): | |||
| yield (i, node) | |||
| def _is_child_wikicode(self, obj: "Wikicode", recursive: bool = True) -> bool: | |||
| def _is_child_wikicode(self, obj: Wikicode, recursive: bool = True) -> bool: | |||
| """Return whether the given :class:`.Wikicode` is a descendant.""" | |||
| def deref(nodes): | |||
| @@ -157,8 +160,8 @@ class Wikicode(StringMixIn): | |||
| return False | |||
| def _do_strong_search( | |||
| self, obj: Union[Node, "Wikicode"], recursive: bool = True | |||
| ) -> tuple["Wikicode", slice]: | |||
| self, obj: Node | Wikicode, recursive: bool = True | |||
| ) -> tuple[Wikicode, slice]: | |||
| """Search for the specific element *obj* within the node list. | |||
| *obj* can be either a :class:`.Node` or a :class:`.Wikicode` object. If | |||
| @@ -194,7 +197,7 @@ class Wikicode(StringMixIn): | |||
| def _do_weak_search( | |||
| self, obj: Any, recursive: bool | |||
| ) -> list[tuple[bool, "Wikicode", slice]]: | |||
| ) -> list[tuple[bool, Wikicode, slice]]: | |||
| """Search for an element that looks like *obj* within the node list. | |||
| This follows the same rules as :meth:`_do_strong_search` with some | |||
| @@ -215,7 +218,7 @@ class Wikicode(StringMixIn): | |||
| if not obj or obj not in self: | |||
| raise ValueError(obj) | |||
| results = [] | |||
| contexts: list["Wikicode"] = [self] | |||
| contexts: list[Wikicode] = [self] | |||
| while contexts: | |||
| context = contexts.pop() | |||
| i = len(context.nodes) - 1 | |||
| @@ -239,7 +242,7 @@ class Wikicode(StringMixIn): | |||
| return results | |||
| def _get_tree( | |||
| self, code: "Wikicode", lines: list[str], marker: Any, indent: int | |||
| self, code: Wikicode, lines: list[str], marker: Any, indent: int | |||
| ) -> list[str]: | |||
| """Build a tree to illustrate the way the Wikicode object was parsed. | |||
| @@ -314,7 +317,7 @@ class Wikicode(StringMixIn): | |||
| return self._nodes | |||
| @nodes.setter | |||
| def nodes(self, value: Union[list[Node], Any]) -> None: | |||
| def nodes(self, value: list[Node] | Any) -> None: | |||
| if not isinstance(value, list): | |||
| value = parse_anything(value).nodes | |||
| self._nodes = value | |||
| @@ -347,7 +350,7 @@ class Wikicode(StringMixIn): | |||
| else: | |||
| self.nodes.pop(index) | |||
| def contains(self, obj: Union[Node, "Wikicode", str]) -> bool: | |||
| def contains(self, obj: Node | Wikicode | str) -> bool: | |||
| """Return whether this Wikicode object contains *obj*. | |||
| If *obj* is a :class:`.Node` or :class:`.Wikicode` object, then we | |||
| @@ -362,7 +365,7 @@ class Wikicode(StringMixIn): | |||
| return False | |||
| return True | |||
| def index(self, obj: Union[Node, "Wikicode", str], recursive: bool = False) -> int: | |||
| def index(self, obj: Node | Wikicode | str, recursive: bool = False) -> int: | |||
| """Return the index of *obj* in the list of nodes. | |||
| Raises :exc:`ValueError` if *obj* is not found. If *recursive* is | |||
| @@ -381,7 +384,7 @@ class Wikicode(StringMixIn): | |||
| return i | |||
| raise ValueError(obj) | |||
| def get_ancestors(self, obj: Union[Node, "Wikicode"]) -> list[Node]: | |||
| def get_ancestors(self, obj: Node | Wikicode) -> list[Node]: | |||
| """Return a list of all ancestor nodes of the :class:`.Node` *obj*. | |||
| The list is ordered from the most shallow ancestor (greatest great- | |||
| @@ -398,7 +401,7 @@ class Wikicode(StringMixIn): | |||
| object. Will raise :exc:`ValueError` if it wasn't found. | |||
| """ | |||
| def _get_ancestors(code: "Wikicode", needle: Node) -> Union[list[Node], None]: | |||
| def _get_ancestors(code: Wikicode, needle: Node) -> list[Node] | None: | |||
| for node in code.nodes: | |||
| if node is needle: | |||
| return [] | |||
| @@ -418,7 +421,7 @@ class Wikicode(StringMixIn): | |||
| raise ValueError(obj) | |||
| return ancestors | |||
| def get_parent(self, obj: Union[Node, "Wikicode"]) -> Union[Node, None]: | |||
| def get_parent(self, obj: Node | Wikicode) -> Node | None: | |||
| """Return the direct parent node of the :class:`.Node` *obj*. | |||
| This function is equivalent to calling :meth:`.get_ancestors` and | |||
| @@ -440,7 +443,7 @@ class Wikicode(StringMixIn): | |||
| self.nodes.insert(index, node) | |||
| def insert_before( | |||
| self, obj: Union[Node, "Wikicode", str], value: Any, recursive: bool = True | |||
| self, obj: Node | Wikicode | str, value: Any, recursive: bool = True | |||
| ) -> None: | |||
| """Insert *value* immediately before *obj*. | |||
| @@ -465,7 +468,7 @@ class Wikicode(StringMixIn): | |||
| self._slice_replace(context, index, obj, str(value) + obj) | |||
| def insert_after( | |||
| self, obj: Union[Node, "Wikicode", str], value: Any, recursive: bool = True | |||
| self, obj: Node | Wikicode | str, value: Any, recursive: bool = True | |||
| ) -> None: | |||
| """Insert *value* immediately after *obj*. | |||
| @@ -490,7 +493,7 @@ class Wikicode(StringMixIn): | |||
| self._slice_replace(context, index, obj, obj + str(value)) | |||
| def replace( | |||
| self, obj: Union[Node, "Wikicode", str], value: Any, recursive: bool = True | |||
| self, obj: Node | Wikicode | str, value: Any, recursive: bool = True | |||
| ) -> None: | |||
| """Replace *obj* with *value*. | |||
| @@ -526,7 +529,7 @@ class Wikicode(StringMixIn): | |||
| for node in nodes: | |||
| self.nodes.append(node) | |||
| def remove(self, obj: Union[Node, "Wikicode", str], recursive: bool = True) -> None: | |||
| def remove(self, obj: Node | Wikicode | str, recursive: bool = True) -> None: | |||
| """Remove *obj* from the list of nodes. | |||
| *obj* can be either a string, a :class:`.Node`, or another | |||
| @@ -552,9 +555,7 @@ class Wikicode(StringMixIn): | |||
| def matches( | |||
| self, | |||
| other: Union[ | |||
| Node, "Wikicode", str, bytes, Iterable[Union[Node, "Wikicode", str, bytes]] | |||
| ], | |||
| other: Node | Wikicode | str | bytes | Iterable[Node | Wikicode | str | bytes], | |||
| ) -> bool: | |||
| """Do a loose equivalency test suitable for comparing page names. | |||
| @@ -583,10 +584,10 @@ class Wikicode(StringMixIn): | |||
| def ifilter( | |||
| self, | |||
| recursive: bool = True, | |||
| matches: Union[Callable[[Node], bool], re.Pattern, str, None] = None, | |||
| matches: Callable[[Node], bool] | re.Pattern | str | None = None, | |||
| flags: int = FLAGS, | |||
| forcetype: Optional[type] = None, | |||
| ) -> Generator[Node, None, None]: | |||
| forcetype: type | None = None, | |||
| ) -> Generator[Node]: | |||
| """Iterate over nodes in our list matching certain conditions. | |||
| If *forcetype* is given, only nodes that are instances of this type (or | |||
| @@ -622,13 +623,13 @@ class Wikicode(StringMixIn): | |||
| def get_sections( | |||
| self, | |||
| levels: Optional[Iterable[int]] = None, | |||
| matches: Union[Callable[[Node], bool], re.Pattern, str, None] = None, | |||
| levels: Iterable[int] | None = None, | |||
| matches: Callable[[Node], bool] | re.Pattern | str | None = None, | |||
| flags: int = FLAGS, | |||
| flat: bool = False, | |||
| include_lead: Optional[bool] = None, | |||
| include_lead: bool | None = None, | |||
| include_headings: bool = True, | |||
| ) -> list["Wikicode"]: | |||
| ) -> list[Wikicode]: | |||
| """Return a list of sections within the page. | |||
| Sections are returned as :class:`.Wikicode` objects with a shared node | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2021 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,6 +18,8 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| from mwparserfromhell.nodes import ( | |||
| Argument, | |||
| Comment, | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,9 +22,12 @@ | |||
| Test cases for the Argument node. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.nodes import Argument, Text | |||
| from .conftest import assert_wikicode_equal, wrap, wraptext | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,10 +22,13 @@ | |||
| Test cases for the Attribute node extra. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.nodes import Template | |||
| from mwparserfromhell.nodes.extras import Attribute | |||
| from .conftest import assert_wikicode_equal, wrap, wraptext | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2019 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,6 +22,8 @@ | |||
| Tests for the builder, which turns tokens into Wikicode objects. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.nodes import ( | |||
| @@ -36,8 +38,9 @@ from mwparserfromhell.nodes import ( | |||
| Wikilink, | |||
| ) | |||
| from mwparserfromhell.nodes.extras import Attribute, Parameter | |||
| from mwparserfromhell.parser import tokens, ParserError | |||
| from mwparserfromhell.parser import ParserError, tokens | |||
| from mwparserfromhell.parser.builder import Builder | |||
| from .conftest import assert_wikicode_equal, wrap, wraptext | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,6 +22,8 @@ | |||
| Test cases for the Comment node. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.nodes import Comment | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,9 +22,11 @@ | |||
| Integration test cases for mwparserfromhell's documentation. | |||
| """ | |||
| from __future__ import annotations | |||
| import json | |||
| from io import StringIO | |||
| import os | |||
| from io import StringIO | |||
| from urllib.parse import urlencode | |||
| from urllib.request import urlopen | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,9 +22,12 @@ | |||
| Test cases for the ExternalLink node. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.nodes import ExternalLink, Text | |||
| from .conftest import assert_wikicode_equal, wrap, wraptext | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,9 +22,12 @@ | |||
| Test cases for the Heading node. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.nodes import Heading, Text | |||
| from .conftest import assert_wikicode_equal, wrap, wraptext | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,6 +22,8 @@ | |||
| Test cases for the HTMLEntity node. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.nodes import HTMLEntity | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,9 +22,12 @@ | |||
| Test cases for the Parameter node extra. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.nodes.extras import Parameter | |||
| from .conftest import assert_wikicode_equal, wraptext | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,11 +22,14 @@ | |||
| Tests for the Parser class itself, which tokenizes and builds nodes. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell import parser | |||
| from mwparserfromhell.nodes import Tag, Template, Text, Wikilink | |||
| from mwparserfromhell.nodes.extras import Parameter | |||
| from .conftest import assert_wikicode_equal, wrap, wraptext | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2023 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,6 +22,8 @@ | |||
| Test cases for the SmartList class and its child, ListProxy. | |||
| """ | |||
| from __future__ import annotations | |||
| import pickle | |||
| import pytest | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,6 +22,8 @@ | |||
| Test cases for the StringMixIn class. | |||
| """ | |||
| from __future__ import annotations | |||
| import sys | |||
| from types import GeneratorType | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,10 +22,13 @@ | |||
| Test cases for the Tag node. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.nodes import Tag, Template, Text | |||
| from mwparserfromhell.nodes.extras import Attribute | |||
| from .conftest import assert_wikicode_equal, wrap, wraptext | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,13 +22,16 @@ | |||
| Test cases for the Template node. | |||
| """ | |||
| from __future__ import annotations | |||
| from difflib import unified_diff | |||
| import pytest | |||
| from mwparserfromhell import parse | |||
| from mwparserfromhell.nodes import HTMLEntity, Template, Text | |||
| from mwparserfromhell.nodes.extras import Parameter | |||
| from mwparserfromhell import parse | |||
| from .conftest import assert_wikicode_equal, wrap, wraptext | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,6 +22,8 @@ | |||
| Test cases for the Text node. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.nodes import Text | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -18,9 +18,11 @@ | |||
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
| # SOFTWARE. | |||
| from __future__ import annotations | |||
| import codecs | |||
| from os import listdir, path | |||
| import warnings | |||
| from os import listdir, path | |||
| import pytest | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,6 +22,8 @@ | |||
| Test cases for the Token class and its subclasses. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.parser import tokens | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2016 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,10 +22,13 @@ | |||
| Tests for the utils module, which provides parse_anything(). | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.nodes import Template, Text | |||
| from mwparserfromhell.utils import parse_anything | |||
| from .conftest import assert_wikicode_equal, wrap, wraptext | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2023 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,17 +22,20 @@ | |||
| Tests for the Wikicode class, which manages a list of nodes. | |||
| """ | |||
| from functools import partial | |||
| import re | |||
| from __future__ import annotations | |||
| import pickle | |||
| import re | |||
| from functools import partial | |||
| from types import GeneratorType | |||
| import pytest | |||
| from mwparserfromhell import parse | |||
| from mwparserfromhell.nodes import Argument, Heading, Template, Text | |||
| from mwparserfromhell.smart_list import SmartList | |||
| from mwparserfromhell.wikicode import Wikicode | |||
| from mwparserfromhell import parse | |||
| from .conftest import wrap, wraptext | |||
| @@ -1,4 +1,4 @@ | |||
| # Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com> | |||
| # | |||
| # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| # of this software and associated documentation files (the "Software"), to deal | |||
| @@ -22,9 +22,12 @@ | |||
| Test cases for the Wikilink node. | |||
| """ | |||
| from __future__ import annotations | |||
| import pytest | |||
| from mwparserfromhell.nodes import Text, Wikilink | |||
| from .conftest import assert_wikicode_equal, wrap, wraptext | |||