diff --git a/pendulum/datetime.py b/pendulum/datetime.py index 0bb837fe..94af8768 100644 --- a/pendulum/datetime.py +++ b/pendulum/datetime.py @@ -58,13 +58,13 @@ class DateTime(datetime.datetime, Date): _FORMATS: ClassVar[dict[str, str | Callable[[datetime.datetime], str]]] = { "atom": ATOM, "cookie": COOKIE, - "iso8601": lambda dt: dt.isoformat(), + "iso8601": lambda dt: dt.isoformat("T"), "rfc822": RFC822, "rfc850": RFC850, "rfc1036": RFC1036, "rfc1123": RFC1123, "rfc2822": RFC2822, - "rfc3339": lambda dt: dt.isoformat(), + "rfc3339": lambda dt: dt.isoformat("T"), "rss": RSS, "w3c": W3C, } @@ -468,7 +468,7 @@ def _to_string(self, fmt: str, locale: str | None = None) -> str: return self.format(fmt_value, locale=locale) def __str__(self) -> str: - return self.isoformat("T") + return self.isoformat(" ") def __repr__(self) -> str: us = "" diff --git a/pendulum/duration.py b/pendulum/duration.py index a07c9c79..ce095594 100644 --- a/pendulum/duration.py +++ b/pendulum/duration.py @@ -446,6 +446,17 @@ def __divmod__(self, other: timedelta) -> tuple[int, Duration]: return NotImplemented + def __deepcopy__(self, _: dict[int, Self]) -> Self: + return self.__class__( + days=self.remaining_days, + seconds=self.remaining_seconds, + microseconds=self.microseconds, + minutes=self.minutes, + hours=self.hours, + years=self.years, + months=self.months, + ) + Duration.min = Duration(days=-999999999) Duration.max = Duration( diff --git a/pendulum/mixins/default.py b/pendulum/mixins/default.py index 6444b2a8..f2531f3d 100644 --- a/pendulum/mixins/default.py +++ b/pendulum/mixins/default.py @@ -22,7 +22,7 @@ def for_json(self) -> str: """ Methods for automatic json serialization by simplejson. """ - return str(self) + return self.isoformat() def __format__(self, format_spec: str) -> str: if len(format_spec) > 0: diff --git a/pendulum/tz/local_timezone.py b/pendulum/tz/local_timezone.py index dacf234d..3cb488cd 100644 --- a/pendulum/tz/local_timezone.py +++ b/pendulum/tz/local_timezone.py @@ -4,12 +4,14 @@ import os import re import sys +import warnings from contextlib import contextmanager from typing import Iterator from typing import cast from pendulum.tz.exceptions import InvalidTimezone +from pendulum.tz.timezone import UTC from pendulum.tz.timezone import FixedTimezone from pendulum.tz.timezone import Timezone @@ -239,7 +241,11 @@ def _get_unix_timezone(_root: str = "/") -> Timezone: with open(tzpath, "rb") as f: return Timezone.from_file(f) - raise RuntimeError("Unable to find any timezone configuration") + warnings.warn( + "Unable not find any timezone configuration, defaulting to UTC.", stacklevel=1 + ) + + return UTC def _tz_from_env(tzenv: str) -> Timezone: diff --git a/tests/datetime/test_strings.py b/tests/datetime/test_strings.py index 87321d84..e78dbc8a 100644 --- a/tests/datetime/test_strings.py +++ b/tests/datetime/test_strings.py @@ -7,9 +7,9 @@ def test_to_string(): d = pendulum.datetime(1975, 12, 25, 0, 0, 0, 0, tz="local") - assert str(d) == d.to_iso8601_string() + assert str(d) == "1975-12-25 00:00:00-05:00" d = pendulum.datetime(1975, 12, 25, 0, 0, 0, 123456, tz="local") - assert str(d) == d.to_iso8601_string() + assert str(d) == "1975-12-25 00:00:00.123456-05:00" def test_to_date_string(): @@ -135,7 +135,7 @@ def test_for_json(): def test_format(): d = pendulum.datetime(1975, 12, 25, 14, 15, 16, tz="Europe/Paris") - assert f"{d}" == "1975-12-25T14:15:16+01:00" + assert f"{d}" == "1975-12-25 14:15:16+01:00" assert f"{d:YYYY}" == "1975" assert f"{d:%Y}" == "1975" assert f"{d:%H:%M %d.%m.%Y}" == "14:15 25.12.1975" diff --git a/tests/duration/test_behavior.py b/tests/duration/test_behavior.py index a97bbde6..2442534a 100644 --- a/tests/duration/test_behavior.py +++ b/tests/duration/test_behavior.py @@ -2,12 +2,15 @@ import pickle +from copy import deepcopy from datetime import timedelta import pendulum +from tests.conftest import assert_duration -def test_pickle(): + +def test_pickle() -> None: it = pendulum.duration(days=3, seconds=2456, microseconds=123456) s = pickle.dumps(it) it2 = pickle.loads(s) @@ -15,7 +18,15 @@ def test_pickle(): assert it == it2 -def test_comparison_to_timedelta(): +def test_comparison_to_timedelta() -> None: duration = pendulum.duration(days=3) assert duration < timedelta(days=4) + + +def test_deepcopy() -> None: + duration = pendulum.duration(months=1) + copied_duration = deepcopy(duration) + + assert copied_duration == duration + assert_duration(copied_duration, months=1)