Skip to content

Commit 071bf63

Browse files
authored
Various fixes (#733)
* Ensure string representations match the standard library Fixes #662 * Fix deepcopy of durations Fixes #714 * Default to UTC if not local timezone can be found Fixes #715
1 parent 77d1791 commit 071bf63

File tree

6 files changed

+38
-10
lines changed

6 files changed

+38
-10
lines changed

pendulum/datetime.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ class DateTime(datetime.datetime, Date):
5858
_FORMATS: ClassVar[dict[str, str | Callable[[datetime.datetime], str]]] = {
5959
"atom": ATOM,
6060
"cookie": COOKIE,
61-
"iso8601": lambda dt: dt.isoformat(),
61+
"iso8601": lambda dt: dt.isoformat("T"),
6262
"rfc822": RFC822,
6363
"rfc850": RFC850,
6464
"rfc1036": RFC1036,
6565
"rfc1123": RFC1123,
6666
"rfc2822": RFC2822,
67-
"rfc3339": lambda dt: dt.isoformat(),
67+
"rfc3339": lambda dt: dt.isoformat("T"),
6868
"rss": RSS,
6969
"w3c": W3C,
7070
}
@@ -468,7 +468,7 @@ def _to_string(self, fmt: str, locale: str | None = None) -> str:
468468
return self.format(fmt_value, locale=locale)
469469

470470
def __str__(self) -> str:
471-
return self.isoformat("T")
471+
return self.isoformat(" ")
472472

473473
def __repr__(self) -> str:
474474
us = ""

pendulum/duration.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,17 @@ def __divmod__(self, other: timedelta) -> tuple[int, Duration]:
446446

447447
return NotImplemented
448448

449+
def __deepcopy__(self, _: dict[int, Self]) -> Self:
450+
return self.__class__(
451+
days=self.remaining_days,
452+
seconds=self.remaining_seconds,
453+
microseconds=self.microseconds,
454+
minutes=self.minutes,
455+
hours=self.hours,
456+
years=self.years,
457+
months=self.months,
458+
)
459+
449460

450461
Duration.min = Duration(days=-999999999)
451462
Duration.max = Duration(

pendulum/mixins/default.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def for_json(self) -> str:
2222
"""
2323
Methods for automatic json serialization by simplejson.
2424
"""
25-
return str(self)
25+
return self.isoformat()
2626

2727
def __format__(self, format_spec: str) -> str:
2828
if len(format_spec) > 0:

pendulum/tz/local_timezone.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
import os
55
import re
66
import sys
7+
import warnings
78

89
from contextlib import contextmanager
910
from typing import Iterator
1011
from typing import cast
1112

1213
from pendulum.tz.exceptions import InvalidTimezone
14+
from pendulum.tz.timezone import UTC
1315
from pendulum.tz.timezone import FixedTimezone
1416
from pendulum.tz.timezone import Timezone
1517

@@ -239,7 +241,11 @@ def _get_unix_timezone(_root: str = "/") -> Timezone:
239241
with open(tzpath, "rb") as f:
240242
return Timezone.from_file(f)
241243

242-
raise RuntimeError("Unable to find any timezone configuration")
244+
warnings.warn(
245+
"Unable not find any timezone configuration, defaulting to UTC.", stacklevel=1
246+
)
247+
248+
return UTC
243249

244250

245251
def _tz_from_env(tzenv: str) -> Timezone:

tests/datetime/test_strings.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
def test_to_string():
99
d = pendulum.datetime(1975, 12, 25, 0, 0, 0, 0, tz="local")
10-
assert str(d) == d.to_iso8601_string()
10+
assert str(d) == "1975-12-25 00:00:00-05:00"
1111
d = pendulum.datetime(1975, 12, 25, 0, 0, 0, 123456, tz="local")
12-
assert str(d) == d.to_iso8601_string()
12+
assert str(d) == "1975-12-25 00:00:00.123456-05:00"
1313

1414

1515
def test_to_date_string():
@@ -135,7 +135,7 @@ def test_for_json():
135135

136136
def test_format():
137137
d = pendulum.datetime(1975, 12, 25, 14, 15, 16, tz="Europe/Paris")
138-
assert f"{d}" == "1975-12-25T14:15:16+01:00"
138+
assert f"{d}" == "1975-12-25 14:15:16+01:00"
139139
assert f"{d:YYYY}" == "1975"
140140
assert f"{d:%Y}" == "1975"
141141
assert f"{d:%H:%M %d.%m.%Y}" == "14:15 25.12.1975"

tests/duration/test_behavior.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,31 @@
22

33
import pickle
44

5+
from copy import deepcopy
56
from datetime import timedelta
67

78
import pendulum
89

10+
from tests.conftest import assert_duration
911

10-
def test_pickle():
12+
13+
def test_pickle() -> None:
1114
it = pendulum.duration(days=3, seconds=2456, microseconds=123456)
1215
s = pickle.dumps(it)
1316
it2 = pickle.loads(s)
1417

1518
assert it == it2
1619

1720

18-
def test_comparison_to_timedelta():
21+
def test_comparison_to_timedelta() -> None:
1922
duration = pendulum.duration(days=3)
2023

2124
assert duration < timedelta(days=4)
25+
26+
27+
def test_deepcopy() -> None:
28+
duration = pendulum.duration(months=1)
29+
copied_duration = deepcopy(duration)
30+
31+
assert copied_duration == duration
32+
assert_duration(copied_duration, months=1)

0 commit comments

Comments
 (0)