Skip to content

Commit dab2536

Browse files
authored
Update __repr__ for initial-default and write-default (#2287)
<!-- Thanks for opening a pull request! --> <!-- In the case this PR will resolve an issue, please replace ${GITHUB_ISSUE_ID} below with the actual Github issue id. --> Closes #1853 This adds a new repr function that ensures that `initial-default` and `write-default` will not appear if they are None. Unfortunately, this functionality isn't baked into Pydantic. # Rationale for this change __repr__ changes may be breaking. # Are these changes tested? Tests included. # Are there any user-facing changes? <!-- In the case of user-facing changes, please add the changelog label. -->
1 parent b435c1b commit dab2536

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

pyiceberg/types.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,8 @@ class NestedField(IcebergType):
340340
field_type: SerializeAsAny[IcebergType] = Field(alias="type")
341341
required: bool = Field(default=False)
342342
doc: Optional[str] = Field(default=None, repr=False)
343-
initial_default: Optional[DefaultValue] = Field(alias="initial-default", default=None, repr=False) # type: ignore
344-
write_default: Optional[DefaultValue] = Field(alias="write-default", default=None, repr=False) # type: ignore
343+
initial_default: Optional[DefaultValue] = Field(alias="initial-default", default=None, repr=True) # type: ignore
344+
write_default: Optional[DefaultValue] = Field(alias="write-default", default=None, repr=True) # type: ignore
345345

346346
@field_validator("field_type", mode="before")
347347
def convert_field_type(cls, v: Any) -> IcebergType:
@@ -401,6 +401,21 @@ def __str__(self) -> str:
401401
req = "required" if self.required else "optional"
402402
return f"{self.field_id}: {self.name}: {req} {self.field_type}{doc}"
403403

404+
def __repr__(self) -> str:
405+
"""Return the string representation of the NestedField class."""
406+
parts = [
407+
f"field_id={self.field_id}",
408+
f"name={self.name!r}",
409+
f"field_type={self.field_type!r}",
410+
f"required={self.required}",
411+
]
412+
if self.initial_default is not None:
413+
parts.append(f"initial_default={self.initial_default!r}")
414+
if self.write_default is not None:
415+
parts.append(f"write_default={self.write_default!r}")
416+
417+
return f"NestedField({', '.join(parts)})"
418+
404419
def __getnewargs__(self) -> Tuple[int, str, IcebergType, bool, Optional[str]]:
405420
"""Pickle the NestedField class."""
406421
return (self.field_id, self.name, self.field_type, self.required, self.doc)

tests/test_types.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,21 @@ def test_repr_decimal() -> None:
525525
assert repr(DecimalType(19, 25)) == "DecimalType(precision=19, scale=25)"
526526

527527

528+
def test_repr_nested_field_default_nones_should_not_appear() -> None:
529+
assert (
530+
repr(NestedField(1, "required_field", StringType(), required=False, initial_default=None, write_default=None))
531+
== "NestedField(field_id=1, name='required_field', field_type=StringType(), required=False)"
532+
)
533+
assert (
534+
repr(NestedField(1, "required_field", StringType(), required=False, initial_default="hello", write_default=None))
535+
== "NestedField(field_id=1, name='required_field', field_type=StringType(), required=False, initial_default='hello')"
536+
)
537+
assert (
538+
repr(NestedField(1, "required_field", StringType(), required=False, initial_default="hello", write_default="bye"))
539+
== "NestedField(field_id=1, name='required_field', field_type=StringType(), required=False, initial_default='hello', write_default='bye')"
540+
)
541+
542+
528543
def test_serialization_nestedfield() -> None:
529544
expected = '{"id":1,"name":"required_field","type":"string","required":true,"doc":"this is a doc"}'
530545
actual = NestedField(1, "required_field", StringType(), True, "this is a doc").model_dump_json()

0 commit comments

Comments
 (0)