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

kevinjqliu 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 098174c2 Fix for ns timestamp non utc (#3142)
098174c2 is described below

commit 098174c2fbcf9dcbc94c2ef9277e05f5e862de1f
Author: Neelesh Salian <[email protected]>
AuthorDate: Thu Mar 12 10:36:21 2026 -0700

    Fix for ns timestamp non utc (#3142)
    
    Closes #3127
    
    # Rationale for this change
    `pa.timestamp("ns", tz="US/Pacific") converts to TimestampNanoType()`
    (tz-naive) instead of raising `TypeError`. The `us` path correctly
    rejects non-UTC timezones.
    
    raises TypeError
    `visit_pyarrow(pa.timestamp("us", tz="US/Pacific"),
    _ConvertToIceberg())`
    
    silently drops timezone
    `visit_pyarrow(pa.timestamp("ns", tz="US/Pacific"),
    _ConvertToIceberg(format_version=3))`
    
    Fixes this by adding the correct elif clause
    ## Are these changes tested?
    Yes - added a couple of tests in the pyarrow visitor
    
    ## Are there any user-facing changes?
    It fixes the behavior that was a bug, so I think it would be.
---
 pyiceberg/io/pyarrow.py          |  2 +-
 tests/io/test_pyarrow_visitor.py | 13 +++++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/pyiceberg/io/pyarrow.py b/pyiceberg/io/pyarrow.py
index 0dfc5eb5..8f22261f 100644
--- a/pyiceberg/io/pyarrow.py
+++ b/pyiceberg/io/pyarrow.py
@@ -1451,7 +1451,7 @@ class _ConvertToIceberg(PyArrowSchemaVisitor[IcebergType 
| Schema]):
                 elif self._format_version >= 3:
                     if primitive.tz in UTC_ALIASES:
                         return TimestamptzNanoType()
-                    else:
+                    elif primitive.tz is None:
                         return TimestampNanoType()
                 else:
                     raise TypeError(
diff --git a/tests/io/test_pyarrow_visitor.py b/tests/io/test_pyarrow_visitor.py
index 433350c2..6727b8c7 100644
--- a/tests/io/test_pyarrow_visitor.py
+++ b/tests/io/test_pyarrow_visitor.py
@@ -63,6 +63,7 @@ from pyiceberg.types import (
     NestedField,
     StringType,
     StructType,
+    TimestampNanoType,
     TimestampType,
     TimestamptzType,
     TimeType,
@@ -226,6 +227,18 @@ def test_pyarrow_timestamp_tz_invalid_tz() -> None:
         visit_pyarrow(pyarrow_type, _ConvertToIceberg())
 
 
+def test_pyarrow_timestamp_ns_tz_invalid_tz() -> None:
+    pyarrow_type = pa.timestamp(unit="ns", tz="US/Pacific")
+    with pytest.raises(TypeError, match=re.escape("Unsupported type: 
timestamp[ns, tz=US/Pacific]")):
+        visit_pyarrow(pyarrow_type, _ConvertToIceberg(format_version=3))
+
+
+def test_pyarrow_timestamp_ns_no_tz_accepted() -> None:
+    pyarrow_type = pa.timestamp(unit="ns")
+    converted = visit_pyarrow(pyarrow_type, 
_ConvertToIceberg(format_version=3))
+    assert converted == TimestampNanoType()
+
+
 @pytest.mark.parametrize("pyarrow_type", [pa.string(), pa.large_string(), 
pa.string_view()])
 def test_pyarrow_string_to_iceberg(pyarrow_type: pa.DataType) -> None:
     converted_iceberg_type = visit_pyarrow(pyarrow_type, _ConvertToIceberg())

Reply via email to