From a6ce6fdce600cfd2faf3910d3a7331411e378279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oleg=20H=C3=B6fling?= Date: Sat, 14 Aug 2021 12:33:32 +0200 Subject: [PATCH] More specific type hints for `dateparser` (#5920) Signed-off-by: oleg.hoefling --- stubs/dateparser/dateparser/__init__.pyi | 33 ++++- stubs/dateparser/dateparser/date.pyi | 125 +++++++++++++----- .../dateparser/languages/locale.pyi | 26 ++-- 3 files changed, 136 insertions(+), 48 deletions(-) diff --git a/stubs/dateparser/dateparser/__init__.pyi b/stubs/dateparser/dateparser/__init__.pyi index 73c4d87f1997..2a137ef9ecff 100644 --- a/stubs/dateparser/dateparser/__init__.pyi +++ b/stubs/dateparser/dateparser/__init__.pyi @@ -1,13 +1,42 @@ import datetime -from typing import Any, Mapping, Set, Tuple +import sys +from typing import Set, Tuple + +from dateparser.date import DateDataParser + +if sys.version_info >= (3, 8): + from typing import Literal, TypedDict +else: + from typing_extensions import Literal, TypedDict __version__: str +_default_parser: DateDataParser + +_Part = Literal["day", "month", "year"] +_ParserKind = Literal["timestamp", "relative-time", "custom-formats", "absolute-time", "no-spaces-time"] + +class _Settings(TypedDict, total=False): + DATE_ORDER: str + PREFER_LOCALE_DATE_ORDER: bool + TIMEZONE: str + TO_TIMEZONE: str + RETURN_AS_TIMEZONE_AWARE: bool + PREFER_DAY_OF_MONTH: Literal["current", "first", "last"] + PREFER_DATES_FROM: Literal["current_period", "future", "past"] + RELATIVE_BASE: datetime.datetime + STRICT_PARSING: bool + REQUIRE_PARTS: list[_Part] + SKIP_TOKENS: list[str] + NORMALIZE: bool + RETURN_TIME_AS_PERIOD: bool + PARSERS: list[_ParserKind] + def parse( date_string: str, date_formats: list[str] | Tuple[str] | Set[str] | None = ..., languages: list[str] | Tuple[str] | Set[str] | None = ..., locales: list[str] | Tuple[str] | Set[str] | None = ..., region: str | None = ..., - settings: Mapping[str, Any] | None = ..., + settings: _Settings | None = ..., ) -> datetime.datetime | None: ... diff --git a/stubs/dateparser/dateparser/date.pyi b/stubs/dateparser/dateparser/date.pyi index 96d1530a1282..f39d15ffe794 100644 --- a/stubs/dateparser/dateparser/date.pyi +++ b/stubs/dateparser/dateparser/date.pyi @@ -1,56 +1,109 @@ -from typing import Any +import sys +from _typeshed import Self as Self +from datetime import datetime +from typing import Any, ClassVar, Iterable, Iterator, Type, overload -APOSTROPHE_LOOK_ALIKE_CHARS: Any -RE_NBSP: Any -RE_SPACES: Any -RE_TRIM_SPACES: Any -RE_TRIM_COLONS: Any -RE_SANITIZE_SKIP: Any -RE_SANITIZE_RUSSIAN: Any -RE_SANITIZE_PERIOD: Any -RE_SANITIZE_ON: Any -RE_SANITIZE_APOSTROPHE: Any -RE_SEARCH_TIMESTAMP: Any +from dateparser import _Settings +from dateparser.conf import Settings +from dateparser.languages.loader import LocaleDataLoader +from dateparser.languages.locale import Locale -def sanitize_spaces(date_string): ... +if sys.version_info >= (3, 8): + from re import Pattern + from typing import Literal +else: + from typing import Pattern + from typing_extensions import Literal + +_Period = Literal["time", "day", "week", "month", "year"] +APOSTROPHE_LOOK_ALIKE_CHARS: list[str] +RE_NBSP: Pattern[str] +RE_SPACES: Pattern[str] +RE_TRIM_SPACES: Pattern[str] +RE_TRIM_COLONS: Pattern[str] +RE_SANITIZE_SKIP: Pattern[str] +RE_SANITIZE_RUSSIAN: Pattern[str] +RE_SANITIZE_PERIOD: Pattern[str] +RE_SANITIZE_ON: Pattern[str] +RE_SANITIZE_APOSTROPHE: Pattern[str] +RE_SEARCH_TIMESTAMP: Pattern[str] + +def sanitize_spaces(date_string: str) -> str: ... def date_range(begin, end, **kwargs) -> None: ... def get_intersecting_periods(low, high, period: str = ...) -> None: ... -def sanitize_date(date_string): ... -def get_date_from_timestamp(date_string, settings): ... -def parse_with_formats(date_string, date_formats, settings): ... +def sanitize_date(date_string: str) -> str: ... +def get_date_from_timestamp(date_string: str, settings: Settings) -> datetime | None: ... +def parse_with_formats(date_string: str, date_formats: Iterable[str], settings: Settings) -> DateData: ... class _DateLocaleParser: - locale: Any - date_string: Any - date_formats: Any - def __init__(self, locale, date_string, date_formats, settings: Any | None = ...) -> None: ... + locale: Locale + date_string: str + date_formats: list[str] | tuple[str] | set[str] | None + def __init__( + self, + locale: Locale, + date_string: str, + date_formats: list[str] | tuple[str] | set[str] | None, + settings: Settings | None = ..., + ) -> None: ... @classmethod - def parse(cls, locale, date_string, date_formats: Any | None = ..., settings: Any | None = ...): ... + def parse( + cls, + locale: Locale, + date_string: str, + date_formats: list[str] | tuple[str] | set[str] | None = ..., + settings: Settings | None = ..., + ) -> DateData: ... + def _parse(self) -> DateData | None: ... + def _try_timestamp(self) -> DateData: ... + def _try_freshness_parser(self) -> DateData | None: ... + def _try_absolute_parser(self) -> DateData | None: ... + def _try_nospaces_parser(self) -> DateData | None: ... + def _try_parser(self, parse_method) -> DateData | None: ... + def _try_given_formats(self) -> DateData | None: ... + def _get_translated_date(self) -> str: ... + def _get_translated_date_with_formatting(self) -> str: ... + def _is_valid_date_data(self, date_data: DateData) -> bool: ... class DateData: - date_obj: Any - period: Any - locale: Any - def __init__(self, *, date_obj: Any | None = ..., period: Any | None = ..., locale: Any | None = ...) -> None: ... - def __getitem__(self, k): ... - def __setitem__(self, k, v) -> None: ... + date_obj: datetime | None + locale: str | None + period: _Period | None + def __init__(self, *, date_obj: datetime | None = ..., period: _Period | None = ..., locale: str | None = ...) -> None: ... + @overload + def __getitem__(self, k: Literal["date_obj"]) -> datetime | None: ... + @overload + def __getitem__(self, k: Literal["locale"]) -> str | None: ... + @overload + def __getitem__(self, k: Literal["period"]) -> _Period | None: ... + @overload + def __setitem__(self, k: Literal["date_obj"], v: datetime) -> None: ... + @overload + def __setitem__(self, k: Literal["locale"], v: str) -> None: ... + @overload + def __setitem__(self, k: Literal["period"], v: _Period) -> None: ... class DateDataParser: - locale_loader: Any - try_previous_locales: Any - use_given_order: Any + _settings: Settings + locale_loader: ClassVar[LocaleDataLoader | None] + try_previous_locales: bool + use_given_order: bool languages: Any locales: Any region: Any previous_locales: Any def __init__( self, - languages: Any | None = ..., - locales: Any | None = ..., - region: Any | None = ..., + languages: list[str] | tuple[str] | set[str] | None = ..., + locales: list[str] | tuple[str] | set[str] | None = ..., + region: str | None = ..., try_previous_locales: bool = ..., use_given_order: bool = ..., - settings: Any | None = ..., + settings: _Settings | None = ..., ) -> None: ... - def get_date_data(self, date_string, date_formats: Any | None = ...): ... - def get_date_tuple(self, *args, **kwargs): ... + def get_date_data(self, date_string: str, date_formats: list[str] | tuple[str] | set[str] | None = ...) -> DateData: ... + def get_date_tuple(self, date_string: str, date_formats: list[str] | tuple[str] | set[str] | None = ...): ... + def _get_applicable_locales(self, date_string: str) -> Iterator[Locale]: ... + def _is_applicable_locale(self, locale: Locale, date_string: str) -> bool: ... + @classmethod + def _get_locale_loader(cls: Type[DateDataParser]) -> LocaleDataLoader: ... diff --git a/stubs/dateparser/dateparser/languages/locale.pyi b/stubs/dateparser/dateparser/languages/locale.pyi index 7b0bf75c3de7..1c91e2659929 100644 --- a/stubs/dateparser/dateparser/languages/locale.pyi +++ b/stubs/dateparser/dateparser/languages/locale.pyi @@ -1,17 +1,23 @@ -from typing import Any +import sys -DIGIT_GROUP_PATTERN: Any -NUMERAL_PATTERN: Any +from dateparser.conf import Settings + +if sys.version_info >= (3, 8): + from re import Pattern +else: + from typing import Pattern + +DIGIT_GROUP_PATTERN: Pattern[str] +NUMERAL_PATTERN: Pattern[str] class Locale: - shortname: Any - info: Any - def __init__(self, shortname, language_info) -> None: ... - def is_applicable(self, date_string, strip_timezone: bool = ..., settings: Any | None = ...): ... - def count_applicability(self, text, strip_timezone: bool = ..., settings: Any | None = ...): ... + shortname: str + def __init__(self, shortname: str, language_info) -> None: ... + def is_applicable(self, date_string: str, strip_timezone: bool = ..., settings: Settings | None = ...) -> bool: ... + def count_applicability(self, text: str, strip_timezone: bool = ..., settings: Settings | None = ...): ... @staticmethod def clean_dictionary(dictionary, threshold: int = ...): ... - def translate(self, date_string, keep_formatting: bool = ..., settings: Any | None = ...): ... - def translate_search(self, search_string, settings: Any | None = ...): ... + def translate(self, date_string: str, keep_formatting: bool = ..., settings: Settings | None = ...) -> str: ... + def translate_search(self, search_string, settings: Settings | None = ...): ... def get_wordchars_for_detection(self, settings): ... def to_parserinfo(self, base_cls=...): ...