This is an automated email from the ASF dual-hosted git repository.

fokko pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-python.git


The following commit(s) were added to refs/heads/main by this push:
     new dab25362 Update `__repr__` for `initial-default` and `write-default` 
(#2287)
dab25362 is described below

commit dab25362831c9a2d6563b041b38f9698dc320d33
Author: Alex Stephen <1325798+ramblerap...@users.noreply.github.com>
AuthorDate: Thu Aug 7 14:01:57 2025 -0700

    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.
    -->
---
 pyiceberg/types.py  | 19 +++++++++++++++++--
 tests/test_types.py | 15 +++++++++++++++
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/pyiceberg/types.py b/pyiceberg/types.py
index 58225979..6872663f 100644
--- a/pyiceberg/types.py
+++ b/pyiceberg/types.py
@@ -340,8 +340,8 @@ class NestedField(IcebergType):
     field_type: SerializeAsAny[IcebergType] = Field(alias="type")
     required: bool = Field(default=False)
     doc: Optional[str] = Field(default=None, repr=False)
-    initial_default: Optional[DefaultValue] = Field(alias="initial-default", 
default=None, repr=False)  # type: ignore
-    write_default: Optional[DefaultValue] = Field(alias="write-default", 
default=None, repr=False)  # type: ignore
+    initial_default: Optional[DefaultValue] = Field(alias="initial-default", 
default=None, repr=True)  # type: ignore
+    write_default: Optional[DefaultValue] = Field(alias="write-default", 
default=None, repr=True)  # type: ignore
 
     @field_validator("field_type", mode="before")
     def convert_field_type(cls, v: Any) -> IcebergType:
@@ -401,6 +401,21 @@ class NestedField(IcebergType):
         req = "required" if self.required else "optional"
         return f"{self.field_id}: {self.name}: {req} {self.field_type}{doc}"
 
+    def __repr__(self) -> str:
+        """Return the string representation of the NestedField class."""
+        parts = [
+            f"field_id={self.field_id}",
+            f"name={self.name!r}",
+            f"field_type={self.field_type!r}",
+            f"required={self.required}",
+        ]
+        if self.initial_default is not None:
+            parts.append(f"initial_default={self.initial_default!r}")
+        if self.write_default is not None:
+            parts.append(f"write_default={self.write_default!r}")
+
+        return f"NestedField({', '.join(parts)})"
+
     def __getnewargs__(self) -> Tuple[int, str, IcebergType, bool, 
Optional[str]]:
         """Pickle the NestedField class."""
         return (self.field_id, self.name, self.field_type, self.required, 
self.doc)
diff --git a/tests/test_types.py b/tests/test_types.py
index 2527f0e8..18eb909d 100644
--- a/tests/test_types.py
+++ b/tests/test_types.py
@@ -525,6 +525,21 @@ def test_repr_decimal() -> None:
     assert repr(DecimalType(19, 25)) == "DecimalType(precision=19, scale=25)"
 
 
+def test_repr_nested_field_default_nones_should_not_appear() -> None:
+    assert (
+        repr(NestedField(1, "required_field", StringType(), required=False, 
initial_default=None, write_default=None))
+        == "NestedField(field_id=1, name='required_field', 
field_type=StringType(), required=False)"
+    )
+    assert (
+        repr(NestedField(1, "required_field", StringType(), required=False, 
initial_default="hello", write_default=None))
+        == "NestedField(field_id=1, name='required_field', 
field_type=StringType(), required=False, initial_default='hello')"
+    )
+    assert (
+        repr(NestedField(1, "required_field", StringType(), required=False, 
initial_default="hello", write_default="bye"))
+        == "NestedField(field_id=1, name='required_field', 
field_type=StringType(), required=False, initial_default='hello', 
write_default='bye')"
+    )
+
+
 def test_serialization_nestedfield() -> None:
     expected = 
'{"id":1,"name":"required_field","type":"string","required":true,"doc":"this is 
a doc"}'
     actual = NestedField(1, "required_field", StringType(), True, "this is a 
doc").model_dump_json()

Reply via email to