Skip to content

Commit 4941de4

Browse files
drokeyeLinchin
andauthored
fix: make AccessEntry equality consistent with from_api_repr (#2218)
* fix: make AccessEntry equality consistent for view entity type * fix: make AccessEntry equality consistent for view entity type * fix: use json.dumps() for normalizaiton of entity_id * remove trailing whitespace and add test assertions * revert back to the original code * fix linting in `dataset.py` * fix linting in `test_dataset.py` --------- Co-authored-by: Lingqing Gan <[email protected]>
1 parent 7c9e7fd commit 4941de4

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

‎google/cloud/bigquery/dataset.py‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from __future__ import absolute_import
1818

1919
import copy
20+
import json
2021

2122
import typing
2223
from typing import Optional, List, Dict, Any, Union
@@ -506,7 +507,20 @@ def entity_id(self) -> Optional[Union[Dict[str, Any], str]]:
506507
def __eq__(self, other):
507508
if not isinstance(other, AccessEntry):
508509
return NotImplemented
509-
return self._key() == other._key()
510+
return (
511+
self.role == other.role
512+
and self.entity_type == other.entity_type
513+
and self._normalize_entity_id(self.entity_id)
514+
== self._normalize_entity_id(other.entity_id)
515+
and self.condition == other.condition
516+
)
517+
518+
@staticmethod
519+
def _normalize_entity_id(value):
520+
"""Ensure consistent equality for dicts like 'view'."""
521+
if isinstance(value, dict):
522+
return json.dumps(value, sort_keys=True)
523+
return value
510524

511525
def __ne__(self, other):
512526
return not self == other
@@ -557,7 +571,6 @@ def from_api_repr(cls, resource: dict) -> "AccessEntry":
557571
google.cloud.bigquery.dataset.AccessEntry:
558572
Access entry parsed from ``resource``.
559573
"""
560-
561574
access_entry = cls()
562575
access_entry._properties = resource.copy()
563576
return access_entry

‎tests/unit/test_dataset.py‎

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,3 +1767,70 @@ def test__hash__with_minimal_inputs(self):
17671767
description=None,
17681768
)
17691769
assert hash(cond1) is not None
1770+
1771+
def test_access_entry_view_equality(self):
1772+
from google.cloud import bigquery
1773+
1774+
entry1 = bigquery.dataset.AccessEntry(
1775+
entity_type="view",
1776+
entity_id={
1777+
"projectId": "my_project",
1778+
"datasetId": "my_dataset",
1779+
"tableId": "my_table",
1780+
},
1781+
)
1782+
entry2 = bigquery.dataset.AccessEntry.from_api_repr(
1783+
{
1784+
"view": {
1785+
"projectId": "my_project",
1786+
"datasetId": "my_dataset",
1787+
"tableId": "my_table",
1788+
}
1789+
}
1790+
)
1791+
1792+
entry3 = bigquery.dataset.AccessEntry(
1793+
entity_type="routine",
1794+
entity_id={
1795+
"projectId": "my_project",
1796+
"datasetId": "my_dataset",
1797+
"routineId": "my_routine",
1798+
},
1799+
)
1800+
1801+
entry4 = bigquery.dataset.AccessEntry.from_api_repr(
1802+
{
1803+
"routine": {
1804+
"projectId": "my_project",
1805+
"datasetId": "my_dataset",
1806+
"routineId": "my_routine",
1807+
}
1808+
}
1809+
)
1810+
1811+
entry5 = bigquery.dataset.AccessEntry(
1812+
entity_type="dataset",
1813+
entity_id={
1814+
"dataset": {
1815+
"projectId": "my_project",
1816+
"datasetId": "my_dataset",
1817+
},
1818+
"target_types": "VIEWS",
1819+
},
1820+
)
1821+
1822+
entry6 = bigquery.dataset.AccessEntry.from_api_repr(
1823+
{
1824+
"dataset": {
1825+
"dataset": {
1826+
"projectId": "my_project",
1827+
"datasetId": "my_dataset",
1828+
},
1829+
"target_types": "VIEWS",
1830+
}
1831+
}
1832+
)
1833+
1834+
assert entry1 == entry2
1835+
assert entry3 == entry4
1836+
assert entry5 == entry6

0 commit comments

Comments
 (0)