style(autocompletion): Improving type hints for custom types

This will provide a better autocompletion experience inside IDEs, commit affects:
- TextHandler
- AttributesHandler
This commit is contained in:
Karim shoair
2025-01-29 00:58:14 +02:00
parent 85f98708b2
commit 5047e886a5
2 changed files with 32 additions and 28 deletions
+2 -1
View File
@@ -3,7 +3,8 @@ Type definitions for type checking purposes.
""" """
from typing import (TYPE_CHECKING, Any, Callable, Dict, Generator, Iterable, from typing import (TYPE_CHECKING, Any, Callable, Dict, Generator, Iterable,
List, Literal, Optional, Pattern, Tuple, Type, Union) List, Literal, Optional, Pattern, Tuple, Type, TypeVar,
Union)
SelectorWaitStates = Literal["attached", "detached", "hidden", "visible"] SelectorWaitStates = Literal["attached", "detached", "hidden", "visible"]
+30 -27
View File
@@ -5,9 +5,13 @@ from types import MappingProxyType
from orjson import dumps, loads from orjson import dumps, loads
from w3lib.html import replace_entities as _replace_entities from w3lib.html import replace_entities as _replace_entities
from scrapling.core._types import Dict, List, Pattern, SupportsIndex, Union from scrapling.core._types import (Dict, Iterable, List, Optional, Pattern,
SupportsIndex, TypeVar, Union)
from scrapling.core.utils import _is_iterable, flatten from scrapling.core.utils import _is_iterable, flatten
# Define type variable for AttributeHandler value type
VT = TypeVar('VT', bound='TextHandler')
class TextHandler(str): class TextHandler(str):
"""Extends standard Python string by adding more functionality""" """Extends standard Python string by adding more functionality"""
@@ -19,71 +23,70 @@ class TextHandler(str):
return super().__new__(cls, '') return super().__new__(cls, '')
# Make methods from original `str` class return `TextHandler` instead of returning `str` again # Make methods from original `str` class return `TextHandler` instead of returning `str` again
# Of course, this stupid workaround is only so we can keep the auto-completion working without issues in your IDE # Of course, I made sonnet write it for me :)
# and I made sonnet write it for me :) def strip(self, chars: str = None) -> Union[str, 'TextHandler']:
def strip(self, chars=None):
return TextHandler(super().strip(chars)) return TextHandler(super().strip(chars))
def lstrip(self, chars=None): def lstrip(self, chars: str = None) -> Union[str, 'TextHandler']:
return TextHandler(super().lstrip(chars)) return TextHandler(super().lstrip(chars))
def rstrip(self, chars=None): def rstrip(self, chars: str = None) -> Union[str, 'TextHandler']:
return TextHandler(super().rstrip(chars)) return TextHandler(super().rstrip(chars))
def capitalize(self): def capitalize(self) -> Union[str, 'TextHandler']:
return TextHandler(super().capitalize()) return TextHandler(super().capitalize())
def casefold(self): def casefold(self) -> Union[str, 'TextHandler']:
return TextHandler(super().casefold()) return TextHandler(super().casefold())
def center(self, width, fillchar=' '): def center(self, width: SupportsIndex, fillchar: str = ' ') -> Union[str, 'TextHandler']:
return TextHandler(super().center(width, fillchar)) return TextHandler(super().center(width, fillchar))
def expandtabs(self, tabsize=8): def expandtabs(self, tabsize: SupportsIndex = 8) -> Union[str, 'TextHandler']:
return TextHandler(super().expandtabs(tabsize)) return TextHandler(super().expandtabs(tabsize))
def format(self, *args, **kwargs): def format(self, *args: str, **kwargs: str) -> Union[str, 'TextHandler']:
return TextHandler(super().format(*args, **kwargs)) return TextHandler(super().format(*args, **kwargs))
def format_map(self, mapping): def format_map(self, mapping) -> Union[str, 'TextHandler']:
return TextHandler(super().format_map(mapping)) return TextHandler(super().format_map(mapping))
def join(self, iterable): def join(self, iterable: Iterable[str]) -> Union[str, 'TextHandler']:
return TextHandler(super().join(iterable)) return TextHandler(super().join(iterable))
def ljust(self, width, fillchar=' '): def ljust(self, width: SupportsIndex, fillchar: str = ' ') -> Union[str, 'TextHandler']:
return TextHandler(super().ljust(width, fillchar)) return TextHandler(super().ljust(width, fillchar))
def rjust(self, width, fillchar=' '): def rjust(self, width: SupportsIndex, fillchar: str = ' ') -> Union[str, 'TextHandler']:
return TextHandler(super().rjust(width, fillchar)) return TextHandler(super().rjust(width, fillchar))
def swapcase(self): def swapcase(self) -> Union[str, 'TextHandler']:
return TextHandler(super().swapcase()) return TextHandler(super().swapcase())
def title(self): def title(self) -> Union[str, 'TextHandler']:
return TextHandler(super().title()) return TextHandler(super().title())
def translate(self, table): def translate(self, table) -> Union[str, 'TextHandler']:
return TextHandler(super().translate(table)) return TextHandler(super().translate(table))
def zfill(self, width): def zfill(self, width: SupportsIndex) -> Union[str, 'TextHandler']:
return TextHandler(super().zfill(width)) return TextHandler(super().zfill(width))
def replace(self, old, new, count=-1): def replace(self, old: str, new: str, count: SupportsIndex = -1) -> Union[str, 'TextHandler']:
return TextHandler(super().replace(old, new, count)) return TextHandler(super().replace(old, new, count))
def upper(self): def upper(self) -> Union[str, 'TextHandler']:
return TextHandler(super().upper()) return TextHandler(super().upper())
def lower(self): def lower(self) -> Union[str, 'TextHandler']:
return TextHandler(super().lower()) return TextHandler(super().lower())
############## ##############
def sort(self, reverse: bool = False) -> str: def sort(self, reverse: bool = False) -> Union[str, 'TextHandler']:
"""Return a sorted version of the string""" """Return a sorted version of the string"""
return self.__class__("".join(sorted(self, reverse=reverse))) return self.__class__("".join(sorted(self, reverse=reverse)))
def clean(self) -> str: def clean(self) -> Union[str, 'TextHandler']:
"""Return a new version of the string after removing all white spaces and consecutive spaces""" """Return a new version of the string after removing all white spaces and consecutive spaces"""
data = re.sub(r'[\t|\r|\n]', '', self) data = re.sub(r'[\t|\r|\n]', '', self)
data = re.sub(' +', ' ', data) data = re.sub(' +', ' ', data)
@@ -210,7 +213,7 @@ class TextHandlers(List[TextHandler]):
get_all = extract get_all = extract
class AttributesHandler(Mapping): class AttributesHandler(Mapping[str, VT]):
"""A read-only mapping to use instead of the standard dictionary for the speed boost but at the same time I use it to add more functionalities. """A read-only mapping to use instead of the standard dictionary for the speed boost but at the same time I use it to add more functionalities.
If standard dictionary is needed, just convert this class to dictionary with `dict` function If standard dictionary is needed, just convert this class to dictionary with `dict` function
""" """
@@ -231,7 +234,7 @@ class AttributesHandler(Mapping):
# Fastest read-only mapping type # Fastest read-only mapping type
self._data = MappingProxyType(mapping) self._data = MappingProxyType(mapping)
def get(self, key, default=None): def get(self, key: str, default: Optional[str] = None) -> Union[VT, None]:
"""Acts like standard dictionary `.get()` method""" """Acts like standard dictionary `.get()` method"""
return self._data.get(key, default) return self._data.get(key, default)
@@ -253,7 +256,7 @@ class AttributesHandler(Mapping):
"""Convert current attributes to JSON string if the attributes are JSON serializable otherwise throws error""" """Convert current attributes to JSON string if the attributes are JSON serializable otherwise throws error"""
return dumps(dict(self._data)) return dumps(dict(self._data))
def __getitem__(self, key): def __getitem__(self, key: str) -> VT:
return self._data[key] return self._data[key]
def __iter__(self): def __iter__(self):