You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by dw...@apache.org on 2022/05/17 20:18:42 UTC
[iceberg] branch master updated: Change types into dataclasses (#4767)
This is an automated email from the ASF dual-hosted git repository.
dweeks pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iceberg.git
The following commit(s) were added to refs/heads/master by this push:
new 97f1771c2 Change types into dataclasses (#4767)
97f1771c2 is described below
commit 97f1771c2ac764f43e263c422c720959ca8eee9b
Author: Fokko Driesprong <fo...@tabular.io>
AuthorDate: Tue May 17 22:18:37 2022 +0200
Change types into dataclasses (#4767)
* Change types into dataclasses
Proposal to change the types into dataclasses.
This has several improvments:
- We can use the dataclasss field(repr=True) to include the fields in the representation, instead of building our own strings
- We can assign the types in the post_init when they are dynamic (List, Maps, Structs etc) , or just override them when they are static (Primitives)
- We don't have to implement any eq methods because they come for free
- The types are frozen, which is kind of nice since we re-use them
- The code is much more consise
- We can assign the min/max of the int/long/float as Final as of 3.8: https://peps.python.org/pep-0591/
My inspiration was the comment by Kyle:
https://github.com/apache/iceberg/pull/4742#discussion_r869494393
This would entail implementing eq, but why not use the generated one since we're comparing all the attributes :)
Would love to get you input
* Remove explicit repr and eq
* Use @cached_property to cache the string
Add missing words to spelling
* Add additional guard for initializing StructType using kwargs
* Replace type with field_type
---
python/setup.cfg | 1 +
python/spellcheck-dictionary.txt | 6 +-
python/src/iceberg/schema.py | 14 +-
python/src/iceberg/types.py | 390 ++++++++++++++++++++-------------------
python/tests/test_schema.py | 6 +-
python/tests/test_types.py | 10 +-
6 files changed, 222 insertions(+), 205 deletions(-)
diff --git a/python/setup.cfg b/python/setup.cfg
index 559751011..18f4d8245 100644
--- a/python/setup.cfg
+++ b/python/setup.cfg
@@ -45,6 +45,7 @@ python_requires = >=3.7
install_requires =
mmh3
singledispatch
+ cached-property; python_version <= '3.7'
[options.extras_require]
arrow =
pyarrow
diff --git a/python/spellcheck-dictionary.txt b/python/spellcheck-dictionary.txt
index 2476d5afd..1100dd703 100644
--- a/python/spellcheck-dictionary.txt
+++ b/python/spellcheck-dictionary.txt
@@ -26,10 +26,13 @@ FileInfo
filesystem
fs
func
+IcebergType
io
NativeFile
+NestedField
nullability
pragma
+PrimitiveType
pyarrow
repr
schemas
@@ -42,4 +45,5 @@ StructType
Timestamptz
Timestamptzs
unscaled
-URI
\ No newline at end of file
+URI
+
diff --git a/python/src/iceberg/schema.py b/python/src/iceberg/schema.py
index 9b9650448..59b9cc835 100644
--- a/python/src/iceberg/schema.py
+++ b/python/src/iceberg/schema.py
@@ -152,7 +152,7 @@ class Schema:
NestedField: The type of the matched NestedField
"""
field = self.find_field(name_or_id=name_or_id, case_sensitive=case_sensitive)
- return field.type # type: ignore
+ return field.field_type
def find_column_name(self, column_id: int) -> str:
"""Find a column name given a column ID
@@ -318,7 +318,7 @@ def _(obj: StructType, visitor: SchemaVisitor[T]) -> T:
for field in obj.fields:
visitor.before_field(field)
- result = visit(field.type, visitor)
+ result = visit(field.field_type, visitor)
visitor.after_field(field)
results.append(visitor.field(field, result))
@@ -330,7 +330,7 @@ def _(obj: ListType, visitor: SchemaVisitor[T]) -> T:
"""Visit a ListType with a concrete SchemaVisitor"""
visitor.before_list_element(obj.element)
- result = visit(obj.element.type, visitor)
+ result = visit(obj.element.field_type, visitor)
visitor.after_list_element(obj.element)
return visitor.list(obj, result)
@@ -340,11 +340,11 @@ def _(obj: ListType, visitor: SchemaVisitor[T]) -> T:
def _(obj: MapType, visitor: SchemaVisitor[T]) -> T:
"""Visit a MapType with a concrete SchemaVisitor"""
visitor.before_map_key(obj.key)
- key_result = visit(obj.key.type, visitor)
+ key_result = visit(obj.key.field_type, visitor)
visitor.after_map_key(obj.key)
visitor.before_map_value(obj.value)
- value_result = visit(obj.value.type, visitor)
+ value_result = visit(obj.value.field_type, visitor)
visitor.after_list_element(obj.value)
return visitor.map(obj, key_result, value_result)
@@ -412,12 +412,12 @@ class _IndexByName(SchemaVisitor[Dict[str, int]]):
def before_list_element(self, element: NestedField) -> None:
"""Short field names omit element when the element is a StructType"""
- if not isinstance(element.type, StructType):
+ if not isinstance(element.field_type, StructType):
self._short_field_names.append(element.name)
self._field_names.append(element.name)
def after_list_element(self, element: NestedField) -> None:
- if not isinstance(element.type, StructType):
+ if not isinstance(element.field_type, StructType):
self._short_field_names.pop()
self._field_names.pop()
diff --git a/python/src/iceberg/types.py b/python/src/iceberg/types.py
index 3173c4aca..5318e4f8a 100644
--- a/python/src/iceberg/types.py
+++ b/python/src/iceberg/types.py
@@ -29,8 +29,15 @@ Example:
Notes:
- https://iceberg.apache.org/#spec/#primitive-types
"""
+import sys
+from dataclasses import dataclass, field
+from typing import ClassVar, Dict, List, Optional, Tuple
-from typing import Dict, Optional, Tuple
+if sys.version_info >= (3, 8):
+ from functools import cached_property
+else:
+ # In the case of <= Python 3.7
+ from cached_property import cached_property
class Singleton:
@@ -42,57 +49,64 @@ class Singleton:
return cls._instance
+@dataclass(frozen=True)
class IcebergType:
- """Base type for all Iceberg Types"""
+ """Base type for all Iceberg Types
- _initialized = False
-
- def __init__(self, type_string: str, repr_string: str):
- self._type_string = type_string
- self._repr_string = repr_string
- self._initialized = True
+ Example:
+ >>> str(IcebergType())
+ 'IcebergType()'
+ >>> repr(IcebergType())
+ 'IcebergType()'
+ """
- def __repr__(self):
- return self._repr_string
+ @property
+ def string_type(self) -> str:
+ return self.__repr__()
- def __str__(self):
- return self._type_string
+ def __str__(self) -> str:
+ return self.string_type
@property
def is_primitive(self) -> bool:
return isinstance(self, PrimitiveType)
+@dataclass(frozen=True, eq=True)
class PrimitiveType(IcebergType):
- """Base class for all Iceberg Primitive Types"""
+ """Base class for all Iceberg Primitive Types
+
+ Example:
+ >>> str(PrimitiveType())
+ 'PrimitiveType()'
+ """
+@dataclass(frozen=True)
class FixedType(PrimitiveType):
"""A fixed data type in Iceberg.
Example:
>>> FixedType(8)
FixedType(length=8)
- >>> FixedType(8)==FixedType(8)
+ >>> FixedType(8) == FixedType(8)
True
"""
- _instances: Dict[int, "FixedType"] = {}
+ length: int = field()
+
+ _instances: ClassVar[Dict[int, "FixedType"]] = {}
def __new__(cls, length: int):
cls._instances[length] = cls._instances.get(length) or object.__new__(cls)
return cls._instances[length]
- def __init__(self, length: int):
- if not self._initialized:
- super().__init__(f"fixed[{length}]", f"FixedType(length={length})")
- self._length = length
-
@property
- def length(self) -> int:
- return self._length
+ def string_type(self) -> str:
+ return f"fixed[{self.length}]"
+@dataclass(frozen=True, eq=True)
class DecimalType(PrimitiveType):
"""A fixed data type in Iceberg.
@@ -103,38 +117,44 @@ class DecimalType(PrimitiveType):
True
"""
- _instances: Dict[Tuple[int, int], "DecimalType"] = {}
+ precision: int = field()
+ scale: int = field()
+
+ _instances: ClassVar[Dict[Tuple[int, int], "DecimalType"]] = {}
def __new__(cls, precision: int, scale: int):
key = (precision, scale)
cls._instances[key] = cls._instances.get(key) or object.__new__(cls)
return cls._instances[key]
- def __init__(self, precision: int, scale: int):
- if not self._initialized:
- super().__init__(
- f"decimal({precision}, {scale})",
- f"DecimalType(precision={precision}, scale={scale})",
- )
- self._precision = precision
- self._scale = scale
-
- @property
- def precision(self) -> int:
- return self._precision
-
@property
- def scale(self) -> int:
- return self._scale
+ def string_type(self) -> str:
+ return f"decimal({self.precision}, {self.scale})"
+@dataclass(frozen=True)
class NestedField(IcebergType):
"""Represents a field of a struct, a map key, a map value, or a list element.
This is where field IDs, names, docs, and nullability are tracked.
+
+ Example:
+ >>> str(NestedField(
+ ... field_id=1,
+ ... name='foo',
+ ... field_type=FixedType(22),
+ ... is_optional=False,
+ ... ))
+ '1: foo: required fixed[22]'
"""
- _instances: Dict[Tuple[bool, int, str, IcebergType, Optional[str]], "NestedField"] = {}
+ field_id: int = field()
+ name: str = field()
+ field_type: IcebergType = field()
+ is_optional: bool = field(default=True)
+ doc: Optional[str] = field(default=None, repr=False)
+
+ _instances: ClassVar[Dict[Tuple[bool, int, str, IcebergType, Optional[str]], "NestedField"]] = {}
def __new__(
cls,
@@ -148,56 +168,20 @@ class NestedField(IcebergType):
cls._instances[key] = cls._instances.get(key) or object.__new__(cls)
return cls._instances[key]
- def __init__(
- self,
- field_id: int,
- name: str,
- field_type: IcebergType,
- is_optional: bool = True,
- doc: Optional[str] = None,
- ):
- if not self._initialized:
- docString = "" if doc is None else f", doc={repr(doc)}"
- super().__init__(
- (
- f"{field_id}: {name}: {'optional' if is_optional else 'required'} {field_type}" ""
- if doc is None
- else f" ({doc})"
- ),
- f"NestedField(field_id={field_id}, name={repr(name)}, field_type={repr(field_type)}, is_optional={is_optional}"
- f"{docString})",
- )
- self._is_optional = is_optional
- self._id = field_id
- self._name = name
- self._type = field_type
- self._doc = doc
-
- @property
- def is_optional(self) -> bool:
- return self._is_optional
-
@property
def is_required(self) -> bool:
- return not self._is_optional
-
- @property
- def field_id(self) -> int:
- return self._id
-
- @property
- def name(self) -> str:
- return self._name
-
- @property
- def doc(self) -> Optional[str]:
- return self._doc
+ return not self.is_optional
@property
- def type(self) -> IcebergType:
- return self._type
+ def string_type(self) -> str:
+ return (
+ f"{self.field_id}: {self.name}: {'optional' if self.is_optional else 'required'} {self.field_type}"
+ if self.doc is None
+ else f" ({self.doc})"
+ )
+@dataclass(frozen=True, init=False)
class StructType(IcebergType):
"""A struct type in Iceberg
@@ -209,25 +193,27 @@ class StructType(IcebergType):
'struct<1: required_field: optional string, 2: optional_field: optional int>'
"""
- _instances: Dict[Tuple[NestedField, ...], "StructType"] = {}
+ fields: List[NestedField] = field()
+
+ _instances: ClassVar[Dict[Tuple[NestedField, ...], "StructType"]] = {}
- def __new__(cls, *fields: NestedField):
+ def __new__(cls, *fields: NestedField, **kwargs):
+ if not fields and "fields" in kwargs:
+ fields = kwargs["fields"]
cls._instances[fields] = cls._instances.get(fields) or object.__new__(cls)
return cls._instances[fields]
- def __init__(self, *fields: NestedField):
- if not self._initialized:
- super().__init__(
- f"struct<{', '.join(map(str, fields))}>",
- f"StructType{repr(fields)}",
- )
- self._fields = fields
+ def __init__(self, *fields: NestedField, **kwargs):
+ if not fields and "fields" in kwargs:
+ fields = kwargs["fields"]
+ object.__setattr__(self, "fields", fields)
- @property
- def fields(self) -> Tuple[NestedField, ...]:
- return self._fields
+ @cached_property
+ def string_type(self) -> str:
+ return f"struct<{', '.join(map(str, self.fields))}>"
+@dataclass(frozen=True)
class ListType(IcebergType):
"""A list type in Iceberg
@@ -236,7 +222,12 @@ class ListType(IcebergType):
ListType(element_id=3, element_type=StringType(), element_is_optional=True)
"""
- _instances: Dict[Tuple[bool, int, IcebergType], "ListType"] = {}
+ element_id: int = field()
+ element_type: IcebergType = field()
+ element_is_optional: bool = field(default=True)
+ element: NestedField = field(init=False, repr=False)
+
+ _instances: ClassVar[Dict[Tuple[bool, int, IcebergType], "ListType"]] = {}
def __new__(
cls,
@@ -248,30 +239,24 @@ class ListType(IcebergType):
cls._instances[key] = cls._instances.get(key) or object.__new__(cls)
return cls._instances[key]
- def __init__(
- self,
- element_id: int,
- element_type: IcebergType,
- element_is_optional: bool = True,
- ):
- if not self._initialized:
- super().__init__(
- f"list<{element_type}>",
- f"ListType(element_id={element_id}, element_type={repr(element_type)}, "
- f"element_is_optional={element_is_optional})",
- )
- self._element_field = NestedField(
+ def __post_init__(self):
+ object.__setattr__(
+ self,
+ "element",
+ NestedField(
name="element",
- is_optional=element_is_optional,
- field_id=element_id,
- field_type=element_type,
- )
+ is_optional=self.element_is_optional,
+ field_id=self.element_id,
+ field_type=self.element_type,
+ ),
+ )
@property
- def element(self) -> NestedField:
- return self._element_field
+ def string_type(self) -> str:
+ return f"list<{self.element_type}>"
+@dataclass(frozen=True)
class MapType(IcebergType):
"""A map type in Iceberg
@@ -280,7 +265,16 @@ class MapType(IcebergType):
MapType(key_id=1, key_type=StringType(), value_id=2, value_type=IntegerType(), value_is_optional=True)
"""
- _instances: Dict[Tuple[int, IcebergType, int, IcebergType, bool], "MapType"] = {}
+ key_id: int = field()
+ key_type: IcebergType = field()
+ value_id: int = field()
+ value_type: IcebergType = field()
+ value_is_optional: bool = field(default=True)
+ key: NestedField = field(init=False, repr=False)
+ value: NestedField = field(init=False, repr=False)
+
+ # _type_string_def = lambda self: f"map<{self.key_type}, {self.value_type}>"
+ _instances: ClassVar[Dict[Tuple[int, IcebergType, int, IcebergType, bool], "MapType"]] = {}
def __new__(
cls,
@@ -294,37 +288,23 @@ class MapType(IcebergType):
cls._instances[impl_key] = cls._instances.get(impl_key) or object.__new__(cls)
return cls._instances[impl_key]
- def __init__(
- self,
- key_id: int,
- key_type: IcebergType,
- value_id: int,
- value_type: IcebergType,
- value_is_optional: bool = True,
- ):
- if not self._initialized:
- super().__init__(
- f"map<{key_type}, {value_type}>",
- f"MapType(key_id={key_id}, key_type={repr(key_type)}, value_id={value_id}, value_type={repr(value_type)}, "
- f"value_is_optional={value_is_optional})",
- )
- self._key_field = NestedField(name="key", field_id=key_id, field_type=key_type, is_optional=False)
- self._value_field = NestedField(
+ def __post_init__(self):
+ object.__setattr__(
+ self, "key", NestedField(name="key", field_id=self.key_id, field_type=self.key_type, is_optional=False)
+ )
+ object.__setattr__(
+ self,
+ "value",
+ NestedField(
name="value",
- field_id=value_id,
- field_type=value_type,
- is_optional=value_is_optional,
- )
-
- @property
- def key(self) -> NestedField:
- return self._key_field
-
- @property
- def value(self) -> NestedField:
- return self._value_field
+ field_id=self.value_id,
+ field_type=self.value_type,
+ is_optional=self.value_is_optional,
+ ),
+ )
+@dataclass(frozen=True)
class BooleanType(PrimitiveType, Singleton):
"""A boolean data type in Iceberg can be represented using an instance of this class.
@@ -332,13 +312,16 @@ class BooleanType(PrimitiveType, Singleton):
>>> column_foo = BooleanType()
>>> isinstance(column_foo, BooleanType)
True
+ >>> column_foo
+ BooleanType()
"""
- def __init__(self):
- if not self._initialized:
- super().__init__("boolean", "BooleanType()")
+ @property
+ def string_type(self) -> str:
+ return "boolean"
+@dataclass(frozen=True)
class IntegerType(PrimitiveType, Singleton):
"""An Integer data type in Iceberg can be represented using an instance of this class. Integers in Iceberg are
32-bit signed and can be promoted to Longs.
@@ -355,15 +338,15 @@ class IntegerType(PrimitiveType, Singleton):
in Java (returns `-2147483648`)
"""
- max: int = 2147483647
+ max: ClassVar[int] = 2147483647
+ min: ClassVar[int] = -2147483648
- min: int = -2147483648
-
- def __init__(self):
- if not self._initialized:
- super().__init__("int", "IntegerType()")
+ @property
+ def string_type(self) -> str:
+ return "int"
+@dataclass(frozen=True)
class LongType(PrimitiveType, Singleton):
"""A Long data type in Iceberg can be represented using an instance of this class. Longs in Iceberg are
64-bit signed integers.
@@ -372,6 +355,10 @@ class LongType(PrimitiveType, Singleton):
>>> column_foo = LongType()
>>> isinstance(column_foo, LongType)
True
+ >>> column_foo
+ LongType()
+ >>> str(column_foo)
+ 'long'
Attributes:
max (int): The maximum allowed value for Longs, inherited from the canonical Iceberg implementation
@@ -380,15 +367,15 @@ class LongType(PrimitiveType, Singleton):
in Java (returns `-9223372036854775808`)
"""
- max: int = 9223372036854775807
+ max: ClassVar[int] = 9223372036854775807
+ min: ClassVar[int] = -9223372036854775808
- min: int = -9223372036854775808
-
- def __init__(self):
- if not self._initialized:
- super().__init__("long", "LongType()")
+ @property
+ def string_type(self) -> str:
+ return "long"
+@dataclass(frozen=True)
class FloatType(PrimitiveType, Singleton):
"""A Float data type in Iceberg can be represented using an instance of this class. Floats in Iceberg are
32-bit IEEE 754 floating points and can be promoted to Doubles.
@@ -397,6 +384,8 @@ class FloatType(PrimitiveType, Singleton):
>>> column_foo = FloatType()
>>> isinstance(column_foo, FloatType)
True
+ >>> column_foo
+ FloatType()
Attributes:
max (float): The maximum allowed value for Floats, inherited from the canonical Iceberg implementation
@@ -405,15 +394,15 @@ class FloatType(PrimitiveType, Singleton):
in Java (returns `-3.4028235e38`)
"""
- max: float = 3.4028235e38
+ max: ClassVar[float] = 3.4028235e38
+ min: ClassVar[float] = -3.4028235e38
- min: float = -3.4028235e38
-
- def __init__(self):
- if not self._initialized:
- super().__init__("float", "FloatType()")
+ @property
+ def string_type(self) -> str:
+ return "float"
+@dataclass(frozen=True)
class DoubleType(PrimitiveType, Singleton):
"""A Double data type in Iceberg can be represented using an instance of this class. Doubles in Iceberg are
64-bit IEEE 754 floating points.
@@ -422,13 +411,16 @@ class DoubleType(PrimitiveType, Singleton):
>>> column_foo = DoubleType()
>>> isinstance(column_foo, DoubleType)
True
+ >>> column_foo
+ DoubleType()
"""
- def __init__(self):
- if not self._initialized:
- super().__init__("double", "DoubleType()")
+ @property
+ def string_type(self) -> str:
+ return "double"
+@dataclass(frozen=True)
class DateType(PrimitiveType, Singleton):
"""A Date data type in Iceberg can be represented using an instance of this class. Dates in Iceberg are
calendar dates without a timezone or time.
@@ -437,13 +429,16 @@ class DateType(PrimitiveType, Singleton):
>>> column_foo = DateType()
>>> isinstance(column_foo, DateType)
True
+ >>> column_foo
+ DateType()
"""
- def __init__(self):
- if not self._initialized:
- super().__init__("date", "DateType()")
+ @property
+ def string_type(self) -> str:
+ return "date"
+@dataclass(frozen=True)
class TimeType(PrimitiveType, Singleton):
"""A Time data type in Iceberg can be represented using an instance of this class. Times in Iceberg
have microsecond precision and are a time of day without a date or timezone.
@@ -452,13 +447,16 @@ class TimeType(PrimitiveType, Singleton):
>>> column_foo = TimeType()
>>> isinstance(column_foo, TimeType)
True
+ >>> column_foo
+ TimeType()
"""
- def __init__(self):
- if not self._initialized:
- super().__init__("time", "TimeType()")
+ @property
+ def string_type(self) -> str:
+ return "time"
+@dataclass(frozen=True)
class TimestampType(PrimitiveType, Singleton):
"""A Timestamp data type in Iceberg can be represented using an instance of this class. Timestamps in
Iceberg have microsecond precision and include a date and a time of day without a timezone.
@@ -467,13 +465,16 @@ class TimestampType(PrimitiveType, Singleton):
>>> column_foo = TimestampType()
>>> isinstance(column_foo, TimestampType)
True
+ >>> column_foo
+ TimestampType()
"""
- def __init__(self):
- if not self._initialized:
- super().__init__("timestamp", "TimestampType()")
+ @property
+ def string_type(self) -> str:
+ return "timestamp"
+@dataclass(frozen=True)
class TimestamptzType(PrimitiveType, Singleton):
"""A Timestamptz data type in Iceberg can be represented using an instance of this class. Timestamptzs in
Iceberg are stored as UTC and include a date and a time of day with a timezone.
@@ -482,13 +483,16 @@ class TimestamptzType(PrimitiveType, Singleton):
>>> column_foo = TimestamptzType()
>>> isinstance(column_foo, TimestamptzType)
True
+ >>> column_foo
+ TimestamptzType()
"""
- def __init__(self):
- if not self._initialized:
- super().__init__("timestamptz", "TimestamptzType()")
+ @property
+ def string_type(self) -> str:
+ return "timestamptz"
+@dataclass(frozen=True)
class StringType(PrimitiveType, Singleton):
"""A String data type in Iceberg can be represented using an instance of this class. Strings in
Iceberg are arbitrary-length character sequences and are encoded with UTF-8.
@@ -497,13 +501,16 @@ class StringType(PrimitiveType, Singleton):
>>> column_foo = StringType()
>>> isinstance(column_foo, StringType)
True
+ >>> column_foo
+ StringType()
"""
- def __init__(self):
- if not self._initialized:
- super().__init__("string", "StringType()")
+ @property
+ def string_type(self) -> str:
+ return "string"
+@dataclass(frozen=True)
class UUIDType(PrimitiveType, Singleton):
"""A UUID data type in Iceberg can be represented using an instance of this class. UUIDs in
Iceberg are universally unique identifiers.
@@ -512,13 +519,16 @@ class UUIDType(PrimitiveType, Singleton):
>>> column_foo = UUIDType()
>>> isinstance(column_foo, UUIDType)
True
+ >>> column_foo
+ UUIDType()
"""
- def __init__(self):
- if not self._initialized:
- super().__init__("uuid", "UUIDType()")
+ @property
+ def string_type(self) -> str:
+ return "uuid"
+@dataclass(frozen=True)
class BinaryType(PrimitiveType, Singleton):
"""A Binary data type in Iceberg can be represented using an instance of this class. Binaries in
Iceberg are arbitrary-length byte arrays.
@@ -527,8 +537,10 @@ class BinaryType(PrimitiveType, Singleton):
>>> column_foo = BinaryType()
>>> isinstance(column_foo, BinaryType)
True
+ >>> column_foo
+ BinaryType()
"""
- def __init__(self):
- if not self._initialized:
- super().__init__("binary", "BinaryType()")
+ @property
+ def string_type(self) -> str:
+ return "binary"
diff --git a/python/tests/test_schema.py b/python/tests/test_schema.py
index 536277c91..d48198edd 100644
--- a/python/tests/test_schema.py
+++ b/python/tests/test_schema.py
@@ -221,19 +221,19 @@ def test_schema_find_field_by_id(table_schema_simple):
column1 = index[1]
assert isinstance(column1, NestedField)
assert column1.field_id == 1
- assert column1.type == StringType()
+ assert column1.field_type == StringType()
assert column1.is_optional == False
column2 = index[2]
assert isinstance(column2, NestedField)
assert column2.field_id == 2
- assert column2.type == IntegerType()
+ assert column2.field_type == IntegerType()
assert column2.is_optional == True
column3 = index[3]
assert isinstance(column3, NestedField)
assert column3.field_id == 3
- assert column3.type == BooleanType()
+ assert column3.field_type == BooleanType()
assert column3.is_optional == False
diff --git a/python/tests/test_types.py b/python/tests/test_types.py
index cda56ab4e..844e3ab7d 100644
--- a/python/tests/test_types.py
+++ b/python/tests/test_types.py
@@ -146,8 +146,8 @@ def test_list_type():
),
False,
)
- assert isinstance(type_var.element.type, StructType)
- assert len(type_var.element.type.fields) == 2
+ assert isinstance(type_var.element.field_type, StructType)
+ assert len(type_var.element.field_type.fields) == 2
assert type_var.element.field_id == 1
assert str(type_var) == str(eval(repr(type_var)))
assert type_var == eval(repr(type_var))
@@ -162,9 +162,9 @@ def test_list_type():
def test_map_type():
type_var = MapType(1, DoubleType(), 2, UUIDType(), False)
- assert isinstance(type_var.key.type, DoubleType)
+ assert isinstance(type_var.key.field_type, DoubleType)
assert type_var.key.field_id == 1
- assert isinstance(type_var.value.type, UUIDType)
+ assert isinstance(type_var.value.field_type, UUIDType)
assert type_var.value.field_id == 2
assert str(type_var) == str(eval(repr(type_var)))
assert type_var == eval(repr(type_var))
@@ -193,7 +193,7 @@ def test_nested_field():
assert field_var.is_optional
assert not field_var.is_required
assert field_var.field_id == 1
- assert isinstance(field_var.type, StructType)
+ assert isinstance(field_var.field_type, StructType)
assert str(field_var) == str(eval(repr(field_var)))