Skip to content

Commit

Permalink
Replace use of Optional in type annotations
Browse files Browse the repository at this point in the history
Since we use `from __future__ import annotations` type annotations
will be ignored as strings. We can use `type | None` even on older
Python versions.
  • Loading branch information
facelessuser committed Feb 17, 2023
1 parent 1615584 commit 2553dbd
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 67 deletions.
30 changes: 15 additions & 15 deletions soupsieve/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
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',
Expand All @@ -45,10 +45,10 @@

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."""
Expand Down Expand Up @@ -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."""
Expand All @@ -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."""
Expand All @@ -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."""
Expand All @@ -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."""
Expand All @@ -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."""
Expand All @@ -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."""
Expand Down
54 changes: 27 additions & 27 deletions soupsieve/css_match.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
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]')
Expand Down Expand Up @@ -171,7 +171,7 @@ def get_contents(self, el: bs4.Tag, no_iframe: bool = False) -> Iterator[bs4.Pag
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
Expand Down Expand Up @@ -239,22 +239,22 @@ def get_parent(self, el: bs4.Tag, no_iframe: bool = False) -> bs4.Tag:
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:
Expand Down Expand Up @@ -287,7 +287,7 @@ def has_html_ns(el: bs4.Tag) -> bool:
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)
Expand Down Expand Up @@ -330,8 +330,8 @@ def get_attribute_by_name(
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
Expand All @@ -348,7 +348,7 @@ def get_attribute_by_name(
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():
Expand Down Expand Up @@ -424,10 +424,10 @@ def validate_minutes(minutes: int) -> bool:
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":
Expand Down Expand Up @@ -486,7 +486,7 @@ def __init__(
self,
selectors: ct.SelectorList,
scope: bs4.Tag,
namespaces: Optional[ct.Namespaces],
namespaces: ct.Namespaces | None,
flags: int
) -> None:
"""Initialize."""
Expand Down Expand Up @@ -545,19 +545,19 @@ def is_html_tag(self, el: bs4.Tag) -> bool:

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):
Expand Down Expand Up @@ -653,8 +653,8 @@ def match_attribute_name(
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
Expand Down Expand Up @@ -751,7 +751,7 @@ def match_tagname(self, el: bs4.Tag, tag: ct.SelectorTag) -> bool:
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
Expand Down Expand Up @@ -1030,7 +1030,7 @@ def match_contains(self, el: bs4.Tag, contains: tuple[ct.SelectorContains, ...])
"""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:
Expand Down Expand Up @@ -1099,7 +1099,7 @@ def match_indeterminate(self, el: bs4.Tag) -> bool:
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)
Expand Down Expand Up @@ -1478,7 +1478,7 @@ def select(self, limit: int = 0) -> Iterator[bs4.Tag]:
if lim < 1:
break

def closest(self) -> Optional[bs4.Tag]:
def closest(self) -> bs4.Tag | None:
"""Match closest ancestor."""

current = self.tag
Expand Down Expand Up @@ -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

Expand All @@ -1516,8 +1516,8 @@ def __init__(
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."""
Expand Down
20 changes: 10 additions & 10 deletions soupsieve/css_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
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

Expand Down Expand Up @@ -207,8 +207,8 @@
@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."""
Expand All @@ -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 = {}
Expand Down Expand Up @@ -317,7 +317,7 @@ def get_name(self) -> str:

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)
Expand All @@ -336,15 +336,15 @@ def __init__(self, patterns: tuple[tuple[str, tuple[str, ...], str, type[Selecto
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:
"""Get name."""

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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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."""
Expand Down
Loading

0 comments on commit 2553dbd

Please sign in to comment.