From 1450f4f332af6b2bbf86213d061f25a4a88e068d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20BAPTISTE?= Date: Mon, 18 May 2020 11:01:53 +0200 Subject: [PATCH 1/6] fix: Makes TimePartitioning printable representation evaluable --- google/cloud/bigquery/table.py | 11 +++++++++-- tests/unit/test_table.py | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/google/cloud/bigquery/table.py b/google/cloud/bigquery/table.py index e66d24e74..cbd0d2ee6 100644 --- a/google/cloud/bigquery/table.py +++ b/google/cloud/bigquery/table.py @@ -2128,7 +2128,14 @@ def to_api_repr(self): return self._properties def _key(self): - return tuple(sorted(self._properties.items())) + properties = self._properties.copy() + if "type" in properties.keys(): + properties["type_"] = properties.pop("type") + if "requirePartitionFilter" in properties.keys(): + properties["require_partition_filter"] = properties.pop("requirePartitionFilter") + if "expirationMs" in properties.keys(): + properties["expiration_ms"] = properties.pop("expirationMs") + return tuple(sorted(properties.items())) def __eq__(self, other): if not isinstance(other, TimePartitioning): @@ -2142,7 +2149,7 @@ def __hash__(self): return hash(self._key()) def __repr__(self): - key_vals = ["{}={}".format(key, val) for key, val in self._key()] + key_vals = ["{}={}".format(key, repr(val)) for key, val in self._key()] return "TimePartitioning({})".format(",".join(key_vals)) diff --git a/tests/unit/test_table.py b/tests/unit/test_table.py index 72275fc53..be8252c4b 100644 --- a/tests/unit/test_table.py +++ b/tests/unit/test_table.py @@ -3743,7 +3743,7 @@ def test___hash__not_equals(self): def test___repr___minimal(self): time_partitioning = self._make_one() - expected = "TimePartitioning(type=DAY)" + expected = "TimePartitioning(type_='DAY')" self.assertEqual(repr(time_partitioning), expected) def test___repr___explicit(self): @@ -3752,7 +3752,7 @@ def test___repr___explicit(self): time_partitioning = self._make_one( type_=TimePartitioningType.DAY, field="name", expiration_ms=10000 ) - expected = "TimePartitioning(" "expirationMs=10000," "field=name," "type=DAY)" + expected = "TimePartitioning(" "expiration_ms=10000," "field=name," "type_='DAY')" self.assertEqual(repr(time_partitioning), expected) def test_set_expiration_w_none(self): From 73addd0f1c641d143775b802c514036414846a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20BAPTISTE?= Date: Mon, 25 May 2020 12:15:11 +0200 Subject: [PATCH 2/6] Remove implicitly concatenated strings Co-authored-by: Peter Lamut --- tests/unit/test_table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_table.py b/tests/unit/test_table.py index be8252c4b..6bc3562e2 100644 --- a/tests/unit/test_table.py +++ b/tests/unit/test_table.py @@ -3752,7 +3752,7 @@ def test___repr___explicit(self): time_partitioning = self._make_one( type_=TimePartitioningType.DAY, field="name", expiration_ms=10000 ) - expected = "TimePartitioning(" "expiration_ms=10000," "field=name," "type_='DAY')" + expected = "TimePartitioning(expiration_ms=10000,field=name,type_='DAY')" self.assertEqual(repr(time_partitioning), expected) def test_set_expiration_w_none(self): From 3a250ad9375fd12fba7a2543b454c040888631c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20BAPTISTE?= Date: Mon, 25 May 2020 13:57:56 +0200 Subject: [PATCH 3/6] fix: Call repr for non built-in type objects only --- google/cloud/bigquery/table.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/google/cloud/bigquery/table.py b/google/cloud/bigquery/table.py index cbd0d2ee6..ced8c3da1 100644 --- a/google/cloud/bigquery/table.py +++ b/google/cloud/bigquery/table.py @@ -2128,9 +2128,14 @@ def to_api_repr(self): return self._properties def _key(self): + # because we are only "renaming" top level keys shallow copy is sufficient here. properties = self._properties.copy() if "type" in properties.keys(): - properties["type_"] = properties.pop("type") + # calling repr for non built-in type objects. + properties["type_"] = repr(properties.pop("type")) + if "field" in properties.keys(): + # calling repr for non built-in type objects. + properties["field"] = repr(properties["field"]) if "requirePartitionFilter" in properties.keys(): properties["require_partition_filter"] = properties.pop("requirePartitionFilter") if "expirationMs" in properties.keys(): @@ -2149,7 +2154,7 @@ def __hash__(self): return hash(self._key()) def __repr__(self): - key_vals = ["{}={}".format(key, repr(val)) for key, val in self._key()] + key_vals = ["{}={}".format(key, val) for key, val in self._key()] return "TimePartitioning({})".format(",".join(key_vals)) From e947bdd4b10522498007463f7bcfafb88f1c3e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20BAPTISTE?= Date: Tue, 26 May 2020 16:24:38 +0200 Subject: [PATCH 4/6] TimePartitioning field "field" is now evaluable. Change test accordingly. --- tests/unit/test_table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_table.py b/tests/unit/test_table.py index 6bc3562e2..34ca31507 100644 --- a/tests/unit/test_table.py +++ b/tests/unit/test_table.py @@ -3752,7 +3752,7 @@ def test___repr___explicit(self): time_partitioning = self._make_one( type_=TimePartitioningType.DAY, field="name", expiration_ms=10000 ) - expected = "TimePartitioning(expiration_ms=10000,field=name,type_='DAY')" + expected = "TimePartitioning(expiration_ms=10000,field='name',type_='DAY')" self.assertEqual(repr(time_partitioning), expected) def test_set_expiration_w_none(self): From ab45cba800441a1656077b8daaea5c0bea93b57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20BAPTISTE?= Date: Thu, 28 May 2020 16:08:27 +0200 Subject: [PATCH 5/6] fix: lint --- google/cloud/bigquery/table.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/google/cloud/bigquery/table.py b/google/cloud/bigquery/table.py index ced8c3da1..da944062a 100644 --- a/google/cloud/bigquery/table.py +++ b/google/cloud/bigquery/table.py @@ -2137,7 +2137,9 @@ def _key(self): # calling repr for non built-in type objects. properties["field"] = repr(properties["field"]) if "requirePartitionFilter" in properties.keys(): - properties["require_partition_filter"] = properties.pop("requirePartitionFilter") + properties["require_partition_filter"] = properties.pop( + "requirePartitionFilter" + ) if "expirationMs" in properties.keys(): properties["expiration_ms"] = properties.pop("expirationMs") return tuple(sorted(properties.items())) From 7839a161e1d148484d88e9b89f1a7571a9241e4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20BAPTISTE?= Date: Thu, 28 May 2020 17:06:09 +0200 Subject: [PATCH 6/6] fix: cover issue --- google/cloud/bigquery/table.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/google/cloud/bigquery/table.py b/google/cloud/bigquery/table.py index da944062a..4b94843ca 100644 --- a/google/cloud/bigquery/table.py +++ b/google/cloud/bigquery/table.py @@ -2130,17 +2130,16 @@ def to_api_repr(self): def _key(self): # because we are only "renaming" top level keys shallow copy is sufficient here. properties = self._properties.copy() - if "type" in properties.keys(): - # calling repr for non built-in type objects. - properties["type_"] = repr(properties.pop("type")) - if "field" in properties.keys(): + # calling repr for non built-in type objects. + properties["type_"] = repr(properties.pop("type")) + if "field" in properties: # calling repr for non built-in type objects. properties["field"] = repr(properties["field"]) - if "requirePartitionFilter" in properties.keys(): + if "requirePartitionFilter" in properties: properties["require_partition_filter"] = properties.pop( "requirePartitionFilter" ) - if "expirationMs" in properties.keys(): + if "expirationMs" in properties: properties["expiration_ms"] = properties.pop("expirationMs") return tuple(sorted(properties.items()))