mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-08-20 05:13:21 -07:00
Bump beautifulsoup4 from 4.11.2 to 4.12.2 (#2037)
* Bump beautifulsoup4 from 4.11.2 to 4.12.2 Bumps [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/) from 4.11.2 to 4.12.2. --- updated-dependencies: - dependency-name: beautifulsoup4 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update beautifulsoup4==4.12.2 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> [skip ci]
This commit is contained in:
parent
1798594569
commit
e70e08c3f5
32 changed files with 1439 additions and 755 deletions
|
@ -32,7 +32,7 @@ from . import css_match as cm
|
|||
from . import css_types as ct
|
||||
from .util import DEBUG, SelectorSyntaxError # noqa: F401
|
||||
import bs4 # type: ignore[import]
|
||||
from typing import Optional, Any, Iterator, Iterable
|
||||
from typing import Any, Iterator, Iterable
|
||||
|
||||
__all__ = (
|
||||
'DEBUG', 'SelectorSyntaxError', 'SoupSieve',
|
||||
|
@ -45,10 +45,10 @@ SoupSieve = cm.SoupSieve
|
|||
|
||||
def compile( # noqa: A001
|
||||
pattern: str,
|
||||
namespaces: Optional[dict[str, str]] = None,
|
||||
namespaces: dict[str, str] | None = None,
|
||||
flags: int = 0,
|
||||
*,
|
||||
custom: Optional[dict[str, str]] = None,
|
||||
custom: dict[str, str] | None = None,
|
||||
**kwargs: Any
|
||||
) -> cm.SoupSieve:
|
||||
"""Compile CSS pattern."""
|
||||
|
@ -79,10 +79,10 @@ def purge() -> None:
|
|||
def closest(
|
||||
select: str,
|
||||
tag: 'bs4.Tag',
|
||||
namespaces: Optional[dict[str, str]] = None,
|
||||
namespaces: dict[str, str] | None = None,
|
||||
flags: int = 0,
|
||||
*,
|
||||
custom: Optional[dict[str, str]] = None,
|
||||
custom: dict[str, str] | None = None,
|
||||
**kwargs: Any
|
||||
) -> 'bs4.Tag':
|
||||
"""Match closest ancestor."""
|
||||
|
@ -93,10 +93,10 @@ def closest(
|
|||
def match(
|
||||
select: str,
|
||||
tag: 'bs4.Tag',
|
||||
namespaces: Optional[dict[str, str]] = None,
|
||||
namespaces: dict[str, str] | None = None,
|
||||
flags: int = 0,
|
||||
*,
|
||||
custom: Optional[dict[str, str]] = None,
|
||||
custom: dict[str, str] | None = None,
|
||||
**kwargs: Any
|
||||
) -> bool:
|
||||
"""Match node."""
|
||||
|
@ -107,10 +107,10 @@ def match(
|
|||
def filter( # noqa: A001
|
||||
select: str,
|
||||
iterable: Iterable['bs4.Tag'],
|
||||
namespaces: Optional[dict[str, str]] = None,
|
||||
namespaces: dict[str, str] | None = None,
|
||||
flags: int = 0,
|
||||
*,
|
||||
custom: Optional[dict[str, str]] = None,
|
||||
custom: dict[str, str] | None = None,
|
||||
**kwargs: Any
|
||||
) -> list['bs4.Tag']:
|
||||
"""Filter list of nodes."""
|
||||
|
@ -121,10 +121,10 @@ def filter( # noqa: A001
|
|||
def select_one(
|
||||
select: str,
|
||||
tag: 'bs4.Tag',
|
||||
namespaces: Optional[dict[str, str]] = None,
|
||||
namespaces: dict[str, str] | None = None,
|
||||
flags: int = 0,
|
||||
*,
|
||||
custom: Optional[dict[str, str]] = None,
|
||||
custom: dict[str, str] | None = None,
|
||||
**kwargs: Any
|
||||
) -> 'bs4.Tag':
|
||||
"""Select a single tag."""
|
||||
|
@ -135,11 +135,11 @@ def select_one(
|
|||
def select(
|
||||
select: str,
|
||||
tag: 'bs4.Tag',
|
||||
namespaces: Optional[dict[str, str]] = None,
|
||||
namespaces: dict[str, str] | None = None,
|
||||
limit: int = 0,
|
||||
flags: int = 0,
|
||||
*,
|
||||
custom: Optional[dict[str, str]] = None,
|
||||
custom: dict[str, str] | None = None,
|
||||
**kwargs: Any
|
||||
) -> list['bs4.Tag']:
|
||||
"""Select the specified tags."""
|
||||
|
@ -150,11 +150,11 @@ def select(
|
|||
def iselect(
|
||||
select: str,
|
||||
tag: 'bs4.Tag',
|
||||
namespaces: Optional[dict[str, str]] = None,
|
||||
namespaces: dict[str, str] | None = None,
|
||||
limit: int = 0,
|
||||
flags: int = 0,
|
||||
*,
|
||||
custom: Optional[dict[str, str]] = None,
|
||||
custom: dict[str, str] | None = None,
|
||||
**kwargs: Any
|
||||
) -> Iterator['bs4.Tag']:
|
||||
"""Iterate the specified tags."""
|
||||
|
|
|
@ -193,5 +193,5 @@ def parse_version(ver: str) -> Version:
|
|||
return Version(major, minor, micro, release, pre, post, dev)
|
||||
|
||||
|
||||
__version_info__ = Version(2, 4, 0, "final")
|
||||
__version_info__ = Version(2, 4, 1, "final")
|
||||
__version__ = __version_info__._get_canonical()
|
||||
|
|
|
@ -6,7 +6,7 @@ import re
|
|||
from . import css_types as ct
|
||||
import unicodedata
|
||||
import bs4 # type: ignore[import]
|
||||
from typing import Iterator, Iterable, Any, Optional, Callable, Sequence, cast # noqa: F401
|
||||
from typing import Iterator, Iterable, Any, Callable, Sequence, cast # noqa: F401
|
||||
|
||||
# Empty tag pattern (whitespace okay)
|
||||
RE_NOT_EMPTY = re.compile('[^ \t\r\n\f]')
|
||||
|
@ -171,7 +171,7 @@ class _DocumentNav:
|
|||
def get_children(
|
||||
self,
|
||||
el: bs4.Tag,
|
||||
start: Optional[int] = None,
|
||||
start: int | None = None,
|
||||
reverse: bool = False,
|
||||
tags: bool = True,
|
||||
no_iframe: bool = False
|
||||
|
@ -239,22 +239,22 @@ class _DocumentNav:
|
|||
return parent
|
||||
|
||||
@staticmethod
|
||||
def get_tag_name(el: bs4.Tag) -> Optional[str]:
|
||||
def get_tag_name(el: bs4.Tag) -> str | None:
|
||||
"""Get tag."""
|
||||
|
||||
return cast(Optional[str], el.name)
|
||||
return cast('str | None', el.name)
|
||||
|
||||
@staticmethod
|
||||
def get_prefix_name(el: bs4.Tag) -> Optional[str]:
|
||||
def get_prefix_name(el: bs4.Tag) -> str | None:
|
||||
"""Get prefix."""
|
||||
|
||||
return cast(Optional[str], el.prefix)
|
||||
return cast('str | None', el.prefix)
|
||||
|
||||
@staticmethod
|
||||
def get_uri(el: bs4.Tag) -> Optional[str]:
|
||||
def get_uri(el: bs4.Tag) -> str | None:
|
||||
"""Get namespace `URI`."""
|
||||
|
||||
return cast(Optional[str], el.namespace)
|
||||
return cast('str | None', el.namespace)
|
||||
|
||||
@classmethod
|
||||
def get_next(cls, el: bs4.Tag, tags: bool = True) -> bs4.PageElement:
|
||||
|
@ -287,7 +287,7 @@ class _DocumentNav:
|
|||
return bool(ns and ns == NS_XHTML)
|
||||
|
||||
@staticmethod
|
||||
def split_namespace(el: bs4.Tag, attr_name: str) -> tuple[Optional[str], Optional[str]]:
|
||||
def split_namespace(el: bs4.Tag, attr_name: str) -> tuple[str | None, str | None]:
|
||||
"""Return namespace and attribute name without the prefix."""
|
||||
|
||||
return getattr(attr_name, 'namespace', None), getattr(attr_name, 'name', None)
|
||||
|
@ -330,8 +330,8 @@ class _DocumentNav:
|
|||
cls,
|
||||
el: bs4.Tag,
|
||||
name: str,
|
||||
default: Optional[str | Sequence[str]] = None
|
||||
) -> Optional[str | Sequence[str]]:
|
||||
default: str | Sequence[str] | None = None
|
||||
) -> str | Sequence[str] | None:
|
||||
"""Get attribute by name."""
|
||||
|
||||
value = default
|
||||
|
@ -348,7 +348,7 @@ class _DocumentNav:
|
|||
return value
|
||||
|
||||
@classmethod
|
||||
def iter_attributes(cls, el: bs4.Tag) -> Iterator[tuple[str, Optional[str | Sequence[str]]]]:
|
||||
def iter_attributes(cls, el: bs4.Tag) -> Iterator[tuple[str, str | Sequence[str] | None]]:
|
||||
"""Iterate attributes."""
|
||||
|
||||
for k, v in el.attrs.items():
|
||||
|
@ -424,10 +424,10 @@ class Inputs:
|
|||
return 0 <= minutes <= 59
|
||||
|
||||
@classmethod
|
||||
def parse_value(cls, itype: str, value: Optional[str]) -> Optional[tuple[float, ...]]:
|
||||
def parse_value(cls, itype: str, value: str | None) -> tuple[float, ...] | None:
|
||||
"""Parse the input value."""
|
||||
|
||||
parsed = None # type: Optional[tuple[float, ...]]
|
||||
parsed = None # type: tuple[float, ...] | None
|
||||
if value is None:
|
||||
return value
|
||||
if itype == "date":
|
||||
|
@ -486,7 +486,7 @@ class CSSMatch(_DocumentNav):
|
|||
self,
|
||||
selectors: ct.SelectorList,
|
||||
scope: bs4.Tag,
|
||||
namespaces: Optional[ct.Namespaces],
|
||||
namespaces: ct.Namespaces | None,
|
||||
flags: int
|
||||
) -> None:
|
||||
"""Initialize."""
|
||||
|
@ -545,19 +545,19 @@ class CSSMatch(_DocumentNav):
|
|||
|
||||
return self.get_tag_ns(el) == NS_XHTML
|
||||
|
||||
def get_tag(self, el: bs4.Tag) -> Optional[str]:
|
||||
def get_tag(self, el: bs4.Tag) -> str | None:
|
||||
"""Get tag."""
|
||||
|
||||
name = self.get_tag_name(el)
|
||||
return util.lower(name) if name is not None and not self.is_xml else name
|
||||
|
||||
def get_prefix(self, el: bs4.Tag) -> Optional[str]:
|
||||
def get_prefix(self, el: bs4.Tag) -> str | None:
|
||||
"""Get prefix."""
|
||||
|
||||
prefix = self.get_prefix_name(el)
|
||||
return util.lower(prefix) if prefix is not None and not self.is_xml else prefix
|
||||
|
||||
def find_bidi(self, el: bs4.Tag) -> Optional[int]:
|
||||
def find_bidi(self, el: bs4.Tag) -> int | None:
|
||||
"""Get directionality from element text."""
|
||||
|
||||
for node in self.get_children(el, tags=False):
|
||||
|
@ -653,8 +653,8 @@ class CSSMatch(_DocumentNav):
|
|||
self,
|
||||
el: bs4.Tag,
|
||||
attr: str,
|
||||
prefix: Optional[str]
|
||||
) -> Optional[str | Sequence[str]]:
|
||||
prefix: str | None
|
||||
) -> str | Sequence[str] | None:
|
||||
"""Match attribute name and return value if it exists."""
|
||||
|
||||
value = None
|
||||
|
@ -751,7 +751,7 @@ class CSSMatch(_DocumentNav):
|
|||
name not in (self.get_tag(el), '*')
|
||||
)
|
||||
|
||||
def match_tag(self, el: bs4.Tag, tag: Optional[ct.SelectorTag]) -> bool:
|
||||
def match_tag(self, el: bs4.Tag, tag: ct.SelectorTag | None) -> bool:
|
||||
"""Match the tag."""
|
||||
|
||||
match = True
|
||||
|
@ -1030,7 +1030,7 @@ class CSSMatch(_DocumentNav):
|
|||
"""Match element if it contains text."""
|
||||
|
||||
match = True
|
||||
content = None # type: Optional[str | Sequence[str]]
|
||||
content = None # type: str | Sequence[str] | None
|
||||
for contain_list in contains:
|
||||
if content is None:
|
||||
if contain_list.own:
|
||||
|
@ -1099,7 +1099,7 @@ class CSSMatch(_DocumentNav):
|
|||
match = False
|
||||
name = cast(str, self.get_attribute_by_name(el, 'name'))
|
||||
|
||||
def get_parent_form(el: bs4.Tag) -> Optional[bs4.Tag]:
|
||||
def get_parent_form(el: bs4.Tag) -> bs4.Tag | None:
|
||||
"""Find this input's form."""
|
||||
form = None
|
||||
parent = self.get_parent(el, no_iframe=True)
|
||||
|
@ -1478,7 +1478,7 @@ class CSSMatch(_DocumentNav):
|
|||
if lim < 1:
|
||||
break
|
||||
|
||||
def closest(self) -> Optional[bs4.Tag]:
|
||||
def closest(self) -> bs4.Tag | None:
|
||||
"""Match closest ancestor."""
|
||||
|
||||
current = self.tag
|
||||
|
@ -1506,7 +1506,7 @@ class SoupSieve(ct.Immutable):
|
|||
|
||||
pattern: str
|
||||
selectors: ct.SelectorList
|
||||
namespaces: Optional[ct.Namespaces]
|
||||
namespaces: ct.Namespaces | None
|
||||
custom: dict[str, str]
|
||||
flags: int
|
||||
|
||||
|
@ -1516,8 +1516,8 @@ class SoupSieve(ct.Immutable):
|
|||
self,
|
||||
pattern: str,
|
||||
selectors: ct.SelectorList,
|
||||
namespaces: Optional[ct.Namespaces],
|
||||
custom: Optional[ct.CustomSelectors],
|
||||
namespaces: ct.Namespaces | None,
|
||||
custom: ct.CustomSelectors | None,
|
||||
flags: int
|
||||
):
|
||||
"""Initialize."""
|
||||
|
|
|
@ -7,7 +7,7 @@ from . import css_match as cm
|
|||
from . import css_types as ct
|
||||
from .util import SelectorSyntaxError
|
||||
import warnings
|
||||
from typing import Optional, Match, Any, Iterator, cast
|
||||
from typing import Match, Any, Iterator, cast
|
||||
|
||||
UNICODE_REPLACEMENT_CHAR = 0xFFFD
|
||||
|
||||
|
@ -113,7 +113,7 @@ VALUE = r'''
|
|||
'''.format(nl=NEWLINE, ident=IDENTIFIER)
|
||||
# Attribute value comparison. `!=` is handled special as it is non-standard.
|
||||
ATTR = r'''
|
||||
(?:{ws}*(?P<cmp>[!~^|*$]?=){ws}*(?P<value>{value})(?:{ws}+(?P<case>[is]))?)?{ws}*\]
|
||||
(?:{ws}*(?P<cmp>[!~^|*$]?=){ws}*(?P<value>{value})(?:{ws}*(?P<case>[is]))?)?{ws}*\]
|
||||
'''.format(ws=WSC, value=VALUE)
|
||||
|
||||
# Selector patterns
|
||||
|
@ -207,8 +207,8 @@ _MAXCACHE = 500
|
|||
@lru_cache(maxsize=_MAXCACHE)
|
||||
def _cached_css_compile(
|
||||
pattern: str,
|
||||
namespaces: Optional[ct.Namespaces],
|
||||
custom: Optional[ct.CustomSelectors],
|
||||
namespaces: ct.Namespaces | None,
|
||||
custom: ct.CustomSelectors | None,
|
||||
flags: int
|
||||
) -> cm.SoupSieve:
|
||||
"""Cached CSS compile."""
|
||||
|
@ -233,7 +233,7 @@ def _purge_cache() -> None:
|
|||
_cached_css_compile.cache_clear()
|
||||
|
||||
|
||||
def process_custom(custom: Optional[ct.CustomSelectors]) -> dict[str, str | ct.SelectorList]:
|
||||
def process_custom(custom: ct.CustomSelectors | None) -> dict[str, str | ct.SelectorList]:
|
||||
"""Process custom."""
|
||||
|
||||
custom_selectors = {}
|
||||
|
@ -317,7 +317,7 @@ class SelectorPattern:
|
|||
|
||||
return self.name
|
||||
|
||||
def match(self, selector: str, index: int, flags: int) -> Optional[Match[str]]:
|
||||
def match(self, selector: str, index: int, flags: int) -> Match[str] | None:
|
||||
"""Match the selector."""
|
||||
|
||||
return self.re_pattern.match(selector, index)
|
||||
|
@ -336,7 +336,7 @@ class SpecialPseudoPattern(SelectorPattern):
|
|||
for pseudo in p[1]:
|
||||
self.patterns[pseudo] = pattern
|
||||
|
||||
self.matched_name = None # type: Optional[SelectorPattern]
|
||||
self.matched_name = None # type: SelectorPattern | None
|
||||
self.re_pseudo_name = re.compile(PAT_PSEUDO_CLASS_SPECIAL, re.I | re.X | re.U)
|
||||
|
||||
def get_name(self) -> str:
|
||||
|
@ -344,7 +344,7 @@ class SpecialPseudoPattern(SelectorPattern):
|
|||
|
||||
return '' if self.matched_name is None else self.matched_name.get_name()
|
||||
|
||||
def match(self, selector: str, index: int, flags: int) -> Optional[Match[str]]:
|
||||
def match(self, selector: str, index: int, flags: int) -> Match[str] | None:
|
||||
"""Match the selector."""
|
||||
|
||||
pseudo = None
|
||||
|
@ -372,14 +372,14 @@ class _Selector:
|
|||
def __init__(self, **kwargs: Any) -> None:
|
||||
"""Initialize."""
|
||||
|
||||
self.tag = kwargs.get('tag', None) # type: Optional[ct.SelectorTag]
|
||||
self.tag = kwargs.get('tag', None) # type: ct.SelectorTag | None
|
||||
self.ids = kwargs.get('ids', []) # type: list[str]
|
||||
self.classes = kwargs.get('classes', []) # type: list[str]
|
||||
self.attributes = kwargs.get('attributes', []) # type: list[ct.SelectorAttribute]
|
||||
self.nth = kwargs.get('nth', []) # type: list[ct.SelectorNth]
|
||||
self.selectors = kwargs.get('selectors', []) # type: list[ct.SelectorList]
|
||||
self.relations = kwargs.get('relations', []) # type: list[_Selector]
|
||||
self.rel_type = kwargs.get('rel_type', None) # type: Optional[str]
|
||||
self.rel_type = kwargs.get('rel_type', None) # type: str | None
|
||||
self.contains = kwargs.get('contains', []) # type: list[ct.SelectorContains]
|
||||
self.lang = kwargs.get('lang', []) # type: list[ct.SelectorLang]
|
||||
self.flags = kwargs.get('flags', 0) # type: int
|
||||
|
@ -462,7 +462,7 @@ class CSSParser:
|
|||
def __init__(
|
||||
self,
|
||||
selector: str,
|
||||
custom: Optional[dict[str, str | ct.SelectorList]] = None,
|
||||
custom: dict[str, str | ct.SelectorList] | None = None,
|
||||
flags: int = 0
|
||||
) -> None:
|
||||
"""Initialize."""
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
from __future__ import annotations
|
||||
import copyreg
|
||||
from .pretty import pretty
|
||||
from typing import Any, Iterator, Hashable, Optional, Pattern, Iterable, Mapping
|
||||
from typing import Any, Iterator, Hashable, Pattern, Iterable, Mapping
|
||||
|
||||
__all__ = (
|
||||
'Selector',
|
||||
|
@ -189,28 +189,28 @@ class Selector(Immutable):
|
|||
'relation', 'rel_type', 'contains', 'lang', 'flags', '_hash'
|
||||
)
|
||||
|
||||
tag: Optional[SelectorTag]
|
||||
tag: SelectorTag | None
|
||||
ids: tuple[str, ...]
|
||||
classes: tuple[str, ...]
|
||||
attributes: tuple[SelectorAttribute, ...]
|
||||
nth: tuple[SelectorNth, ...]
|
||||
selectors: tuple[SelectorList, ...]
|
||||
relation: SelectorList
|
||||
rel_type: Optional[str]
|
||||
rel_type: str | None
|
||||
contains: tuple[SelectorContains, ...]
|
||||
lang: tuple[SelectorLang, ...]
|
||||
flags: int
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
tag: Optional[SelectorTag],
|
||||
tag: SelectorTag | None,
|
||||
ids: tuple[str, ...],
|
||||
classes: tuple[str, ...],
|
||||
attributes: tuple[SelectorAttribute, ...],
|
||||
nth: tuple[SelectorNth, ...],
|
||||
selectors: tuple[SelectorList, ...],
|
||||
relation: SelectorList,
|
||||
rel_type: Optional[str],
|
||||
rel_type: str | None,
|
||||
contains: tuple[SelectorContains, ...],
|
||||
lang: tuple[SelectorLang, ...],
|
||||
flags: int
|
||||
|
@ -247,9 +247,9 @@ class SelectorTag(Immutable):
|
|||
__slots__ = ("name", "prefix", "_hash")
|
||||
|
||||
name: str
|
||||
prefix: Optional[str]
|
||||
prefix: str | None
|
||||
|
||||
def __init__(self, name: str, prefix: Optional[str]) -> None:
|
||||
def __init__(self, name: str, prefix: str | None) -> None:
|
||||
"""Initialize."""
|
||||
|
||||
super().__init__(name=name, prefix=prefix)
|
||||
|
@ -262,15 +262,15 @@ class SelectorAttribute(Immutable):
|
|||
|
||||
attribute: str
|
||||
prefix: str
|
||||
pattern: Optional[Pattern[str]]
|
||||
xml_type_pattern: Optional[Pattern[str]]
|
||||
pattern: Pattern[str] | None
|
||||
xml_type_pattern: Pattern[str] | None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
attribute: str,
|
||||
prefix: str,
|
||||
pattern: Optional[Pattern[str]],
|
||||
xml_type_pattern: Optional[Pattern[str]]
|
||||
pattern: Pattern[str] | None,
|
||||
xml_type_pattern: Pattern[str] | None
|
||||
) -> None:
|
||||
"""Initialize."""
|
||||
|
||||
|
@ -360,7 +360,7 @@ class SelectorList(Immutable):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
selectors: Optional[Iterable[Selector | SelectorNull]] = None,
|
||||
selectors: Iterable[Selector | SelectorNull] | None = None,
|
||||
is_not: bool = False,
|
||||
is_html: bool = False
|
||||
) -> None:
|
||||
|
|
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||
from functools import wraps, lru_cache
|
||||
import warnings
|
||||
import re
|
||||
from typing import Callable, Any, Optional
|
||||
from typing import Callable, Any
|
||||
|
||||
DEBUG = 0x00001
|
||||
|
||||
|
@ -27,7 +27,7 @@ def lower(string: str) -> str:
|
|||
class SelectorSyntaxError(Exception):
|
||||
"""Syntax error in a CSS selector."""
|
||||
|
||||
def __init__(self, msg: str, pattern: Optional[str] = None, index: Optional[int] = None) -> None:
|
||||
def __init__(self, msg: str, pattern: str | None = None, index: int | None = None) -> None:
|
||||
"""Initialize."""
|
||||
|
||||
self.line = None
|
||||
|
@ -84,7 +84,7 @@ def get_pattern_context(pattern: str, index: int) -> tuple[str, int, int]:
|
|||
col = 1
|
||||
text = [] # type: list[str]
|
||||
line = 1
|
||||
offset = None # type: Optional[int]
|
||||
offset = None # type: int | None
|
||||
|
||||
# Split pattern by newline and handle the text before the newline
|
||||
for m in RE_PATTERN_LINE_SPLIT.finditer(pattern):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue