From 944a7950f9ccb85743321fc21a4aaec5a2365df5 Mon Sep 17 00:00:00 2001 From: Luke Bakken Date: Fri, 8 Jul 2016 11:57:37 -0700 Subject: [PATCH 1/4] Take datetime objects into account that have tzinfo information. Fixes #483 --- riak/tests/test_datetime.py | 30 ++++++++++++++++++++++++++++++ riak/tz.py | 17 +++++++++++++++++ riak/util.py | 12 ++++++++++-- tox.ini | 2 +- 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 riak/tests/test_datetime.py create mode 100644 riak/tz.py diff --git a/riak/tests/test_datetime.py b/riak/tests/test_datetime.py new file mode 100644 index 00000000..2b2aa6a3 --- /dev/null +++ b/riak/tests/test_datetime.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +import datetime +import unittest + +from riak.util import epoch, epoch_tz, \ + unix_time_millis, \ + datetime_from_unix_time_millis + +# NB: without tzinfo, this is UTC +ts0 = datetime.datetime(2015, 1, 1, 12, 1, 2, 987000) +ts0_ts = 1420113662987 +ts0_ts_pst = 1420142462987 + + +class DatetimeUnitTests(unittest.TestCase): + def test_get_unix_time_without_tzinfo(self): + self.assertIsNone(epoch.tzinfo) + self.assertIsNone(ts0.tzinfo) + utm = unix_time_millis(ts0) + self.assertEqual(utm, ts0_ts) + + def test_get_unix_time_with_tzinfo(self): + try: + import pytz + tz = pytz.timezone('America/Los_Angeles') + ts0_pst = tz.localize(ts0) + utm = unix_time_millis(ts0_pst) + self.assertEqual(utm, ts0_ts_pst) + except ImportError: + pass diff --git a/riak/tz.py b/riak/tz.py new file mode 100644 index 00000000..dd4dec01 --- /dev/null +++ b/riak/tz.py @@ -0,0 +1,17 @@ +from datetime import tzinfo, timedelta + +ZERO = timedelta(0) + +class UTC(tzinfo): + """UTC""" + + def utcoffset(self, dt): + return ZERO + + def tzname(self, dt): + return "UTC" + + def dst(self, dt): + return ZERO + +utc = UTC() diff --git a/riak/util.py b/riak/util.py index 4dfc310a..3f826837 100644 --- a/riak/util.py +++ b/riak/util.py @@ -8,10 +8,18 @@ from six import string_types, PY2 epoch = datetime.datetime.utcfromtimestamp(0) - +try: + import pytz + epoch_tz = pytz.utc.localize(epoch) +except ImportError: + from riak.tz import utc + epoch_tz = datetime.datetime.fromtimestamp(0, tz=utc) def unix_time_millis(dt): - td = dt - epoch + if dt.tzinfo: + td = dt - epoch_tz + else: + td = dt - epoch tdms = ((td.days * 24 * 3600) + td.seconds) * 1000 ms = td.microseconds // 1000 return tdms + ms diff --git a/tox.ini b/tox.ini index 079cb0b0..01d165d8 100644 --- a/tox.ini +++ b/tox.ini @@ -12,5 +12,5 @@ basepython = {env:HOME}/.pyenv/versions/riak-py278/bin/python2.7 [testenv] install_command = pip install --upgrade {packages} commands = {envpython} setup.py test -deps = pip +deps = pip pytz passenv = RUN_* SKIP_* RIAK_* From e8887760d5b500efe19a869ee9a1f2f6c28df5d2 Mon Sep 17 00:00:00 2001 From: Luke Bakken Date: Fri, 8 Jul 2016 12:00:05 -0700 Subject: [PATCH 2/4] Fix lint --- riak/tests/test_datetime.py | 4 ++-- riak/tz.py | 1 + riak/util.py | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/riak/tests/test_datetime.py b/riak/tests/test_datetime.py index 2b2aa6a3..a3640105 100644 --- a/riak/tests/test_datetime.py +++ b/riak/tests/test_datetime.py @@ -3,8 +3,7 @@ import unittest from riak.util import epoch, epoch_tz, \ - unix_time_millis, \ - datetime_from_unix_time_millis + unix_time_millis # NB: without tzinfo, this is UTC ts0 = datetime.datetime(2015, 1, 1, 12, 1, 2, 987000) @@ -15,6 +14,7 @@ class DatetimeUnitTests(unittest.TestCase): def test_get_unix_time_without_tzinfo(self): self.assertIsNone(epoch.tzinfo) + self.assertIsNotNone(epoch_tz.tzinfo) self.assertIsNone(ts0.tzinfo) utm = unix_time_millis(ts0) self.assertEqual(utm, ts0_ts) diff --git a/riak/tz.py b/riak/tz.py index dd4dec01..30544b9f 100644 --- a/riak/tz.py +++ b/riak/tz.py @@ -2,6 +2,7 @@ ZERO = timedelta(0) + class UTC(tzinfo): """UTC""" diff --git a/riak/util.py b/riak/util.py index 3f826837..e3124612 100644 --- a/riak/util.py +++ b/riak/util.py @@ -15,6 +15,7 @@ from riak.tz import utc epoch_tz = datetime.datetime.fromtimestamp(0, tz=utc) + def unix_time_millis(dt): if dt.tzinfo: td = dt - epoch_tz From ae33a2993c62cfcc3f872ace4fe7a9d8fed81cf5 Mon Sep 17 00:00:00 2001 From: Luke Bakken Date: Sat, 9 Jul 2016 09:12:20 -0700 Subject: [PATCH 3/4] add pytz to tox.ini --- tox.ini | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 01d165d8..10387e42 100644 --- a/tox.ini +++ b/tox.ini @@ -12,5 +12,7 @@ basepython = {env:HOME}/.pyenv/versions/riak-py278/bin/python2.7 [testenv] install_command = pip install --upgrade {packages} commands = {envpython} setup.py test -deps = pip pytz +deps = + pip + pytz passenv = RUN_* SKIP_* RIAK_* From b770f7f8cf1c8683c07741c992e581bdf5ea700e Mon Sep 17 00:00:00 2001 From: Luke Bakken Date: Mon, 11 Jul 2016 15:26:57 -0700 Subject: [PATCH 4/4] Fix TS pbuf tests on Python 3.X where results are bytes --- riak/tests/test_timeseries_pbuf.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/riak/tests/test_timeseries_pbuf.py b/riak/tests/test_timeseries_pbuf.py index 2db1af9e..4588d01d 100644 --- a/riak/tests/test_timeseries_pbuf.py +++ b/riak/tests/test_timeseries_pbuf.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import datetime +import six import unittest import riak.pb.riak_ts_pb2 @@ -457,5 +458,6 @@ def test_store_and_fetch_gh_483(self): row = ts_obj.rows[0] self.assertEqual(len(row), 5) - exp = rows[0] + exp = [six.b('hash1'), six.b('user2'), now, + six.b('frazzle'), 12.3] self.assertEqual(row, exp)