Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add a __hash__ implementation to AccessEntry #93

Merged
merged 5 commits into from May 15, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
51 changes: 37 additions & 14 deletions google/cloud/bigquery/dataset.py
Expand Up @@ -20,6 +20,7 @@
import copy

import google.cloud._helpers

from google.cloud.bigquery import _helpers
from google.cloud.bigquery.model import ModelReference
from google.cloud.bigquery.routine import RoutineReference
Expand Down Expand Up @@ -145,38 +146,60 @@ 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

def __repr__(self):
return "<AccessEntry: role=%s, %s=%s>" % (
self.role,
self.entity_type,
self.entity_id,
self._role,
self._entity_type,
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

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
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/test_dataset.py
Expand Up @@ -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()
Expand Down