Repository: sdispater/pendulum
Pull request #733 (2023-08-15 14:02:55)

Various fixes
Fixes https://github.com/sdispater/pendulum/issues/662
Fixes https://github.com/sdispater/pendulum/issues/662
Fixes https://github.com/sdispater/pendulum/issues/715

## Pull Request Check List

- [x] Added **tests** for changed code.
- [ ] Updated **documentation** for changed code.


codspeed-hq[bot]: ## [CodSpeed Performance Report](https://codspeed.io/sdispater/pendulum/branches/fix/various-fixes)

### Merging #733 will **not alter performance**

<sub>Comparing <code>fix/various-fixes</code> (8792507) with <code>master</code> (77d1791)</sub>



### Summary

`✅ 2` untouched benchmarks






Patch:
diff --git a/pendulum/datetime.py b/pendulum/datetime.py
index 0bb837f..94af876 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 @@ class DateTime(datetime.datetime, Date):
         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 a07c9c7..ce09559 100644
--- a/pendulum/duration.py
+++ b/pendulum/duration.py
@@ -446,6 +446,17 @@ class Duration(timedelta):
 
         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 6444b2a..f2531f3 100644
--- a/pendulum/mixins/default.py
+++ b/pendulum/mixins/default.py
@@ -22,7 +22,7 @@ class FormattableMixin:
         """
         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 dacf234..3cb488c 100644
--- a/pendulum/tz/local_timezone.py
+++ b/pendulum/tz/local_timezone.py
@@ -4,12 +4,14 @@ import contextlib
 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:


Test patch:
diff --git a/tests/datetime/test_strings.py b/tests/datetime/test_strings.py
index 87321d8..e78dbc8 100644
--- a/tests/datetime/test_strings.py
+++ b/tests/datetime/test_strings.py
@@ -7,9 +7,9 @@ import pendulum
 
 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 a97bbde..2442534 100644
--- a/tests/duration/test_behavior.py
+++ b/tests/duration/test_behavior.py
@@ -2,12 +2,15 @@ from __future__ import annotations
 
 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)