From 416bdca166987702e1e9781340518bac52fcf2cd Mon Sep 17 00:00:00 2001 From: Spencer McCreary Date: Wed, 6 May 2020 06:57:18 -0400 Subject: [PATCH 1/4] feat: add a __hash__ implementation to AccessEntry --- google/cloud/bigquery/dataset.py | 47 +++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/google/cloud/bigquery/dataset.py b/google/cloud/bigquery/dataset.py index 99c47026f..9aa3eeece 100644 --- a/google/cloud/bigquery/dataset.py +++ b/google/cloud/bigquery/dataset.py @@ -16,15 +16,16 @@ from __future__ import absolute_import -import six import copy import google.cloud._helpers +import six + from google.cloud.bigquery import _helpers +from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration from google.cloud.bigquery.model import ModelReference from google.cloud.bigquery.routine import RoutineReference from google.cloud.bigquery.table import TableReference -from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration def _get_table_reference(self, table_id): @@ -145,18 +146,29 @@ def __init__(self, role, entity_type, entity_id): "Role must be set for entity " "type %r" % (entity_type,) ) - self.role = role - self.entity_type = entity_type - self.entity_id = entity_id + self._role = role + self._entity_type = entity_type + self._entity_id = entity_id + + @property + def role(self): + """str: The role of the entry.""" + return self._role + + @property + def entity_type(self): + """str: The entity_type of the entry.""" + return self._entity_type + + @property + def entity_id(self): + """str: The entity_id of the entry.""" + return self._entity_id def __eq__(self, other): if not isinstance(other, AccessEntry): return NotImplemented - return ( - self.role == other.role - and self.entity_type == other.entity_type - and self.entity_id == other.entity_id - ) + return self._key() == other._key() def __ne__(self, other): return not self == other @@ -168,6 +180,21 @@ def __repr__(self): self.entity_id, ) + def _key(self): + """ A tuple key that uniquely describes this field. + Used to compute this instance's hashcode and evaluate equality. + Returns: + Tuple: The contents of this :class:`~google.cloud.bigquery.dataset.AccessEntry`. + """ + return ( + self._role, + self._entity_type, + self._entity_id + ) + + def __hash__(self): + return hash(self._key()) + def to_api_repr(self): """Construct the API resource representation of this access entry From 75016c04c650393a630f58236563934a72b5cd3f Mon Sep 17 00:00:00 2001 From: Spencer McCreary Date: Wed, 6 May 2020 08:15:08 -0400 Subject: [PATCH 2/4] use internal --- google/cloud/bigquery/dataset.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/google/cloud/bigquery/dataset.py b/google/cloud/bigquery/dataset.py index 9aa3eeece..f3278d3e9 100644 --- a/google/cloud/bigquery/dataset.py +++ b/google/cloud/bigquery/dataset.py @@ -16,16 +16,16 @@ from __future__ import absolute_import +import six import copy import google.cloud._helpers -import six from google.cloud.bigquery import _helpers -from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration from google.cloud.bigquery.model import ModelReference from google.cloud.bigquery.routine import RoutineReference from google.cloud.bigquery.table import TableReference +from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration def _get_table_reference(self, table_id): @@ -175,9 +175,9 @@ def __ne__(self, other): def __repr__(self): return "" % ( - self.role, - self.entity_type, - self.entity_id, + self._role, + self._entity_type, + self._entity_id, ) def _key(self): @@ -201,9 +201,9 @@ def to_api_repr(self): Returns: Dict[str, object]: Access entry represented as an API resource """ - resource = {self.entity_type: self.entity_id} - if self.role is not None: - resource["role"] = self.role + resource = {self._entity_type: self._entity_id} + if self._role is not None: + resource["role"] = self._role return resource @classmethod From 2f0cc262946a952e6d1315551c748c44ef2a934f Mon Sep 17 00:00:00 2001 From: Spencer McCreary Date: Wed, 6 May 2020 14:43:17 -0400 Subject: [PATCH 3/4] feat: unit tests for hashable AccessEntry --- tests/unit/test_dataset.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/unit/test_dataset.py b/tests/unit/test_dataset.py index ac13e0093..e4977a270 100644 --- a/tests/unit/test_dataset.py +++ b/tests/unit/test_dataset.py @@ -84,6 +84,20 @@ def test__eq___type_mismatch(self): self.assertNotEqual(entry, object()) self.assertEqual(entry, mock.ANY) + def test___hash__set_equality(self): + entry1 = self._make_one("OWNER", "userByEmail", "silly@example.com") + entry2 = self._make_one("OWNER", "userByEmail", "phred@example.com") + set_one = {entry1, entry2} + set_two = {entry1, entry2} + self.assertEqual(set_one, set_two) + + def test___hash__not_equals(self): + entry1 = self._make_one("OWNER", "userByEmail", "silly@example.com") + entry2 = self._make_one("OWNER", "userByEmail", "phred@example.com") + set_one = {entry1} + set_two = {entry2} + self.assertNotEqual(set_one, set_two) + def test_to_api_repr(self): entry = self._make_one("OWNER", "userByEmail", "salmon@example.com") resource = entry.to_api_repr() From 7dc5abacf729c9de84a13cd88197f4a1ed7d86c6 Mon Sep 17 00:00:00 2001 From: Spencer McCreary Date: Thu, 7 May 2020 08:31:33 -0400 Subject: [PATCH 4/4] fix: black lint issue --- google/cloud/bigquery/dataset.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/google/cloud/bigquery/dataset.py b/google/cloud/bigquery/dataset.py index f3278d3e9..40489a38b 100644 --- a/google/cloud/bigquery/dataset.py +++ b/google/cloud/bigquery/dataset.py @@ -186,11 +186,7 @@ def _key(self): Returns: Tuple: The contents of this :class:`~google.cloud.bigquery.dataset.AccessEntry`. """ - return ( - self._role, - self._entity_type, - self._entity_id - ) + return (self._role, self._entity_type, self._entity_id) def __hash__(self): return hash(self._key())