Skip to content

Commit dd25e45

Browse files
committed
Moving Bigtable helpers for duration protobufs into core.
1 parent 5a42aca commit dd25e45

File tree

4 files changed

+117
-121
lines changed

4 files changed

+117
-121
lines changed

bigtable/google/cloud/bigtable/column_family.py

Lines changed: 3 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -15,62 +15,13 @@
1515
"""User friendly container for Google Cloud Bigtable Column Family."""
1616

1717

18-
import datetime
19-
20-
from google.protobuf import duration_pb2
21-
18+
from google.cloud import _helpers
2219
from google.cloud.bigtable._generated import (
2320
table_pb2 as table_v2_pb2)
2421
from google.cloud.bigtable._generated import (
2522
bigtable_table_admin_pb2 as table_admin_v2_pb2)
2623

2724

28-
def _timedelta_to_duration_pb(timedelta_val):
29-
"""Convert a Python timedelta object to a duration protobuf.
30-
31-
.. note::
32-
33-
The Python timedelta has a granularity of microseconds while
34-
the protobuf duration type has a duration of nanoseconds.
35-
36-
:type timedelta_val: :class:`datetime.timedelta`
37-
:param timedelta_val: A timedelta object.
38-
39-
:rtype: :class:`google.protobuf.duration_pb2.Duration`
40-
:returns: A duration object equivalent to the time delta.
41-
"""
42-
seconds_decimal = timedelta_val.total_seconds()
43-
# Truncate the parts other than the integer.
44-
seconds = int(seconds_decimal)
45-
if seconds_decimal < 0:
46-
signed_micros = timedelta_val.microseconds - 10**6
47-
else:
48-
signed_micros = timedelta_val.microseconds
49-
# Convert nanoseconds to microseconds.
50-
nanos = 1000 * signed_micros
51-
return duration_pb2.Duration(seconds=seconds, nanos=nanos)
52-
53-
54-
def _duration_pb_to_timedelta(duration_pb):
55-
"""Convert a duration protobuf to a Python timedelta object.
56-
57-
.. note::
58-
59-
The Python timedelta has a granularity of microseconds while
60-
the protobuf duration type has a duration of nanoseconds.
61-
62-
:type duration_pb: :class:`google.protobuf.duration_pb2.Duration`
63-
:param duration_pb: A protobuf duration object.
64-
65-
:rtype: :class:`datetime.timedelta`
66-
:returns: The converted timedelta object.
67-
"""
68-
return datetime.timedelta(
69-
seconds=duration_pb.seconds,
70-
microseconds=(duration_pb.nanos / 1000.0),
71-
)
72-
73-
7425
class GarbageCollectionRule(object):
7526
"""Garbage collection rule for column families within a table.
7627
@@ -137,7 +88,7 @@ def to_pb(self):
13788
:rtype: :class:`.table_v2_pb2.GcRule`
13889
:returns: The converted current object.
13990
"""
140-
max_age = _timedelta_to_duration_pb(self.max_age)
91+
max_age = _helpers._timedelta_to_duration_pb(self.max_age)
14192
return table_v2_pb2.GcRule(max_age=max_age)
14293

14394

