Skip to content

Commit 5b0b216

Browse files
committed
Moving _get_pb_property_value from bigtable into core.
Doing this so that we can factor out `_has_field` and use it across packages. This is because `HasField()` works differently in `proto3` and we use this behavior from time to time.
1 parent c0fd747 commit 5b0b216

File tree

4 files changed

+62
-46
lines changed

4 files changed

+62
-46
lines changed

gcloud/_helpers.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,45 @@ def _to_bytes(value, encoding='ascii'):
322322
raise TypeError('%r could not be converted to bytes' % (value,))
323323

324324

325+
def _has_field(message_pb, property_name):
326+
"""Determine if a field is set on a protobuf.
327+
328+
:type message_pb: :class:`google.protobuf.message.Message`
329+
:param message_pb: The message to check for ``property_name``.
330+
331+
:type property_name: str
332+
:param property_name: The property value to check against.
333+
334+
:rtype: bool
335+
:returns: Flag indicating if ``property_name`` is set on ``message_pb``.
336+
"""
337+
# NOTE: As of proto3, HasField() only works for message fields, not for
338+
# singular (non-message) fields.
339+
all_fields = set([field.name for field in message_pb._fields])
340+
return property_name in all_fields
341+
342+
343+
def _get_pb_property_value(message_pb, property_name):
344+
"""Return a message field value.
345+
346+
:type message_pb: :class:`google.protobuf.message.Message`
347+
:param message_pb: The message to check for ``property_name``.
348+
349+
:type property_name: str
350+
:param property_name: The property value to check against.
351+
352+
:rtype: object
353+
:returns: The value of ``property_name`` set on ``message_pb``.
354+
:raises: :class:`ValueError <exceptions.ValueError>` if the result returned
355+
from the ``message_pb`` does not contain the ``property_name``
356+
value.
357+
"""
358+
if _has_field(message_pb, property_name):
359+
return getattr(message_pb, property_name)
360+
else:
361+
raise ValueError('Message does not contain %s.' % (property_name,))
362+
363+
325364
try:
326365
from pytz import UTC # pylint: disable=unused-import,wrong-import-position
327366
except ImportError:

gcloud/bigtable/cluster.py

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import re
2020

2121
from gcloud._helpers import _EPOCH
22+
from gcloud._helpers import _get_pb_property_value
2223
from gcloud.bigtable._generated import bigtable_cluster_data_pb2 as data_pb2
2324
from gcloud.bigtable._generated import (
2425
bigtable_cluster_service_messages_pb2 as messages_pb2)
@@ -47,30 +48,6 @@
4748
}
4849

4950

50-
def _get_pb_property_value(message_pb, property_name):
51-
"""Return a message field value.
52-
53-
:type message_pb: :class:`google.protobuf.message.Message`
54-
:param message_pb: The message to check for ``property_name``.
55-
56-
:type property_name: str
57-
:param property_name: The property value to check against.
58-
59-
:rtype: object
60-
:returns: The value of ``property_name`` set on ``message_pb``.
61-
:raises: :class:`ValueError <exceptions.ValueError>` if the result returned
62-
from the ``message_pb`` does not contain the ``property_name``
63-
value.
64-
"""
65-
# Make sure `property_name` is set on the response.
66-
# NOTE: As of proto3, HasField() only works for message fields, not for
67-
# singular (non-message) fields.
68-
all_fields = set([field.name for field in message_pb._fields])
69-
if property_name not in all_fields:
70-
raise ValueError('Message does not contain %s.' % (property_name,))
71-
return getattr(message_pb, property_name)
72-
73-
7451
def _prepare_create_request(cluster):
7552
"""Creates a protobuf request for a CreateCluster request.
7653

gcloud/bigtable/test_cluster.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -631,28 +631,6 @@ def test_list_tables_failure_name_bad_before(self):
631631
self._list_tables_helper(table_id, table_name=bad_table_name)
632632

633633

634-
class Test__get_pb_property_value(unittest2.TestCase):
635-
636-
def _callFUT(self, message_pb, property_name):
637-
from gcloud.bigtable.cluster import _get_pb_property_value
638-
return _get_pb_property_value(message_pb, property_name)
639-
640-
def test_it(self):
641-
from gcloud.bigtable._generated import (
642-
bigtable_cluster_data_pb2 as data_pb2)
643-
serve_nodes = 119
644-
cluster_pb = data_pb2.Cluster(serve_nodes=serve_nodes)
645-
result = self._callFUT(cluster_pb, 'serve_nodes')
646-
self.assertEqual(result, serve_nodes)
647-
648-
def test_with_value_unset_on_pb(self):
649-
from gcloud.bigtable._generated import (
650-
bigtable_cluster_data_pb2 as data_pb2)
651-
cluster_pb = data_pb2.Cluster()
652-
with self.assertRaises(ValueError):
653-
self._callFUT(cluster_pb, 'serve_nodes')
654-
655-
656634
class Test__prepare_create_request(unittest2.TestCase):
657635

658636
def _callFUT(self, cluster):

gcloud/test__helpers.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,28 @@ def test_with_nonstring_type(self):
409409
self.assertRaises(TypeError, self._callFUT, value)
410410

411411

412+
class Test__get_pb_property_value(unittest2.TestCase):
413+
414+
def _callFUT(self, message_pb, property_name):
415+
from gcloud._helpers import _get_pb_property_value
416+
return _get_pb_property_value(message_pb, property_name)
417+
418+
def test_it(self):
419+
from gcloud.bigtable._generated import (
420+
bigtable_cluster_data_pb2 as data_pb2)
421+
serve_nodes = 119
422+
cluster_pb = data_pb2.Cluster(serve_nodes=serve_nodes)
423+
result = self._callFUT(cluster_pb, 'serve_nodes')
424+
self.assertEqual(result, serve_nodes)
425+
426+
def test_with_value_unset_on_pb(self):
427+
from gcloud.bigtable._generated import (
428+
bigtable_cluster_data_pb2 as data_pb2)
429+
cluster_pb = data_pb2.Cluster()
430+
with self.assertRaises(ValueError):
431+
self._callFUT(cluster_pb, 'serve_nodes')
432+
433+
412434
class _AppIdentity(object):
413435

414436
def __init__(self, app_id):

0 commit comments

Comments
 (0)