From 5e925f3b639143bf1b28af5193728f72921dca11 Mon Sep 17 00:00:00 2001 From: Bartosz Sokorski Date: Tue, 17 Dec 2024 22:35:13 +0100 Subject: [PATCH] Update ruff config, use ruff format instead of black --- .pre-commit-config.yaml | 10 +--- clock | 2 +- pyproject.toml | 48 +++++++++------- src/pendulum/__init__.py | 40 ++++++------- src/pendulum/_helpers.py | 20 ++++--- src/pendulum/date.py | 9 +-- src/pendulum/datetime.py | 16 ++---- src/pendulum/duration.py | 22 ++++--- .../formatting/difference_formatter.py | 8 +-- src/pendulum/formatting/formatter.py | 49 ++++++++-------- src/pendulum/helpers.py | 15 +++-- src/pendulum/interval.py | 57 ++++++++----------- src/pendulum/parser.py | 6 +- src/pendulum/parsing/__init__.py | 9 +-- src/pendulum/parsing/iso8601.py | 13 +++-- src/pendulum/testing/traveller.py | 11 ++-- src/pendulum/time.py | 14 ++--- src/pendulum/tz/__init__.py | 16 ++++-- src/pendulum/tz/local_timezone.py | 3 +- src/pendulum/tz/timezone.py | 10 ++-- 20 files changed, 180 insertions(+), 198 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3ec3be2a..98ac5c45 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,15 +11,11 @@ repos: exclude: ^tests/.*/fixtures/.* - id: debug-statements - - repo: https://github.com/psf/black - rev: 23.7.0 - hooks: - - id: black - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.291 + rev: v0.11.2 hooks: - - id: ruff + - id: ruff + - id: ruff-format - repo: local hooks: diff --git a/clock b/clock index acd8c558..a24b69cc 100755 --- a/clock +++ b/clock @@ -196,7 +196,7 @@ translations = {{}} v = repr(v) s.append(f"{' ' * tab}{k!r}: {v},\n") - s.append(f'{" " * (tab - 1)}}}') + s.append(f"{' ' * (tab - 1)}}}") return "".join(s) diff --git a/pyproject.toml b/pyproject.toml index c60c4ff6..4cdfc07f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,44 +68,50 @@ module-name = "pendulum._pendulum" [tool.ruff] fix = true -unfixable = [ - "ERA", # do not autoremove commented out code -] -target-version = "py39" line-length = 88 +target-version = "py39" +extend-exclude = [ + # External to the project's coding standards: + "docs/*", + # Machine-generated, too many false-positives + "src/pendulum/locales/*", + # ruff disagrees with black when it comes to formatting + "*.pyi", +] + +[tool.ruff.lint] extend-select = [ - "B", # flake8-bugbear - "C4", # flake8-comprehensions + "B", # flake8-bugbear + "C4", # flake8-comprehensions "ERA", # flake8-eradicate/eradicate - "I", # isort - "N", # pep8-naming + "I", # isort + "N", # pep8-naming "PIE", # flake8-pie "PGH", # pygrep "RUF", # ruff checks "SIM", # flake8-simplify + "T20", # flake8-print "TCH", # flake8-type-checking "TID", # flake8-tidy-imports - "UP", # pyupgrade + "UP", # pyupgrade ] ignore = [ "B904", # use 'raise ... from err' "B905", # use explicit 'strict=' parameter with 'zip()' - "N818", # Exception name should be named with an Error suffix - "RUF001", + "N818", + "RUF001" ] -extend-exclude = [ - # External to the project's coding standards: - "docs/*", - # Machine-generated, too many false-positives - "src/pendulum/locales/*", - # ruff disagrees with black when it comes to formatting - "*.pyi", +extend-safe-fixes = [ + "TCH", # move import from and to TYPE_CHECKING blocks +] +unfixable = [ + "ERA", # do not autoremove commented out code ] -[tool.ruff.flake8-tidy-imports] +[tool.ruff.lint.flake8-tidy-imports] ban-relative-imports = "all" -[tool.ruff.isort] +[tool.ruff.lint.isort] force-single-line = true lines-between-types = 1 lines-after-imports = 2 @@ -119,7 +125,7 @@ known-third-party = [ ] required-imports = ["from __future__ import annotations"] -[tool.ruff.extend-per-file-ignores] +[tool.ruff.lint.extend-per-file-ignores] "build.py" = ["I002"] "clock" = ["RUF012"] diff --git a/src/pendulum/__init__.py b/src/pendulum/__init__.py index 16e7b367..e1cdf402 100644 --- a/src/pendulum/__init__.py +++ b/src/pendulum/__init__.py @@ -59,18 +59,15 @@ @overload -def timezone(name: int) -> FixedTimezone: - ... +def timezone(name: int) -> FixedTimezone: ... @overload -def timezone(name: str) -> Timezone: - ... +def timezone(name: str) -> Timezone: ... @overload -def timezone(name: str | int) -> Timezone | FixedTimezone: - ... +def timezone(name: str | int) -> Timezone | FixedTimezone: ... def timezone(name: str | int) -> Timezone | FixedTimezone: @@ -119,7 +116,7 @@ def _safe_timezone( obj = int(offset.total_seconds()) - obj = cast(Union[str, int], obj) + obj = cast("Union[str, int]", obj) return timezone(obj) @@ -205,24 +202,21 @@ def time(hour: int, minute: int = 0, second: int = 0, microsecond: int = 0) -> T def instance( obj: _datetime.datetime, tz: str | Timezone | FixedTimezone | _datetime.tzinfo | None = UTC, -) -> DateTime: - ... +) -> DateTime: ... @overload def instance( obj: _datetime.date, tz: str | Timezone | FixedTimezone | _datetime.tzinfo | None = UTC, -) -> Date: - ... +) -> Date: ... @overload def instance( obj: _datetime.time, tz: str | Timezone | FixedTimezone | _datetime.tzinfo | None = UTC, -) -> Time: - ... +) -> Time: ... def instance( @@ -350,7 +344,6 @@ def interval( travel_back = _traveller.travel_back __all__ = [ - "__version__", "DAYS_PER_WEEK", "HOURS_PER_DAY", "MINUTES_PER_HOUR", @@ -358,14 +351,20 @@ def interval( "SECONDS_PER_DAY", "SECONDS_PER_HOUR", "SECONDS_PER_MINUTE", + "UTC", "WEEKS_PER_YEAR", "YEARS_PER_CENTURY", "YEARS_PER_DECADE", "Date", "DateTime", "Duration", + "FixedTimezone", "Formatter", + "Interval", + "Time", + "Timezone", "WeekDay", + "__version__", "date", "datetime", "duration", @@ -377,18 +376,13 @@ def interval( "instance", "interval", "local", + "local_timezone", "locale", "naive", "now", - "set_locale", - "week_ends_at", - "week_starts_at", "parse", - "Interval", - "Time", - "UTC", - "local_timezone", "set_local_timezone", + "set_locale", "test_local_timezone", "time", "timezone", @@ -398,7 +392,7 @@ def interval( "travel", "travel_back", "travel_to", - "FixedTimezone", - "Timezone", + "week_ends_at", + "week_starts_at", "yesterday", ] diff --git a/src/pendulum/_helpers.py b/src/pendulum/_helpers.py index 3eb85439..bb989625 100644 --- a/src/pendulum/_helpers.py +++ b/src/pendulum/_helpers.py @@ -2,8 +2,8 @@ import datetime import math -import zoneinfo +from typing import TYPE_CHECKING from typing import NamedTuple from typing import cast @@ -22,7 +22,12 @@ from pendulum.constants import SECS_PER_YEAR from pendulum.constants import TM_DECEMBER from pendulum.constants import TM_JANUARY -from pendulum.tz.timezone import Timezone + + +if TYPE_CHECKING: + import zoneinfo + + from pendulum.tz.timezone import Timezone class PreciseDiff(NamedTuple): @@ -174,11 +179,8 @@ def precise_diff( d2.tzinfo if isinstance(d2, datetime.datetime) else None ) - if ( - tzinfo1 is None - and tzinfo2 is not None - or tzinfo2 is None - and tzinfo1 is not None + if (tzinfo1 is None and tzinfo2 is not None) or ( + tzinfo2 is None and tzinfo1 is not None ): raise ValueError( "Comparison between naive and aware datetimes is not supported" @@ -324,10 +326,10 @@ def _get_tzinfo_name(tzinfo: datetime.tzinfo | None) -> str | None: if hasattr(tzinfo, "key"): # zoneinfo timezone - return cast(zoneinfo.ZoneInfo, tzinfo).key + return cast("zoneinfo.ZoneInfo", tzinfo).key elif hasattr(tzinfo, "name"): # Pendulum timezone - return cast(Timezone, tzinfo).name + return cast("Timezone", tzinfo).name elif hasattr(tzinfo, "zone"): # pytz timezone return tzinfo.zone # type: ignore[no-any-return] diff --git a/src/pendulum/date.py b/src/pendulum/date.py index 633bb6da..50554f43 100644 --- a/src/pendulum/date.py +++ b/src/pendulum/date.py @@ -257,16 +257,13 @@ def __add__(self, other: timedelta) -> Self: return self._add_timedelta(other) @overload # type: ignore[override] # this is only needed because of Python 3.7 - def __sub__(self, __delta: timedelta) -> Self: - ... + def __sub__(self, __delta: timedelta) -> Self: ... @overload - def __sub__(self, __dt: datetime) -> NoReturn: - ... + def __sub__(self, __dt: datetime) -> NoReturn: ... @overload - def __sub__(self, __dt: Self) -> Interval[Date]: - ... + def __sub__(self, __dt: Self) -> Interval[Date]: ... def __sub__(self, other: timedelta | date) -> Self | Interval[Date]: if isinstance(other, timedelta): diff --git a/src/pendulum/datetime.py b/src/pendulum/datetime.py index c1babbf8..e6f19eb2 100644 --- a/src/pendulum/datetime.py +++ b/src/pendulum/datetime.py @@ -146,13 +146,11 @@ def instance( @overload @classmethod - def now(cls, tz: datetime.tzinfo | None = None) -> Self: - ... + def now(cls, tz: datetime.tzinfo | None = None) -> Self: ... @overload @classmethod - def now(cls, tz: str | Timezone | FixedTimezone | None = None) -> Self: - ... + def now(cls, tz: str | Timezone | FixedTimezone | None = None) -> Self: ... @classmethod def now( @@ -474,7 +472,7 @@ def __repr__(self) -> str: if self.microsecond: us = f", {self.microsecond}" - repr_ = "{klass}(" "{year}, {month}, {day}, " "{hour}, {minute}, {second}{us}" + repr_ = "{klass}({year}, {month}, {day}, {hour}, {minute}, {second}{us}" if self.tzinfo is not None: repr_ += ", tzinfo={tzinfo}" @@ -1008,7 +1006,7 @@ def nth_of(self, unit: str, nth: int, day_of_week: WeekDay) -> Self: if unit not in ["month", "quarter", "year"]: raise ValueError(f'Invalid unit "{unit}" for first_of()') - dt = cast(Optional["Self"], getattr(self, f"_nth_of_{unit}")(nth, day_of_week)) + dt = cast("Optional[Self]", getattr(self, f"_nth_of_{unit}")(nth, day_of_week)) if not dt: raise PendulumException( f"Unable to find occurrence {nth}" @@ -1186,12 +1184,10 @@ def average( # type: ignore[override] ) @overload # type: ignore[override] - def __sub__(self, other: datetime.timedelta) -> Self: - ... + def __sub__(self, other: datetime.timedelta) -> Self: ... @overload - def __sub__(self, other: DateTime) -> Interval[datetime.datetime]: - ... + def __sub__(self, other: DateTime) -> Interval[datetime.datetime]: ... def __sub__( self, other: datetime.datetime | datetime.timedelta diff --git a/src/pendulum/duration.py b/src/pendulum/duration.py index a4875fca..2958ee66 100644 --- a/src/pendulum/duration.py +++ b/src/pendulum/duration.py @@ -37,7 +37,7 @@ def _divide_and_round(a: float, b: float) -> int: # positive, 2 * r < b if b negative. r *= 2 greater_than_half = r > b if b > 0 else r < b - if greater_than_half or r == b and q % 2 == 1: + if greater_than_half or (r == b and q % 2 == 1): q += 1 return q @@ -375,12 +375,10 @@ def __mul__(self, other: int | float) -> Self: __rmul__ = __mul__ @overload - def __floordiv__(self, other: timedelta) -> int: - ... + def __floordiv__(self, other: timedelta) -> int: ... @overload - def __floordiv__(self, other: int) -> Self: - ... + def __floordiv__(self, other: int) -> Self: ... def __floordiv__(self, other: int | timedelta) -> int | Duration: if not isinstance(other, (int, timedelta)): @@ -389,7 +387,8 @@ def __floordiv__(self, other: int | timedelta) -> int | Duration: usec = self._to_microseconds() if isinstance(other, timedelta): return cast( - int, usec // other._to_microseconds() # type: ignore[attr-defined] + "int", + usec // other._to_microseconds(), # type: ignore[attr-defined] ) if isinstance(other, int): @@ -402,12 +401,10 @@ def __floordiv__(self, other: int | timedelta) -> int | Duration: ) @overload - def __truediv__(self, other: timedelta) -> float: - ... + def __truediv__(self, other: timedelta) -> float: ... @overload - def __truediv__(self, other: float) -> Self: - ... + def __truediv__(self, other: float) -> Self: ... def __truediv__(self, other: int | float | timedelta) -> Self | float: if not isinstance(other, (int, float, timedelta)): @@ -416,7 +413,8 @@ def __truediv__(self, other: int | float | timedelta) -> Self | float: usec = self._to_microseconds() if isinstance(other, timedelta): return cast( - float, usec / other._to_microseconds() # type: ignore[attr-defined] + "float", + usec / other._to_microseconds(), # type: ignore[attr-defined] ) if isinstance(other, int): @@ -443,7 +441,7 @@ def __truediv__(self, other: int | float | timedelta) -> Self | float: def __mod__(self, other: timedelta) -> Self: if isinstance(other, timedelta): - r = self._to_microseconds() % other._to_microseconds() # type: ignore[attr-defined] # noqa: E501 + r = self._to_microseconds() % other._to_microseconds() # type: ignore[attr-defined] return self.__class__(0, 0, r) diff --git a/src/pendulum/formatting/difference_formatter.py b/src/pendulum/formatting/difference_formatter.py index 588c0727..b3b6840b 100644 --- a/src/pendulum/formatting/difference_formatter.py +++ b/src/pendulum/formatting/difference_formatter.py @@ -75,7 +75,7 @@ def format( time = locale.get("custom.units.few_second") if time is not None: if absolute: - return t.cast(str, time) + return t.cast("str", time) key = "custom" is_future = diff.invert @@ -90,7 +90,7 @@ def format( else: key += ".before" - return t.cast(str, locale.get(key).format(time)) + return t.cast("str", locale.get(key).format(time)) else: unit = "second" count = diff.remaining_seconds @@ -137,8 +137,8 @@ def format( else: key += ".before" - return t.cast(str, locale.get(key).format(time)) + return t.cast("str", locale.get(key).format(time)) key += f".{locale.plural(count)}" - return t.cast(str, locale.get(key).format(count)) + return t.cast("str", locale.get(key).format(count)) diff --git a/src/pendulum/formatting/formatter.py b/src/pendulum/formatting/formatter.py index 8735ecc4..da05617d 100644 --- a/src/pendulum/formatting/formatter.py +++ b/src/pendulum/formatting/formatter.py @@ -3,7 +3,6 @@ import datetime import re -from collections.abc import Sequence from re import Match from typing import TYPE_CHECKING from typing import Any @@ -17,6 +16,8 @@ if TYPE_CHECKING: + from collections.abc import Sequence + from pendulum import Timezone _MATCH_1 = r"\d" @@ -38,7 +39,7 @@ _MATCH_TIMESTAMP = r"[+-]?\d+(\.\d{1,6})?" _MATCH_WORD = ( "(?i)[0-9]*" - "['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+" + "['a-z\u00a0-\u05ff\u0700-\ud7ff\uf900-\ufdcf\ufdf0-\uffef]+" r"|[\u0600-\u06FF/]+(\s*?[\u0600-\u06FF]+){1,2}" ) _MATCH_TIMEZONE = "[A-Za-z0-9-+]+(/[A-Za-z0-9-+_]+)?" @@ -138,8 +139,8 @@ class Formatter: "X": lambda dt: f"{dt.int_timestamp:d}", "x": lambda dt: f"{dt.int_timestamp * 1000 + dt.microsecond // 1000:d}", # Timezone - "zz": lambda dt: f'{dt.tzname() if dt.tzinfo is not None else ""}', - "z": lambda dt: f'{dt.timezone_name or ""}', + "zz": lambda dt: f"{dt.tzname() if dt.tzinfo is not None else ''}", + "z": lambda dt: f"{dt.timezone_name or ''}", } _DATE_FORMATS: ClassVar[dict[str, str]] = { @@ -314,20 +315,20 @@ def _format_localizable_token( :param locale: The locale to use """ if token == "MMM": - return cast(str, locale.get("translations.months.abbreviated")[dt.month]) + return cast("str", locale.get("translations.months.abbreviated")[dt.month]) elif token == "MMMM": - return cast(str, locale.get("translations.months.wide")[dt.month]) + return cast("str", locale.get("translations.months.wide")[dt.month]) elif token == "dd": - return cast(str, locale.get("translations.days.short")[dt.day_of_week]) + return cast("str", locale.get("translations.days.short")[dt.day_of_week]) elif token == "ddd": return cast( - str, + "str", locale.get("translations.days.abbreviated")[dt.day_of_week], ) elif token == "dddd": - return cast(str, locale.get("translations.days.wide")[dt.day_of_week]) + return cast("str", locale.get("translations.days.wide")[dt.day_of_week]) elif token == "e": - first_day = cast(int, locale.get("translations.week_data.first_day")) + first_day = cast("int", locale.get("translations.week_data.first_day")) return str((dt.day_of_week % 7 - first_day) % 7) elif token == "Do": @@ -343,7 +344,7 @@ def _format_localizable_token( elif token == "DDDo": return locale.ordinalize(dt.day_of_year) elif token == "eo": - first_day = cast(int, locale.get("translations.week_data.first_day")) + first_day = cast("int", locale.get("translations.week_data.first_day")) return locale.ordinalize((dt.day_of_week % 7 - first_day) % 7 + 1) elif token == "A": @@ -353,7 +354,7 @@ def _format_localizable_token( else: key += ".am" - return cast(str, locale.get(key)) + return cast("str", locale.get(key)) else: return token @@ -441,7 +442,7 @@ def _check_parsed( if parsed["timestamp"] is not None: str_us = str(parsed["timestamp"]) if "." in str_us: - microseconds = int(f'{str_us.split(".")[1].ljust(6, "0")}') + microseconds = int(f"{str_us.split('.')[1].ljust(6, '0')}") else: microseconds = 0 @@ -460,7 +461,7 @@ def _check_parsed( if parsed["quarter"] is not None: if validated["year"] is not None: - dt = pendulum.datetime(cast(int, validated["year"]), 1, 1) + dt = pendulum.datetime(cast("int", validated["year"]), 1, 1) else: dt = now @@ -478,8 +479,8 @@ def _check_parsed( if parsed["day_of_year"] is not None: dt = cast( - pendulum.DateTime, - pendulum.parse(f'{validated["year"]}-{parsed["day_of_year"]:>03d}'), + "pendulum.DateTime", + pendulum.parse(f"{validated['year']}-{parsed['day_of_year']:>03d}"), ) validated["month"] = dt.month @@ -487,9 +488,9 @@ def _check_parsed( if parsed["day_of_week"] is not None: dt = pendulum.datetime( - cast(int, validated["year"]), - cast(int, validated["month"]) or now.month, - cast(int, validated["day"]) or now.day, + cast("int", validated["year"]), + cast("int", validated["month"]) or now.month, + cast("int", validated["day"]) or now.day, ) dt = dt.start_of("week").subtract(days=1) dt = dt.next(parsed["day_of_week"]) @@ -628,7 +629,7 @@ def _get_parsed_locale_value( unit = "month" match = "months.abbreviated" elif token == "Do": - parsed["day"] = int(cast(Match[str], re.match(r"(\d+)", value)).group(1)) + parsed["day"] = int(cast("Match[str]", re.match(r"(\d+)", value)).group(1)) return elif token == "dddd": @@ -681,18 +682,18 @@ def _replace_tokens(self, token: str, locale: Locale) -> str: else: candidates = tuple( locale.translation( - cast(str, self._LOCALIZABLE_TOKENS[token]) + cast("str", self._LOCALIZABLE_TOKENS[token]) ).values() ) else: - candidates = cast(Sequence[str], self._REGEX_TOKENS[token]) + candidates = cast("Sequence[str]", self._REGEX_TOKENS[token]) if not candidates: raise ValueError(f"Unsupported token: {token}") if not isinstance(candidates, tuple): - candidates = (cast(str, candidates),) + candidates = (cast("str", candidates),) - pattern = f'(?P<{token}>{"|".join(candidates)})' + pattern = f"(?P<{token}>{'|'.join(candidates)})" return pattern diff --git a/src/pendulum/helpers.py b/src/pendulum/helpers.py index 5d5fe8e5..e9424d90 100644 --- a/src/pendulum/helpers.py +++ b/src/pendulum/helpers.py @@ -62,8 +62,7 @@ def add_duration( minutes: int = 0, seconds: float = 0, microseconds: int = 0, -) -> _DT: - ... +) -> _DT: ... @overload @@ -205,17 +204,17 @@ def week_ends_at(wday: WeekDay) -> None: __all__ = [ "PreciseDiff", + "add_duration", "days_in_year", + "format_diff", + "get_locale", "is_leap", "is_long_year", "local_time", - "precise_diff", - "week_day", - "add_duration", - "format_diff", "locale", + "precise_diff", "set_locale", - "get_locale", - "week_starts_at", + "week_day", "week_ends_at", + "week_starts_at", ] diff --git a/src/pendulum/interval.py b/src/pendulum/interval.py index 345a160e..747367c1 100644 --- a/src/pendulum/interval.py +++ b/src/pendulum/interval.py @@ -37,11 +37,8 @@ class Interval(Duration, Generic[_T]): """ def __new__(cls, start: _T, end: _T, absolute: bool = False) -> Self: - if ( - isinstance(start, datetime) - and not isinstance(end, datetime) - or not isinstance(start, datetime) - and isinstance(end, datetime) + if (isinstance(start, datetime) and not isinstance(end, datetime)) or ( + not isinstance(start, datetime) and isinstance(end, datetime) ): raise ValueError( "Both start and end of an Interval must have the same type" @@ -51,10 +48,8 @@ def __new__(cls, start: _T, end: _T, absolute: bool = False) -> Self: isinstance(start, datetime) and isinstance(end, datetime) and ( - start.tzinfo is None - and end.tzinfo is not None - or start.tzinfo is not None - and end.tzinfo is None + (start.tzinfo is None and end.tzinfo is not None) + or (start.tzinfo is not None and end.tzinfo is None) ) ): raise TypeError("can't compare offset-naive and offset-aware datetimes") @@ -66,7 +61,7 @@ def __new__(cls, start: _T, end: _T, absolute: bool = False) -> Self: _end = end if isinstance(start, pendulum.DateTime): _start = cast( - _T, + "_T", datetime( start.year, start.month, @@ -80,11 +75,11 @@ def __new__(cls, start: _T, end: _T, absolute: bool = False) -> Self: ), ) elif isinstance(start, pendulum.Date): - _start = cast(_T, date(start.year, start.month, start.day)) + _start = cast("_T", date(start.year, start.month, start.day)) if isinstance(end, pendulum.DateTime): _end = cast( - _T, + "_T", datetime( end.year, end.month, @@ -98,7 +93,7 @@ def __new__(cls, start: _T, end: _T, absolute: bool = False) -> Self: ), ) elif isinstance(end, pendulum.Date): - _end = cast(_T, date(end.year, end.month, end.day)) + _end = cast("_T", date(end.year, end.month, end.day)) # Fixing issues with datetime.__sub__() # not handling offsets if the tzinfo is the same @@ -108,12 +103,12 @@ def __new__(cls, start: _T, end: _T, absolute: bool = False) -> Self: and _start.tzinfo is _end.tzinfo ): if _start.tzinfo is not None: - offset = cast(timedelta, cast(datetime, start).utcoffset()) - _start = cast(_T, (_start - offset).replace(tzinfo=None)) + offset = cast("timedelta", cast("datetime", start).utcoffset()) + _start = cast("_T", (_start - offset).replace(tzinfo=None)) if isinstance(end, datetime) and _end.tzinfo is not None: - offset = cast(timedelta, end.utcoffset()) - _end = cast(_T, (_end - offset).replace(tzinfo=None)) + offset = cast("timedelta", end.utcoffset()) + _end = cast("_T", (_end - offset).replace(tzinfo=None)) delta: timedelta = _end - _start @@ -125,15 +120,15 @@ def __init__(self, start: _T, end: _T, absolute: bool = False) -> None: _start: _T if not isinstance(start, pendulum.Date): if isinstance(start, datetime): - start = cast(_T, pendulum.instance(start)) + start = cast("_T", pendulum.instance(start)) else: - start = cast(_T, pendulum.date(start.year, start.month, start.day)) + start = cast("_T", pendulum.date(start.year, start.month, start.day)) _start = start else: if isinstance(start, pendulum.DateTime): _start = cast( - _T, + "_T", datetime( start.year, start.month, @@ -146,20 +141,20 @@ def __init__(self, start: _T, end: _T, absolute: bool = False) -> None: ), ) else: - _start = cast(_T, date(start.year, start.month, start.day)) + _start = cast("_T", date(start.year, start.month, start.day)) _end: _T if not isinstance(end, pendulum.Date): if isinstance(end, datetime): - end = cast(_T, pendulum.instance(end)) + end = cast("_T", pendulum.instance(end)) else: - end = cast(_T, pendulum.date(end.year, end.month, end.day)) + end = cast("_T", pendulum.date(end.year, end.month, end.day)) _end = end else: if isinstance(end, pendulum.DateTime): _end = cast( - _T, + "_T", datetime( end.year, end.month, @@ -172,7 +167,7 @@ def __init__(self, start: _T, end: _T, absolute: bool = False) -> None: ), ) else: - _end = cast(_T, date(end.year, end.month, end.day)) + _end = cast("_T", date(end.year, end.month, end.day)) self._invert = False if start > end: @@ -336,12 +331,10 @@ def __mul__(self, other: int | float) -> Duration: # type: ignore[override] __rmul__ = __mul__ # type: ignore[assignment] @overload # type: ignore[override] - def __floordiv__(self, other: timedelta) -> int: - ... + def __floordiv__(self, other: timedelta) -> int: ... @overload - def __floordiv__(self, other: int) -> Duration: - ... + def __floordiv__(self, other: int) -> Duration: ... def __floordiv__(self, other: int | timedelta) -> int | Duration: return self.as_duration().__floordiv__(other) @@ -349,12 +342,10 @@ def __floordiv__(self, other: int | timedelta) -> int | Duration: __div__ = __floordiv__ # type: ignore[assignment] @overload # type: ignore[override] - def __truediv__(self, other: timedelta) -> float: - ... + def __truediv__(self, other: timedelta) -> float: ... @overload - def __truediv__(self, other: float) -> Duration: - ... + def __truediv__(self, other: float) -> Duration: ... def __truediv__(self, other: float | timedelta) -> Duration | float: return self.as_duration().__truediv__(other) diff --git a/src/pendulum/parser.py b/src/pendulum/parser.py index a329a321..b7c0a1d0 100644 --- a/src/pendulum/parser.py +++ b/src/pendulum/parser.py @@ -86,7 +86,7 @@ def _parse( ) dt = pendulum.instance( - t.cast(datetime.datetime, parsed.end), tz=options.get("tz", UTC) + t.cast("datetime.datetime", parsed.end), tz=options.get("tz", UTC) ) return pendulum.interval( @@ -105,10 +105,10 @@ def _parse( return pendulum.interval( pendulum.instance( - t.cast(datetime.datetime, parsed.start), tz=options.get("tz", UTC) + t.cast("datetime.datetime", parsed.start), tz=options.get("tz", UTC) ), pendulum.instance( - t.cast(datetime.datetime, parsed.end), tz=options.get("tz", UTC) + t.cast("datetime.datetime", parsed.end), tz=options.get("tz", UTC) ), ) diff --git a/src/pendulum/parsing/__init__.py b/src/pendulum/parsing/__init__.py index 60b232bf..9ff7b937 100644 --- a/src/pendulum/parsing/__init__.py +++ b/src/pendulum/parsing/__init__.py @@ -27,7 +27,7 @@ from pendulum._pendulum import Duration from pendulum._pendulum import parse_iso8601 except ImportError: - from pendulum.duration import Duration # type: ignore[assignment] + from pendulum.duration import Duration # type: ignore[assignment] # noqa: TC001 from pendulum.parsing.iso8601 import parse_iso8601 # type: ignore[assignment] @@ -44,7 +44,8 @@ " )" ")?" # Time (optional) # noqa: ERA001 - "(?P