Skip to content

Commit 249cccf

Browse files
committed
Fixes __add__, __sub__ and __neg__ for intervals
1 parent 8072b78 commit 249cccf

File tree

6 files changed

+145
-9
lines changed

6 files changed

+145
-9
lines changed

pendulum/pendulum_interval.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -233,26 +233,22 @@ def __repr__(self):
233233

234234
def __add__(self, other):
235235
if isinstance(other, timedelta):
236-
return PendulumInterval(self._days + other._days,
237-
self._seconds + other._seconds,
238-
self._microseconds + other._microseconds)
236+
return PendulumInterval(seconds=self.total_seconds() + other.total_seconds())
237+
239238
return NotImplemented
240239

241240
def __sub__(self, other):
242241
if isinstance(other, timedelta):
243242
# for CPython compatibility, we cannot use
244243
# our __class__ here, but need a real timedelta
245-
return PendulumInterval(self._days - other._days,
246-
self._seconds - other._seconds,
247-
self._microseconds - other._microseconds)
244+
return PendulumInterval(seconds=self.total_seconds() - other.total_seconds())
245+
248246
return NotImplemented
249247

250248
def __neg__(self):
251249
# for CPython compatibility, we cannot use
252250
# our __class__ here, but need a real timedelta
253-
return PendulumInterval(-self._days,
254-
-self._seconds,
255-
-self._microseconds)
251+
return PendulumInterval(seconds=-self.total_seconds())
256252

257253

258254
class AbsolutePendulumInterval(PendulumInterval):
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from datetime import timedelta
4+
from pendulum import PendulumInterval
5+
6+
from .. import AbstractTestCase
7+
8+
9+
class AddSubTestCase(AbstractTestCase):
10+
11+
def test_add_interval(self):
12+
p1 = PendulumInterval(days=23, seconds=32)
13+
p2 = PendulumInterval(days=12, seconds=30)
14+
15+
p = p1 + p2
16+
self.assertInterval(p, 5, 0, 0, 1, 2)
17+
18+
def test_add_timedelta(self):
19+
p1 = PendulumInterval(days=23, seconds=32)
20+
p2 = timedelta(days=12, seconds=30)
21+
22+
p = p1 + p2
23+
self.assertInterval(p, 5, 0, 0, 1, 2)
24+
25+
def test_add_unsupported(self):
26+
p = PendulumInterval(days=23, seconds=32)
27+
self.assertEqual(NotImplemented, p.__add__(5))
28+
29+
def test_sub_interval(self):
30+
p1 = PendulumInterval(days=23, seconds=32)
31+
p2 = PendulumInterval(days=12, seconds=28)
32+
33+
p = p1 - p2
34+
self.assertInterval(p, 1, 4, 0, 0, 4)
35+
36+
def test_sub_timedelta(self):
37+
p1 = PendulumInterval(days=23, seconds=32)
38+
p2 = timedelta(days=12, seconds=28)
39+
40+
p = p1 - p2
41+
self.assertInterval(p, 1, 4, 0, 0, 4)
42+
43+
def test_sub_unsupported(self):
44+
p = PendulumInterval(days=23, seconds=32)
45+
self.assertEqual(NotImplemented, p.__sub__(5))
46+
47+
def test_neg(self):
48+
p = PendulumInterval(days=23, seconds=32)
49+
self.assertInterval(-p, -4, -5, 0, 0, -28)

tests/interval_tests/test_construct.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# -*- coding: utf-8 -*-
22

3+
from datetime import timedelta
34
from pendulum import PendulumInterval
5+
from pendulum.pendulum_interval import AbsolutePendulumInterval
46

57
from .. import AbstractTestCase
68

@@ -40,3 +42,19 @@ def test_minutes(self):
4042
def test_all(self):
4143
pi = PendulumInterval(days=1177, seconds=7284, microseconds=1000000)
4244
self.assertInterval(pi, 168, 1, 2, 1, 25)
45+
46+
def test_instance(self):
47+
pi = PendulumInterval.instance(timedelta(days=1177, seconds=7284, microseconds=1000000))
48+
self.assertInterval(pi, 168, 1, 2, 1, 25)
49+
50+
def test_absolute_interval(self):
51+
pi = AbsolutePendulumInterval(days=-1177, seconds=-7284, microseconds=-1000001)
52+
self.assertInterval(pi, 168, 1, 2, 1, 25)
53+
self.assertEqual(999999, pi.microseconds)
54+
55+
def test_invert(self):
56+
pi = PendulumInterval(days=1177, seconds=7284, microseconds=1000000)
57+
self.assertFalse(pi.invert)
58+
59+
pi = PendulumInterval(days=-1177, seconds=-7284, microseconds=-1000000)
60+
self.assertTrue(pi.invert)

tests/interval_tests/test_in_words.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,10 @@ def test_in_french(self):
3636
'168 semaines 1 jour 2 heures 1 minute 25 secondes',
3737
pi.in_words(locale='fr')
3838
)
39+
40+
def test_repr(self):
41+
pi = PendulumInterval(days=1177, seconds=7284, microseconds=1000000)
42+
self.assertEqual(
43+
'168 weeks 1 day 2 hours 1 minute 25 seconds',
44+
repr(pi)
45+
)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from pendulum import PendulumInterval
4+
from pendulum.translator import Translator
5+
6+
from .. import AbstractTestCase
7+
8+
9+
class LocaleTest(AbstractTestCase):
10+
11+
def test_get_locale(self):
12+
pi = PendulumInterval
13+
self.assertEqual('en', pi.get_locale())
14+
15+
pi.set_locale('fr')
16+
self.assertEqual('fr', pi.get_locale())
17+
18+
pi.set_locale('en')
19+
20+
def test_set_invalid_locale(self):
21+
pi = PendulumInterval
22+
self.assertFalse(pi.set_locale('invalid'))
23+
24+
def test_set_translator(self):
25+
pi = PendulumInterval
26+
t = Translator('en')
27+
pi.set_translator(t)
28+
self.assertIs(t, pi.translator())
29+
30+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from pendulum.pendulum_interval import PendulumInterval
4+
5+
from .. import AbstractTestCase
6+
7+
8+
class TotalMethodsTest(AbstractTestCase):
9+
10+
def test_total_years(self):
11+
it = PendulumInterval(days=365)
12+
self.assertEqual(1, it.total_years())
13+
14+
def test_in_months(self):
15+
it = PendulumInterval(days=75)
16+
self.assertEqual(2.5, it.total_months())
17+
18+
def test_in_weeks(self):
19+
it = PendulumInterval(days=17)
20+
self.assertEqual(2.43, round(it.total_weeks(), 2))
21+
22+
def test_in_days(self):
23+
it = PendulumInterval(days=3)
24+
self.assertEqual(3, it.total_days())
25+
26+
def test_in_hours(self):
27+
it = PendulumInterval(days=3, minutes=72)
28+
self.assertEqual(73.2, it.total_hours())
29+
30+
def test_in_minutes(self):
31+
it = PendulumInterval(minutes=6, seconds=72)
32+
self.assertEqual(7.2, it.total_minutes())
33+
34+
def test_in_seconds(self):
35+
it = PendulumInterval(seconds=72, microseconds=123456)
36+
self.assertEqual(72.123456, it.total_seconds())

0 commit comments

Comments
 (0)