From d6d80a17444c90259c5bfdacb84c61e6bfece655 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 5 Jan 2023 11:38:41 +0100 Subject: Merging upstream version 3.0.0~a1. Signed-off-by: Daniel Baumann --- pendulum/parser.py | 245 +++++++++++++++++++++++++++-------------------------- 1 file changed, 124 insertions(+), 121 deletions(-) (limited to 'pendulum/parser.py') diff --git a/pendulum/parser.py b/pendulum/parser.py index 9b9e383..77900e2 100644 --- a/pendulum/parser.py +++ b/pendulum/parser.py @@ -1,121 +1,124 @@ -from __future__ import absolute_import - -import datetime -import typing - -import pendulum - -from .date import Date -from .datetime import DateTime -from .parsing import _Interval -from .parsing import parse as base_parse -from .time import Duration -from .time import Time -from .tz import UTC - - -try: - from .parsing._iso8601 import Duration as CDuration -except ImportError: - CDuration = None - - -def parse( - text, **options -): # type: (str, **typing.Any) -> typing.Union[Date, Time, DateTime, Duration] - # Use the mock now value if it exists - options["now"] = options.get("now", pendulum.get_test_now()) - - return _parse(text, **options) - - -def _parse(text, **options): - """ - Parses a string with the given options. - - :param text: The string to parse. - :type text: str - - :rtype: mixed - """ - # Handling special cases - if text == "now": - return pendulum.now() - - parsed = base_parse(text, **options) - - if isinstance(parsed, datetime.datetime): - return pendulum.datetime( - parsed.year, - parsed.month, - parsed.day, - parsed.hour, - parsed.minute, - parsed.second, - parsed.microsecond, - tz=parsed.tzinfo or options.get("tz", UTC), - ) - - if isinstance(parsed, datetime.date): - return pendulum.date(parsed.year, parsed.month, parsed.day) - - if isinstance(parsed, datetime.time): - return pendulum.time( - parsed.hour, parsed.minute, parsed.second, parsed.microsecond - ) - - if isinstance(parsed, _Interval): - if parsed.duration is not None: - duration = parsed.duration - - if parsed.start is not None: - dt = pendulum.instance(parsed.start, tz=options.get("tz", UTC)) - - return pendulum.period( - dt, - dt.add( - years=duration.years, - months=duration.months, - weeks=duration.weeks, - days=duration.remaining_days, - hours=duration.hours, - minutes=duration.minutes, - seconds=duration.remaining_seconds, - microseconds=duration.microseconds, - ), - ) - - dt = pendulum.instance(parsed.end, tz=options.get("tz", UTC)) - - return pendulum.period( - dt.subtract( - years=duration.years, - months=duration.months, - weeks=duration.weeks, - days=duration.remaining_days, - hours=duration.hours, - minutes=duration.minutes, - seconds=duration.remaining_seconds, - microseconds=duration.microseconds, - ), - dt, - ) - - return pendulum.period( - pendulum.instance(parsed.start, tz=options.get("tz", UTC)), - pendulum.instance(parsed.end, tz=options.get("tz", UTC)), - ) - - if CDuration and isinstance(parsed, CDuration): - return pendulum.duration( - years=parsed.years, - months=parsed.months, - weeks=parsed.weeks, - days=parsed.days, - hours=parsed.hours, - minutes=parsed.minutes, - seconds=parsed.seconds, - microseconds=parsed.microseconds, - ) - - return parsed +from __future__ import annotations + +import datetime +import typing as t + +import pendulum + +from pendulum.parsing import _Interval +from pendulum.parsing import parse as base_parse +from pendulum.tz.timezone import UTC + +if t.TYPE_CHECKING: + from pendulum.date import Date + from pendulum.datetime import DateTime + from pendulum.duration import Duration + from pendulum.interval import Interval + from pendulum.time import Time + +try: + from pendulum.parsing._iso8601 import Duration as CDuration +except ImportError: + CDuration = None # type: ignore[misc, assignment] + + +def parse(text: str, **options: t.Any) -> Date | Time | DateTime | Duration: + # Use the mock now value if it exists + options["now"] = options.get("now") + + return _parse(text, **options) + + +def _parse(text: str, **options: t.Any) -> Date | DateTime | Time | Duration | Interval: + """ + Parses a string with the given options. + + :param text: The string to parse. + """ + # Handling special cases + if text == "now": + return pendulum.now() + + parsed = base_parse(text, **options) + + if isinstance(parsed, datetime.datetime): + return pendulum.datetime( + parsed.year, + parsed.month, + parsed.day, + parsed.hour, + parsed.minute, + parsed.second, + parsed.microsecond, + tz=parsed.tzinfo or options.get("tz", UTC), + ) + + if isinstance(parsed, datetime.date): + return pendulum.date(parsed.year, parsed.month, parsed.day) + + if isinstance(parsed, datetime.time): + return pendulum.time( + parsed.hour, parsed.minute, parsed.second, parsed.microsecond + ) + + if isinstance(parsed, _Interval): + if parsed.duration is not None: + duration = parsed.duration + + if parsed.start is not None: + dt = pendulum.instance(parsed.start, tz=options.get("tz", UTC)) + + return pendulum.interval( + dt, + dt.add( + years=duration.years, + months=duration.months, + weeks=duration.weeks, + days=duration.remaining_days, + hours=duration.hours, + minutes=duration.minutes, + seconds=duration.remaining_seconds, + microseconds=duration.microseconds, + ), + ) + + dt = pendulum.instance( + t.cast(datetime.datetime, parsed.end), tz=options.get("tz", UTC) + ) + + return pendulum.interval( + dt.subtract( + years=duration.years, + months=duration.months, + weeks=duration.weeks, + days=duration.remaining_days, + hours=duration.hours, + minutes=duration.minutes, + seconds=duration.remaining_seconds, + microseconds=duration.microseconds, + ), + dt, + ) + + return pendulum.interval( + pendulum.instance( + t.cast(datetime.datetime, parsed.start), tz=options.get("tz", UTC) + ), + pendulum.instance( + t.cast(datetime.datetime, parsed.end), tz=options.get("tz", UTC) + ), + ) + + if CDuration and isinstance(parsed, CDuration): + return pendulum.duration( + years=parsed.years, + months=parsed.months, + weeks=parsed.weeks, + days=parsed.days, + hours=parsed.hours, + minutes=parsed.minutes, + seconds=parsed.seconds, + microseconds=parsed.microseconds, + ) + + return parsed -- cgit v1.2.3