@@ -269,7 +269,7 @@ def __get_int(api_repr, name):
269269 return v
270270
271271 @classmethod
272- def from_api_repr (cls , api_repr : dict ) -> "SchemaField" :
272+ def from_api_repr (cls , api_repr : Mapping [ str , Any ] ) -> "SchemaField" :
273273 """Return a ``SchemaField`` object deserialized from a dictionary.
274274
275275 Args:
@@ -942,67 +942,118 @@ def from_api_repr(cls, resource: dict) -> SerDeInfo:
942942
943943
944944class Schema (collections .UserList ):
945- # TODO docstrings and type hints
946- def __init__ (self , fields = None , foreign_type_info = None ):
947- self ._properties = {}
945+ """
946+ Represents a BigQuery schema, defining the structure and types of data.
947+
948+ This class manages a list of schema fields and provides methods for
949+ serialization and deserialization with the BigQuery API. It extends the
950+ `collections.UserList` class to allow for list-like behavior.
951+
952+ Args:
953+ fields (Optional[List[Any]], optional): A list of SchemaField objects representing the fields
954+ in the schema. Defaults to None, which creates an empty schema.
955+ foreign_type_info (Optional[str], optional): Optional type information relevant for foreign
956+ systems. Defaults to None.
957+ """
958+
959+ def __init__ (
960+ self ,
961+ fields : Optional [List [Any ]] = None ,
962+ foreign_type_info : Optional [str ] = None ,
963+ ):
964+ self ._properties : Dict [str , Any ] = {}
948965 self ._fields = [] if fields is None else list (fields ) # Internal List
949966 self .foreign_type_info = foreign_type_info
950967
951968 @property
952- def foreign_type_info (self ) -> Any :
953- """TODO: docstring"""
969+ def foreign_type_info (self ) -> Optional [str ]:
954970 return self ._properties .get ("foreignTypeInfo" )
955971
956972 @foreign_type_info .setter
957- def foreign_type_info (self , value : str ) -> None :
973+ def foreign_type_info (self , value : Optional [str ]) -> None :
974+ """
975+ Sets the foreign type information for this schema.
976+
977+ Args:
978+ value (Optional[str]): The foreign type information, can be set to None.
979+ """
958980 value = _isinstance_or_raise (value , str , none_allowed = True )
959981 self ._properties ["foreignTypeInfo" ] = value
960982
961983 @property
962- def _fields (self ) -> Any :
963- """TODO: docstring"""
984+ def _fields (self ) -> Optional [List [Any ]]:
964985 return self ._properties .get ("fields" )
965986
966987 @_fields .setter
967- def _fields (self , value : list ) -> None :
988+ def _fields (self , value : Optional [List [Any ]]) -> None :
989+ """
990+ Sets the internal list of field definitions.
991+
992+ NOTE: In the API representation the 'fields' key points to a sequence of schema fields.
993+ To maintain a similarity in names, the 'Schema._fields' attribute points to the
994+ '_properties["fields"]' key. Schema class is superclassed by UserList, which requires the
995+ use of a '.data' attribute. The decision was made to have both of these attributes point to
996+ the same key "fields" in the '_properties' dictionary. Thus '.data' is an alias
997+ for '_fields'.
998+
999+ Args:
1000+ value (Optional[List[Any]]): A list of schema fields, can be set to None.
1001+ """
9681002 value = _isinstance_or_raise (value , list , none_allowed = True )
9691003 value = _build_schema_resource (value )
9701004 self ._properties ["fields" ] = value
9711005
9721006 @property
973- def data (self ):
1007+ def data (self ) -> Any :
9741008 return self ._properties .get ("fields" )
9751009
9761010 @data .setter
977- def data (self , value : list ):
978- # for simplicity, no validation in this proof of concept
1011+ def data (self , value ) -> None :
1012+ """
1013+ Sets the list of schema fields.
1014+
1015+ NOTE: In the API representation the 'fields' key points to a sequence of schema fields.
1016+ To maintain a similarity in names, the 'Schema._fields' attribute points to the
1017+ '_properties["fields"]' key. Schema class is superclassed by UserList, which requires the
1018+ use of a '.data' attribute. The decision was made to have both of these attributes point to
1019+ the same key "fields" in the '_properties' dictionary. Thus '.data' is an alias
1020+ for '_fields'.
1021+
1022+ Args:
1023+ value (Optional[List[Any]]): A list of schema fields, can be set to None.
1024+ """
1025+
9791026 value = _isinstance_or_raise (value , list , none_allowed = True )
9801027 value = _build_schema_resource (value )
9811028 self ._properties ["fields" ] = value
9821029
983- def __str__ (self ):
1030+ def __str__ (self ) -> str :
9841031 return f"Schema({ self ._fields } , { self .foreign_type_info } )"
9851032
986- def __repr__ (self ):
1033+ def __repr__ (self ) -> str :
9871034 return f"Schema({ self ._fields !r} , { self .foreign_type_info !r} )"
9881035
989- def to_api_repr (self ) -> dict :
1036+ def to_api_repr (self ) -> Dict [ str , Any ] :
9901037 """Build an API representation of this object.
9911038
9921039 Returns:
9931040 Dict[str, Any]:
9941041 A dictionary in the format used by the BigQuery API.
1042+ If the schema contains SchemaField objects, the fields are
1043+ also converted to their API representations.
9951044 """
9961045 # If this is a RECORD type, then sub-fields are also included,
9971046 # add this to the serialized representation.
9981047 answer = self ._properties .copy ()
1048+ if self ._fields is None :
1049+ return answer
9991050 schemafields = any ([isinstance (f , SchemaField ) for f in self ._fields ])
10001051 if schemafields :
10011052 answer ["fields" ] = [f .to_api_repr () for f in self ._fields ]
10021053 return answer
10031054
10041055 @classmethod
1005- def from_api_repr (cls , resource : dict ) -> Schema :
1056+ def from_api_repr (cls , resource : Dict [ str , Any ] ) -> " Schema" :
10061057 """Factory: constructs an instance of the class (cls)
10071058 given its API representation.
10081059
@@ -1013,6 +1064,6 @@ def from_api_repr(cls, resource: dict) -> Schema:
10131064 Returns:
10141065 An instance of the class initialized with data from 'resource'.
10151066 """
1016- config = cls ("" )
1067+ config = cls ([] )
10171068 config ._properties = copy .copy (resource )
10181069 return config
0 commit comments