From 561a97bb60a34985cdfd88f84006401cbf933590 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Thu, 21 Nov 2024 15:57:26 +0000 Subject: [PATCH 1/5] likely gonna delete this branch cause TestTableSchema may not be necessary --- tests/unit/test_schema.py | 42 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/tests/unit/test_schema.py b/tests/unit/test_schema.py index ee0538b3f..7fe6d1c9b 100644 --- a/tests/unit/test_schema.py +++ b/tests/unit/test_schema.py @@ -16,9 +16,10 @@ from google.cloud.bigquery.standard_sql import StandardSqlStructType from google.cloud.bigquery.schema import ( PolicyTagList, - # ForeignTypeInfo, + ForeignTypeInfo, StorageDescriptor, SerDeInfo, + TableSchema, ) import unittest @@ -1121,8 +1122,6 @@ class TestForeignTypeInfo: @staticmethod def _get_target_class(): - from google.cloud.bigquery.schema import ForeignTypeInfo - return ForeignTypeInfo def _make_one(self, *args, **kw): @@ -1316,3 +1315,40 @@ def test_to_api_repr(self): assert serde_info.to_api_repr() == expected_repr # TODO: needs a from_api_repr() test. + +@pytest.fixture +def _make_foreign_type_info(): + return ForeignTypeInfo( + type_system="TODO_fake_type_system", + ) + + +class TestTableSchema: + @staticmethod + def _get_target_class(): + return TableSchema + + def _make_one(self, *args, **kwargs): + return self._get_target_class()(*args, **kwargs) + + def test_ctor_valid_input(self, _make_foreign_type_info): + table_schema = self._make_one( + fields="TODO needs a fields object", + foreign_type_info=_make_foreign_type_info.to_api_repr(), + ) + # Test default constructors + # Create expected TableSchema object + # * use target_class + # * use make_one + # Create result TableSchema object + # compare the two + assert False + + def test_ctor_invalid_input(self): + assert False + + def test_to_api_repr(self): + assert False + + def test_from_api_repr(self): + assert False From be6d15d429101335e3fb651c2a9beefe450d3492 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Fri, 22 Nov 2024 13:11:53 +0000 Subject: [PATCH 2/5] Adds ForeignTypeInfo test_from_api_repr --- google/cloud/bigquery/schema.py | 102 ++++++++++++++++++-------------- tests/unit/test_schema.py | 92 +++++++++++++++++----------- tests/unit/test_table.py | 20 +++++++ 3 files changed, 134 insertions(+), 80 deletions(-) diff --git a/google/cloud/bigquery/schema.py b/google/cloud/bigquery/schema.py index dc6241214..93469c57f 100644 --- a/google/cloud/bigquery/schema.py +++ b/google/cloud/bigquery/schema.py @@ -501,6 +501,7 @@ def _to_schema_fields(schema): sequence is not a :class:`~google.cloud.bigquery.schema.SchemaField` instance or a compatible mapping representation of the field. """ + for field in schema: if not isinstance(field, (SchemaField, collections.abc.Mapping)): raise ValueError( @@ -598,59 +599,59 @@ def to_api_repr(self) -> dict: return answer -class TableSchema: - """Schema of a table +# class TableSchema: +# """Schema of a table - Args: - fields (Optional[list]): Describes the fields in a table. - foreignTypeInfo (Optional[str]): Specifies metadata of the foreign data type - definition in field schema. - """ +# Args: +# fields (Optional[list]): Describes the fields in a table. +# foreignTypeInfo (Optional[str]): Specifies metadata of the foreign data type +# definition in field schema. +# """ - def __init__( - self, fields: Optional[list] = None, foreign_type_info: Optional[str] = None - ): - self._properties = {} - self.fields = fields - self.foreign_type_info = foreign_type_info +# def __init__( +# self, fields: Optional[list] = None, foreign_type_info: Optional[str] = None +# ): +# self._properties = {} +# self.fields = fields +# self.foreign_type_info = foreign_type_info - @property - def fields(self) -> Any: - """Describes the fields in a table.""" +# @property +# def fields(self) -> Any: +# """Describes the fields in a table.""" - return self._properties.get("fields") +# return self._properties.get("fields") - @fields.setter - def fields(self, value: list, dtype: str) -> str: - value = _isinstance_or_raise(value, list, none_allowed=True) - self._properties["fields"] = value +# @fields.setter +# def fields(self, value: list, dtype: str) -> str: +# value = _isinstance_or_raise(value, list, none_allowed=True) +# self._properties["fields"] = value - @property - def foreign_type_info(self) -> Any: - """Optional. Specifies metadata of the foreign data type definition in - field schema (TableFieldSchema.foreign_type_definition).""" +# @property +# def foreign_type_info(self) -> Any: +# """Optional. Specifies metadata of the foreign data type definition in +# field schema (TableFieldSchema.foreign_type_definition).""" - return self._properties.get("foreignTypeInfo") +# return self._properties.get("foreignTypeInfo") - @foreign_type_info.setter - def foreign_type_info(self, value: str, dtype: str) -> str: - if not isinstance(value, str): - raise ValueError( - f"Pass {value} as a '{repr(dtype)}'." f"Got {type(value)}." - ) - self._properties["foreignTypeInfo"] = value +# @foreign_type_info.setter +# def foreign_type_info(self, value: str, dtype: str) -> str: +# if not isinstance(value, str): +# raise ValueError( +# f"Pass {value} as a '{repr(dtype)}'." f"Got {type(value)}." +# ) +# self._properties["foreignTypeInfo"] = value - def to_api_repr(self) -> dict: - """Build an API representation of this object. +# def to_api_repr(self) -> dict: +# """Build an API representation of this object. - Returns: - Dict[str, Any]: - A dictionary in the format used by the BigQuery API. - """ - return copy.deepcopy(self._properties) +# Returns: +# Dict[str, Any]: +# A dictionary in the format used by the BigQuery API. +# """ +# return copy.deepcopy(self._properties) - def from_api_repr(self, resource): - return _from_api_repr(self, resource) +# def from_api_repr(self, resource): +# return _from_api_repr(self, resource) class ForeignTypeInfo: @@ -686,9 +687,22 @@ def to_api_repr(self) -> dict: A dictionary in the format used by the BigQuery API. """ return copy.deepcopy(self._properties) + + @classmethod + def from_api_repr(cls, resource): + """Factory: constructs an instance of the class (cls) + given its API representation. - def from_api_repr(self, resource): - return _from_api_repr(self, resource) + Args: + resource (Dict[str, Any]): + API representation of the object to be instantiated. + + Returns: + An instance of the class initialized with data from 'resource'. + """ + config = cls() + config._properties = copy.deepcopy(resource) + return config class StorageDescriptor: diff --git a/tests/unit/test_schema.py b/tests/unit/test_schema.py index 7fe6d1c9b..4eb1e20d8 100644 --- a/tests/unit/test_schema.py +++ b/tests/unit/test_schema.py @@ -19,7 +19,7 @@ ForeignTypeInfo, StorageDescriptor, SerDeInfo, - TableSchema, + # TODO: delete this line...TableSchema, ) import unittest @@ -1159,6 +1159,26 @@ def test_to_api_repr(self, type_system, expected): result = self._make_one(type_system=type_system) assert result.to_api_repr() == expected + def test_from_api_repr(self): + """GIVEN an api representation of a ForeignTypeInfo object (i.e. resource) + WHEN converted into a ForeignTypeInfo object using from_api_repr() and + displayed as a dict + THEN it will have the same representation a ForeignTypeInfo object created + directly (via _make_one()) and displayed as a dict. + """ + resource = { + "typeSystem": "TYPE_SYSTEM_UNSPECIFIED" + } + + expected = self._make_one( + type_system="TYPE_SYSTEM_UNSPECIFIED" + ) + + klass = self._get_target_class() + result = klass.from_api_repr(resource) + + assert result.to_api_repr() == expected.to_api_repr() + class TestStorageDescriptor: """Tests for the StorageDescriptor class.""" @@ -1316,39 +1336,39 @@ def test_to_api_repr(self): # TODO: needs a from_api_repr() test. -@pytest.fixture -def _make_foreign_type_info(): - return ForeignTypeInfo( - type_system="TODO_fake_type_system", - ) - - -class TestTableSchema: - @staticmethod - def _get_target_class(): - return TableSchema - - def _make_one(self, *args, **kwargs): - return self._get_target_class()(*args, **kwargs) - - def test_ctor_valid_input(self, _make_foreign_type_info): - table_schema = self._make_one( - fields="TODO needs a fields object", - foreign_type_info=_make_foreign_type_info.to_api_repr(), - ) - # Test default constructors - # Create expected TableSchema object - # * use target_class - # * use make_one - # Create result TableSchema object - # compare the two - assert False - - def test_ctor_invalid_input(self): - assert False - - def test_to_api_repr(self): - assert False +# @pytest.fixture +# def _make_foreign_type_info(): +# return ForeignTypeInfo( +# type_system="TODO_fake_type_system", +# ) + + +# class TestTableSchema: +# @staticmethod +# def _get_target_class(): +# return TableSchema + +# def _make_one(self, *args, **kwargs): +# return self._get_target_class()(*args, **kwargs) + +# def test_ctor_valid_input(self, _make_foreign_type_info): +# table_schema = self._make_one( +# fields="TODO needs a fields object", +# foreign_type_info=_make_foreign_type_info.to_api_repr(), +# ) +# # Test default constructors +# # Create expected TableSchema object +# # * use target_class +# # * use make_one +# # Create result TableSchema object +# # compare the two +# assert False + +# def test_ctor_invalid_input(self): +# assert False + +# def test_to_api_repr(self): +# assert False - def test_from_api_repr(self): - assert False +# def test_from_api_repr(self): +# assert False diff --git a/tests/unit/test_table.py b/tests/unit/test_table.py index dafeb9aa0..731686f1f 100644 --- a/tests/unit/test_table.py +++ b/tests/unit/test_table.py @@ -570,6 +570,26 @@ def test_ctor_w_schema(self): self.assertEqual(table.schema, [full_name, age]) + def test_ctor_w_schema_klass(self): + from google.cloud.bigquery.schema import SchemaField + from google.cloud.bigquery.schema import Schema + + + dataset = DatasetReference(self.PROJECT, self.DS_ID) + table_ref = dataset.table(self.TABLE_NAME) + full_name = SchemaField("full_name", "STRING", mode="REQUIRED") + age = SchemaField("age", "INTEGER", mode="REQUIRED") + # ONLY CHANGE IN THE BODY OF THE TEST + schema = Schema(foreign_type_info="EXAMPLE FTF", fields=[full_name, age]) + + table = self._make_one(table_ref, schema=schema) + print(f"DINOSAUR: {schema}\n{dir(schema)}\n{type(schema)}\n{type(table.schema)}") + self.assertEqual(table.schema, [full_name, age]) + # ADDITIONAL CHECK TEST + self.assertEqual(table.schema.foreign_type_info, "EXAMPLE FTF") + + + def test_ctor_string(self): table = self._make_one("some-project.some_dset.some_tbl") self.assertEqual(table.project, "some-project") From 51ff9cb695213cc7e95980213b40229a51f3bb81 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Fri, 22 Nov 2024 13:17:28 +0000 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20po?= =?UTF-8?q?st-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- google/cloud/bigquery/schema.py | 2 +- tests/unit/test_schema.py | 11 ++++------- tests/unit/test_table.py | 7 +++---- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/google/cloud/bigquery/schema.py b/google/cloud/bigquery/schema.py index 93469c57f..99e702386 100644 --- a/google/cloud/bigquery/schema.py +++ b/google/cloud/bigquery/schema.py @@ -687,7 +687,7 @@ def to_api_repr(self) -> dict: A dictionary in the format used by the BigQuery API. """ return copy.deepcopy(self._properties) - + @classmethod def from_api_repr(cls, resource): """Factory: constructs an instance of the class (cls) diff --git a/tests/unit/test_schema.py b/tests/unit/test_schema.py index 4eb1e20d8..11b7f4e73 100644 --- a/tests/unit/test_schema.py +++ b/tests/unit/test_schema.py @@ -1166,13 +1166,9 @@ def test_from_api_repr(self): THEN it will have the same representation a ForeignTypeInfo object created directly (via _make_one()) and displayed as a dict. """ - resource = { - "typeSystem": "TYPE_SYSTEM_UNSPECIFIED" - } + resource = {"typeSystem": "TYPE_SYSTEM_UNSPECIFIED"} - expected = self._make_one( - type_system="TYPE_SYSTEM_UNSPECIFIED" - ) + expected = self._make_one(type_system="TYPE_SYSTEM_UNSPECIFIED") klass = self._get_target_class() result = klass.from_api_repr(resource) @@ -1336,6 +1332,7 @@ def test_to_api_repr(self): # TODO: needs a from_api_repr() test. + # @pytest.fixture # def _make_foreign_type_info(): # return ForeignTypeInfo( @@ -1369,6 +1366,6 @@ def test_to_api_repr(self): # def test_to_api_repr(self): # assert False - + # def test_from_api_repr(self): # assert False diff --git a/tests/unit/test_table.py b/tests/unit/test_table.py index 731686f1f..8400421e8 100644 --- a/tests/unit/test_table.py +++ b/tests/unit/test_table.py @@ -574,7 +574,6 @@ def test_ctor_w_schema_klass(self): from google.cloud.bigquery.schema import SchemaField from google.cloud.bigquery.schema import Schema - dataset = DatasetReference(self.PROJECT, self.DS_ID) table_ref = dataset.table(self.TABLE_NAME) full_name = SchemaField("full_name", "STRING", mode="REQUIRED") @@ -583,13 +582,13 @@ def test_ctor_w_schema_klass(self): schema = Schema(foreign_type_info="EXAMPLE FTF", fields=[full_name, age]) table = self._make_one(table_ref, schema=schema) - print(f"DINOSAUR: {schema}\n{dir(schema)}\n{type(schema)}\n{type(table.schema)}") + print( + f"DINOSAUR: {schema}\n{dir(schema)}\n{type(schema)}\n{type(table.schema)}" + ) self.assertEqual(table.schema, [full_name, age]) # ADDITIONAL CHECK TEST self.assertEqual(table.schema.foreign_type_info, "EXAMPLE FTF") - - def test_ctor_string(self): table = self._make_one("some-project.some_dset.some_tbl") self.assertEqual(table.project, "some-project") From e3f25eba1ab439d7a631a0705b3fa482de862f67 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Fri, 22 Nov 2024 13:18:32 +0000 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20po?= =?UTF-8?q?st-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- google/cloud/bigquery/schema.py | 2 +- tests/unit/test_schema.py | 11 ++++------- tests/unit/test_table.py | 7 +++---- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/google/cloud/bigquery/schema.py b/google/cloud/bigquery/schema.py index 93469c57f..99e702386 100644 --- a/google/cloud/bigquery/schema.py +++ b/google/cloud/bigquery/schema.py @@ -687,7 +687,7 @@ def to_api_repr(self) -> dict: A dictionary in the format used by the BigQuery API. """ return copy.deepcopy(self._properties) - + @classmethod def from_api_repr(cls, resource): """Factory: constructs an instance of the class (cls) diff --git a/tests/unit/test_schema.py b/tests/unit/test_schema.py index 4eb1e20d8..11b7f4e73 100644 --- a/tests/unit/test_schema.py +++ b/tests/unit/test_schema.py @@ -1166,13 +1166,9 @@ def test_from_api_repr(self): THEN it will have the same representation a ForeignTypeInfo object created directly (via _make_one()) and displayed as a dict. """ - resource = { - "typeSystem": "TYPE_SYSTEM_UNSPECIFIED" - } + resource = {"typeSystem": "TYPE_SYSTEM_UNSPECIFIED"} - expected = self._make_one( - type_system="TYPE_SYSTEM_UNSPECIFIED" - ) + expected = self._make_one(type_system="TYPE_SYSTEM_UNSPECIFIED") klass = self._get_target_class() result = klass.from_api_repr(resource) @@ -1336,6 +1332,7 @@ def test_to_api_repr(self): # TODO: needs a from_api_repr() test. + # @pytest.fixture # def _make_foreign_type_info(): # return ForeignTypeInfo( @@ -1369,6 +1366,6 @@ def test_to_api_repr(self): # def test_to_api_repr(self): # assert False - + # def test_from_api_repr(self): # assert False diff --git a/tests/unit/test_table.py b/tests/unit/test_table.py index 731686f1f..8400421e8 100644 --- a/tests/unit/test_table.py +++ b/tests/unit/test_table.py @@ -574,7 +574,6 @@ def test_ctor_w_schema_klass(self): from google.cloud.bigquery.schema import SchemaField from google.cloud.bigquery.schema import Schema - dataset = DatasetReference(self.PROJECT, self.DS_ID) table_ref = dataset.table(self.TABLE_NAME) full_name = SchemaField("full_name", "STRING", mode="REQUIRED") @@ -583,13 +582,13 @@ def test_ctor_w_schema_klass(self): schema = Schema(foreign_type_info="EXAMPLE FTF", fields=[full_name, age]) table = self._make_one(table_ref, schema=schema) - print(f"DINOSAUR: {schema}\n{dir(schema)}\n{type(schema)}\n{type(table.schema)}") + print( + f"DINOSAUR: {schema}\n{dir(schema)}\n{type(schema)}\n{type(table.schema)}" + ) self.assertEqual(table.schema, [full_name, age]) # ADDITIONAL CHECK TEST self.assertEqual(table.schema.foreign_type_info, "EXAMPLE FTF") - - def test_ctor_string(self): table = self._make_one("some-project.some_dset.some_tbl") self.assertEqual(table.project, "some-project") From 6830e408c33f0354b6a8b42a632f3cddcce4b16b Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Fri, 22 Nov 2024 13:33:03 +0000 Subject: [PATCH 5/5] fixes merge conflict --- google/cloud/bigquery/schema.py | 56 --------------------------------- tests/unit/test_schema.py | 39 ----------------------- tests/unit/test_table.py | 19 ----------- 3 files changed, 114 deletions(-) diff --git a/google/cloud/bigquery/schema.py b/google/cloud/bigquery/schema.py index 99e702386..f9ac584a1 100644 --- a/google/cloud/bigquery/schema.py +++ b/google/cloud/bigquery/schema.py @@ -24,7 +24,6 @@ from google.cloud.bigquery import standard_sql from google.cloud.bigquery._helpers import ( _isinstance_or_raise, - _from_api_repr, _get_sub_prop, ) from google.cloud.bigquery.enums import StandardSqlTypeNames @@ -599,61 +598,6 @@ def to_api_repr(self) -> dict: return answer -# class TableSchema: -# """Schema of a table - -# Args: -# fields (Optional[list]): Describes the fields in a table. -# foreignTypeInfo (Optional[str]): Specifies metadata of the foreign data type -# definition in field schema. -# """ - -# def __init__( -# self, fields: Optional[list] = None, foreign_type_info: Optional[str] = None -# ): -# self._properties = {} -# self.fields = fields -# self.foreign_type_info = foreign_type_info - -# @property -# def fields(self) -> Any: -# """Describes the fields in a table.""" - -# return self._properties.get("fields") - -# @fields.setter -# def fields(self, value: list, dtype: str) -> str: -# value = _isinstance_or_raise(value, list, none_allowed=True) -# self._properties["fields"] = value - -# @property -# def foreign_type_info(self) -> Any: -# """Optional. Specifies metadata of the foreign data type definition in -# field schema (TableFieldSchema.foreign_type_definition).""" - -# return self._properties.get("foreignTypeInfo") - -# @foreign_type_info.setter -# def foreign_type_info(self, value: str, dtype: str) -> str: -# if not isinstance(value, str): -# raise ValueError( -# f"Pass {value} as a '{repr(dtype)}'." f"Got {type(value)}." -# ) -# self._properties["foreignTypeInfo"] = value - -# def to_api_repr(self) -> dict: -# """Build an API representation of this object. - -# Returns: -# Dict[str, Any]: -# A dictionary in the format used by the BigQuery API. -# """ -# return copy.deepcopy(self._properties) - -# def from_api_repr(self, resource): -# return _from_api_repr(self, resource) - - class ForeignTypeInfo: """Metadata about the foreign data type definition such as the system in which the type is defined. diff --git a/tests/unit/test_schema.py b/tests/unit/test_schema.py index 11b7f4e73..b7ff87b9a 100644 --- a/tests/unit/test_schema.py +++ b/tests/unit/test_schema.py @@ -19,7 +19,6 @@ ForeignTypeInfo, StorageDescriptor, SerDeInfo, - # TODO: delete this line...TableSchema, ) import unittest @@ -1331,41 +1330,3 @@ def test_to_api_repr(self): assert serde_info.to_api_repr() == expected_repr # TODO: needs a from_api_repr() test. - - -# @pytest.fixture -# def _make_foreign_type_info(): -# return ForeignTypeInfo( -# type_system="TODO_fake_type_system", -# ) - - -# class TestTableSchema: -# @staticmethod -# def _get_target_class(): -# return TableSchema - -# def _make_one(self, *args, **kwargs): -# return self._get_target_class()(*args, **kwargs) - -# def test_ctor_valid_input(self, _make_foreign_type_info): -# table_schema = self._make_one( -# fields="TODO needs a fields object", -# foreign_type_info=_make_foreign_type_info.to_api_repr(), -# ) -# # Test default constructors -# # Create expected TableSchema object -# # * use target_class -# # * use make_one -# # Create result TableSchema object -# # compare the two -# assert False - -# def test_ctor_invalid_input(self): -# assert False - -# def test_to_api_repr(self): -# assert False - -# def test_from_api_repr(self): -# assert False diff --git a/tests/unit/test_table.py b/tests/unit/test_table.py index 8400421e8..dafeb9aa0 100644 --- a/tests/unit/test_table.py +++ b/tests/unit/test_table.py @@ -570,25 +570,6 @@ def test_ctor_w_schema(self): self.assertEqual(table.schema, [full_name, age]) - def test_ctor_w_schema_klass(self): - from google.cloud.bigquery.schema import SchemaField - from google.cloud.bigquery.schema import Schema - - dataset = DatasetReference(self.PROJECT, self.DS_ID) - table_ref = dataset.table(self.TABLE_NAME) - full_name = SchemaField("full_name", "STRING", mode="REQUIRED") - age = SchemaField("age", "INTEGER", mode="REQUIRED") - # ONLY CHANGE IN THE BODY OF THE TEST - schema = Schema(foreign_type_info="EXAMPLE FTF", fields=[full_name, age]) - - table = self._make_one(table_ref, schema=schema) - print( - f"DINOSAUR: {schema}\n{dir(schema)}\n{type(schema)}\n{type(table.schema)}" - ) - self.assertEqual(table.schema, [full_name, age]) - # ADDITIONAL CHECK TEST - self.assertEqual(table.schema.foreign_type_info, "EXAMPLE FTF") - def test_ctor_string(self): table = self._make_one("some-project.some_dset.some_tbl") self.assertEqual(table.project, "some-project")