From 385c1fb287687f5bec70f06cf9c4092e87709c47 Mon Sep 17 00:00:00 2001 From: donbarbos Date: Sun, 1 Mar 2026 11:52:45 +0400 Subject: [PATCH 1/2] [python-dateutil] Complete stubs * Add missing return types * Use TypeVar when possible --- pyrightconfig.stricter.json | 1 - stubs/python-dateutil/dateutil/parser/_parser.pyi | 2 +- stubs/python-dateutil/dateutil/parser/isoparser.pyi | 2 +- stubs/python-dateutil/dateutil/rrule.pyi | 4 ++-- stubs/python-dateutil/dateutil/tz/_common.pyi | 3 ++- stubs/python-dateutil/dateutil/tz/tz.pyi | 8 ++++---- stubs/python-dateutil/dateutil/utils.pyi | 5 ++++- 7 files changed, 14 insertions(+), 11 deletions(-) diff --git a/pyrightconfig.stricter.json b/pyrightconfig.stricter.json index de9383275efa..269b302254eb 100644 --- a/pyrightconfig.stricter.json +++ b/pyrightconfig.stricter.json @@ -78,7 +78,6 @@ "stubs/pycurl", "stubs/Pygments", "stubs/PyMySQL", - "stubs/python-dateutil", "stubs/python-jose", "stubs/pywin32", "stubs/PyYAML", diff --git a/stubs/python-dateutil/dateutil/parser/_parser.pyi b/stubs/python-dateutil/dateutil/parser/_parser.pyi index 9119ec25d7b7..7c47cae76a28 100644 --- a/stubs/python-dateutil/dateutil/parser/_parser.pyi +++ b/stubs/python-dateutil/dateutil/parser/_parser.pyi @@ -125,7 +125,7 @@ class _tzparser: day: int | None time: int | None - def __init__(self): ... + def __init__(self) -> None: ... def parse(self, tzstr: str | re.Pattern[str]) -> _result | None: ... diff --git a/stubs/python-dateutil/dateutil/parser/isoparser.pyi b/stubs/python-dateutil/dateutil/parser/isoparser.pyi index 51a9c153af81..b0940e2905b3 100644 --- a/stubs/python-dateutil/dateutil/parser/isoparser.pyi +++ b/stubs/python-dateutil/dateutil/parser/isoparser.pyi @@ -8,7 +8,7 @@ _TakesAscii: TypeAlias = str | bytes | _Readable __all__ = ["isoparse", "isoparser"] class isoparser: - def __init__(self, sep: str | bytes | None = None): ... + def __init__(self, sep: str | bytes | None = None) -> None: ... def isoparse(self, dt_str: _TakesAscii) -> datetime: ... def parse_isodate(self, datestr: _TakesAscii) -> date: ... def parse_isotime(self, timestr: _TakesAscii) -> time: ... diff --git a/stubs/python-dateutil/dateutil/rrule.pyi b/stubs/python-dateutil/dateutil/rrule.pyi index dd712283fd3a..8a77b531c1b5 100644 --- a/stubs/python-dateutil/dateutil/rrule.pyi +++ b/stubs/python-dateutil/dateutil/rrule.pyi @@ -62,8 +62,8 @@ class rrulebase: def __getitem__(self, item: int | slice) -> datetime.datetime: ... def __contains__(self, item: datetime.datetime) -> bool: ... def count(self) -> int | None: ... - def before(self, dt: datetime.datetime, inc: bool = False): ... - def after(self, dt: datetime.datetime, inc: bool = False): ... + def before(self, dt: datetime.datetime, inc: bool = False) -> datetime.datetime: ... + def after(self, dt: datetime.datetime, inc: bool = False) -> datetime.datetime: ... def xafter(self, dt: datetime.datetime, count: int | None = None, inc: bool = False) -> Generator[datetime.datetime]: ... def between( self, after: datetime.datetime, before: datetime.datetime, inc: bool = False, count: int = 1 diff --git a/stubs/python-dateutil/dateutil/tz/_common.pyi b/stubs/python-dateutil/dateutil/tz/_common.pyi index 23bce452e8bb..56117f232d68 100644 --- a/stubs/python-dateutil/dateutil/tz/_common.pyi +++ b/stubs/python-dateutil/dateutil/tz/_common.pyi @@ -10,9 +10,10 @@ __all__ = ["tzname_in_python2", "enfold"] _P = ParamSpec("_P") _R = TypeVar("_R") +_DateTimeT = TypeVar("_DateTimeT", bound=datetime) def tzname_in_python2(namefunc: Callable[_P, _R]) -> Callable[_P, _R]: ... -def enfold(dt: datetime, fold: int = 1): ... +def enfold(dt: _DateTimeT, fold: int = 1) -> _DateTimeT: ... # Doesn't actually have ABCMeta as the metaclass at runtime, # but mypy complains if we don't have it in the stub. diff --git a/stubs/python-dateutil/dateutil/tz/tz.pyi b/stubs/python-dateutil/dateutil/tz/tz.pyi index 0fad227656a0..19ce1c9dd51e 100644 --- a/stubs/python-dateutil/dateutil/tz/tz.pyi +++ b/stubs/python-dateutil/dateutil/tz/tz.pyi @@ -13,7 +13,7 @@ else: tzwin: None tzwinlocal: None -_DT = TypeVar("_DT", bound=datetime) +_DateTimeT = TypeVar("_DateTimeT", bound=datetime) ZERO: timedelta EPOCH: datetime @@ -24,7 +24,7 @@ class tzutc(tzinfo): def dst(self, dt: datetime | None) -> timedelta | None: ... def tzname(self, dt: datetime | None) -> str: ... def is_ambiguous(self, dt: datetime | None) -> bool: ... - def fromutc(self, dt: _DT) -> _DT: ... + def fromutc(self, dt: _DateTimeT) -> _DateTimeT: ... def __eq__(self, other: object) -> bool: ... __hash__: ClassVar[None] # type: ignore[assignment] def __ne__(self, other: object) -> bool: ... @@ -38,7 +38,7 @@ class tzoffset(tzinfo): def dst(self, dt: datetime | None) -> timedelta | None: ... def is_ambiguous(self, dt: datetime | None) -> bool: ... def tzname(self, dt: datetime | None) -> str: ... - def fromutc(self, dt: _DT) -> _DT: ... + def fromutc(self, dt: _DateTimeT) -> _DateTimeT: ... def __eq__(self, other: object) -> bool: ... __hash__: ClassVar[None] # type: ignore[assignment] def __ne__(self, other: object) -> bool: ... @@ -126,7 +126,7 @@ TZPATHS: list[str] def datetime_exists(dt: datetime, tz: tzinfo | None = None) -> bool: ... def datetime_ambiguous(dt: datetime, tz: tzinfo | None = None) -> bool: ... -def resolve_imaginary(dt: datetime) -> datetime: ... +def resolve_imaginary(dt: _DateTimeT) -> _DateTimeT: ... # Singleton type defined locally in a function. Calls itself "GettzFunc". @type_check_only diff --git a/stubs/python-dateutil/dateutil/utils.pyi b/stubs/python-dateutil/dateutil/utils.pyi index 512c241832c9..ce4d8d38ccc0 100644 --- a/stubs/python-dateutil/dateutil/utils.pyi +++ b/stubs/python-dateutil/dateutil/utils.pyi @@ -1,5 +1,8 @@ from datetime import _TzInfo, datetime, timedelta +from typing import TypeVar + +_DateTimeT = TypeVar("_DateTimeT", bound=datetime) def today(tzinfo: _TzInfo | None = None) -> datetime: ... -def default_tzinfo(dt: datetime, tzinfo: _TzInfo) -> datetime: ... +def default_tzinfo(dt: _DateTimeT, tzinfo: _TzInfo) -> _DateTimeT: ... def within_delta(dt1: datetime, dt2: datetime, delta: timedelta) -> bool: ... From 6d0ec6059c0ac8d8a764be49034fc64e7623bf19 Mon Sep 17 00:00:00 2001 From: donbarbos Date: Mon, 2 Mar 2026 21:22:53 +0400 Subject: [PATCH 2/2] or None --- stubs/python-dateutil/dateutil/rrule.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stubs/python-dateutil/dateutil/rrule.pyi b/stubs/python-dateutil/dateutil/rrule.pyi index 8a77b531c1b5..62fe9bb928d7 100644 --- a/stubs/python-dateutil/dateutil/rrule.pyi +++ b/stubs/python-dateutil/dateutil/rrule.pyi @@ -62,8 +62,8 @@ class rrulebase: def __getitem__(self, item: int | slice) -> datetime.datetime: ... def __contains__(self, item: datetime.datetime) -> bool: ... def count(self) -> int | None: ... - def before(self, dt: datetime.datetime, inc: bool = False) -> datetime.datetime: ... - def after(self, dt: datetime.datetime, inc: bool = False) -> datetime.datetime: ... + def before(self, dt: datetime.datetime, inc: bool = False) -> datetime.datetime | None: ... + def after(self, dt: datetime.datetime, inc: bool = False) -> datetime.datetime | None: ... def xafter(self, dt: datetime.datetime, count: int | None = None, inc: bool = False) -> Generator[datetime.datetime]: ... def between( self, after: datetime.datetime, before: datetime.datetime, inc: bool = False, count: int = 1