@@ -325,7 +276,7 @@ def _gc_rule_from_pb(gc_rule_pb):
325276
if rule_name == 'max_num_versions':
326277
return MaxVersionsGCRule(gc_rule_pb.max_num_versions)
327278
elif rule_name == 'max_age':
328-
max_age = _duration_pb_to_timedelta(gc_rule_pb.max_age)
279+
max_age = _helpers._duration_pb_to_timedelta(gc_rule_pb.max_age)
329280
return MaxAgeGCRule(max_age)
330281
elif rule_name == 'union':
331282
return GCRuleUnion([_gc_rule_from_pb(rule)

bigtable/unit_tests/test_column_family.py

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -16,75 +16,6 @@
1616
import unittest
1717

1818

19-
class Test__timedelta_to_duration_pb(unittest.TestCase):
20-
21-
def _call_fut(self, *args, **kwargs):
22-
from google.cloud.bigtable.column_family import (
23-
_timedelta_to_duration_pb)
24-
25-
return _timedelta_to_duration_pb(*args, **kwargs)
26-
27-
def test_it(self):
28-
import datetime
29-
from google.protobuf import duration_pb2
30-
31-
seconds = microseconds = 1
32-
timedelta_val = datetime.timedelta(seconds=seconds,
33-
microseconds=microseconds)
34-
result = self._call_fut(timedelta_val)
35-
self.assertIsInstance(result, duration_pb2.Duration)
36-
self.assertEqual(result.seconds, seconds)
37-
self.assertEqual(result.nanos, 1000 * microseconds)
38-
39-
def test_with_negative_microseconds(self):
40-
import datetime
41-
from google.protobuf import duration_pb2
42-
43-
seconds = 1
44-
microseconds = -5
45-
timedelta_val = datetime.timedelta(seconds=seconds,
46-
microseconds=microseconds)
47-
result = self._call_fut(timedelta_val)
48-
self.assertIsInstance(result, duration_pb2.Duration)
49-
self.assertEqual(result.seconds, seconds - 1)
50-
self.assertEqual(result.nanos, 10**9 + 1000 * microseconds)
51-
52-
def test_with_negative_seconds(self):
53-
import datetime
54-
from google.protobuf import duration_pb2
55-
56-
seconds = -1
57-
microseconds = 5
58-
timedelta_val = datetime.timedelta(seconds=seconds,
59-
microseconds=microseconds)
60-
result = self._call_fut(timedelta_val)
61-
self.assertIsInstance(result, duration_pb2.Duration)
62-
self.assertEqual(result.seconds, seconds + 1)
63-
self.assertEqual(result.nanos, -(10**9 - 1000 * microseconds))
64-
65-
66-
class Test__duration_pb_to_timedelta(unittest.TestCase):
67-
68-
def _call_fut(self, *args, **kwargs):
69-
from google.cloud.bigtable.column_family import (
70-
_duration_pb_to_timedelta)
71-
72-
return _duration_pb_to_timedelta(*args, **kwargs)
73-
74-
def test_it(self):
75-
import datetime
76-
from google.protobuf import duration_pb2
77-
78-
seconds = microseconds = 1
79-
duration_pb = duration_pb2.Duration(seconds=seconds,
80-
nanos=1000 * microseconds)
81-
timedelta_val = datetime.timedelta(seconds=seconds,
82-
microseconds=microseconds)
83-
result = self._call_fut(duration_pb)
84-
self.assertIsInstance(result, datetime.timedelta)
85-
self.assertEqual(result, timedelta_val)
86-
87-
8819
class TestMaxVersionsGCRule(unittest.TestCase):
8920

9021
@staticmethod

core/google/cloud/_helpers.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from threading import local as Local
2828

2929
import google.auth
30+
from google.protobuf import duration_pb2
3031
from google.protobuf import timestamp_pb2
3132
import google_auth_httplib2
3233

@@ -424,6 +425,52 @@ def _datetime_to_pb_timestamp(when):
424425
return timestamp_pb2.Timestamp(seconds=seconds, nanos=nanos)
425426

426427

428+
def _timedelta_to_duration_pb(timedelta_val):
429+
"""Convert a Python timedelta object to a duration protobuf.
430+
431+
.. note::
432+
433+
The Python timedelta has a granularity of microseconds while
434+
the protobuf duration type has a duration of nanoseconds.
435+
436+
:type timedelta_val: :class:`datetime.timedelta`
437+
:param timedelta_val: A timedelta object.
438+
439+
:rtype: :class:`google.protobuf.duration_pb2.Duration`
440+
:returns: A duration object equivalent to the time delta.
441+
"""
442+
seconds_decimal = timedelta_val.total_seconds()
443+
# Truncate the parts other than the integer.
444+
seconds = int(seconds_decimal)
445+
if seconds_decimal < 0:
446+
signed_micros = timedelta_val.microseconds - 10**6
447+
else:
448+
signed_micros = timedelta_val.microseconds
449+
# Convert nanoseconds to microseconds.
450+
nanos = 1000 * signed_micros
451+
return duration_pb2.Duration(seconds=seconds, nanos=nanos)
452+
453+
454+
def _duration_pb_to_timedelta(duration_pb):
455+
"""Convert a duration protobuf to a Python timedelta object.
456+
457+
.. note::
458+
459+
The Python timedelta has a granularity of microseconds while
460+
the protobuf duration type has a duration of nanoseconds.
461+
462+
:type duration_pb: :class:`google.protobuf.duration_pb2.Duration`
463+
:param duration_pb: A protobuf duration object.
464+
465+
:rtype: :class:`datetime.timedelta`
466+
:returns: The converted timedelta object.
467+
"""
468+
return datetime.timedelta(
469+
seconds=duration_pb.seconds,
470+
microseconds=(duration_pb.nanos / 1000.0),
471+
)
472+
473+
427474
def _name_from_project_path(path, project, template):
428475
"""Validate a URI path and get the leaf object's name.
429476

core/unit_tests/test__helpers.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,73 @@ def test_it(self):
594594
self.assertEqual(self._call_fut(dt_stamp), timestamp)
595595

596596

597+
class Test__timedelta_to_duration_pb(unittest.TestCase):
598+
599+
def _call_fut(self, *args, **kwargs):
600+
from google.cloud._helpers import _timedelta_to_duration_pb
601+
602+
return _timedelta_to_duration_pb(*args, **kwargs)
603+
604+
def test_it(self):
605+
import datetime
606+
from google.protobuf import duration_pb2
607+
608+
seconds = microseconds = 1
609+
timedelta_val = datetime.timedelta(seconds=seconds,
610+
microseconds=microseconds)
611+
result = self._call_fut(timedelta_val)
612+
self.assertIsInstance(result, duration_pb2.Duration)
613+
self.assertEqual(result.seconds, seconds)
614+
self.assertEqual(result.nanos, 1000 * microseconds)
615+
616+
def test_with_negative_microseconds(self):
617+
import datetime
618+
from google.protobuf import duration_pb2
619+
620+
seconds = 1
621+
microseconds = -5
622+
timedelta_val = datetime.timedelta(seconds=seconds,
623+
microseconds=microseconds)
624+
result = self._call_fut(timedelta_val)
625+
self.assertIsInstance(result, duration_pb2.Duration)
626+
self.assertEqual(result.seconds, seconds - 1)
627+
self.assertEqual(result.nanos, 10**9 + 1000 * microseconds)
628+
629+
def test_with_negative_seconds(self):
630+
import datetime
631+
from google.protobuf import duration_pb2
632+
633+
seconds = -1
634+
microseconds = 5
635+
timedelta_val = datetime.timedelta(seconds=seconds,
636+
microseconds=microseconds)
637+
result = self._call_fut(timedelta_val)
638+
self.assertIsInstance(result, duration_pb2.Duration)
639+
self.assertEqual(result.seconds, seconds + 1)
640+
self.assertEqual(result.nanos, -(10**9 - 1000 * microseconds))
641+
642+
643+
class Test__duration_pb_to_timedelta(unittest.TestCase):
644+
645+
def _call_fut(self, *args, **kwargs):
646+
from google.cloud._helpers import _duration_pb_to_timedelta
647+
648+
return _duration_pb_to_timedelta(*args, **kwargs)
649+
650+
def test_it(self):
651+
import datetime
652+
from google.protobuf import duration_pb2
653+
654+
seconds = microseconds = 1
655+
duration_pb = duration_pb2.Duration(seconds=seconds,
656+
nanos=1000 * microseconds)
657+
timedelta_val = datetime.timedelta(seconds=seconds,
658+
microseconds=microseconds)
659+
result = self._call_fut(duration_pb)
660+
self.assertIsInstance(result, datetime.timedelta)
661+
self.assertEqual(result, timedelta_val)
662+
663+
597664
class Test__name_from_project_path(unittest.TestCase):
598665

599666
PROJECT = 'PROJECT'

0 commit comments

Comments
 (0)