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

AlenkaF pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 3db7076bad1 GH-50847: [Python] Add Type_RUN_END_ENCODED to 
_NESTED_TYPES set (#50848)
3db7076bad1 is described below

commit 3db7076bad124ab46c41bee3ba8f31509342d1de
Author: nishad shabbir <[email protected]>
AuthorDate: Thu Aug 27 19:31:56 2026 +0530

    GH-50847: [Python] Add Type_RUN_END_ENCODED to _NESTED_TYPES set (#50848)
    
    ### Rationale for this change
    
    `pyarrow.types.is_nested()` said a run-end encoded type wasn't nested, 
while the C++ `arrow::is_nested()` says it is:
    
    ```python
    >>> import pyarrow as pa
    >>> t = pa.run_end_encoded(pa.int32(), pa.string())
    >>> t.num_fields
    2
    >>> pa.types.is_nested(t)
    False
    ```
    
    The Python side reads from a hardcoded `_NESTED_TYPES` set in 
`python/pyarrow/types.py` rather than from the C++ trait, so it has to be kept 
in step by hand. Lining that set up against `is_nested()` in 
`cpp/src/arrow/type_traits.h`, run-end encoded was the only type the two still 
disagreed about — the list-view types and fixed-size list are already there.
    
    It's also out of step with the type itself. Run-end encoded has two 
children, the run ends and the values, and every other type in pyarrow that has 
children answers `True` here.
    
    This is the same thing that happened to fixed-size list in #40171, fixed by 
#40172, and the list-view types were added after that. This looks like the last 
one missed when run-end encoding went in.
    
    ### What changes are included in this PR?
    
    Adds `Type_RUN_END_ENCODED` to `_NESTED_TYPES`, which is the whole fix.
    
    In the test I've added the run-end encoded case, and while I was there also 
a map and a dictionary. Map was nested already but wasn't asserted anywhere, 
and dictionary is the interesting negative — it wraps a value type but is 
deliberately not nested in either implementation, so pinning it means a later 
change can't quietly sweep it in.
    
    ### Are these changes tested?
    
    Yes. `test_is_nested_or_struct` fails on the current code and passes with 
the change.
    
    I don't have a local C++ build, so I checked this by running the updated 
`test_types.py` against an installed pyarrow 25.0.0 with the same one-line 
change applied to its `types.py`. Before the change that file had 87 passing 
with `test_is_nested_or_struct` failing; after it, 88 passing. The two errors 
and one failure I see in both runs are environmental on my machine and 
unrelated — the errors are the `pickle_module` fixture, which comes from a 
conftest I wasn't loading, and the failu [...]
    
    ### Are there any user-facing changes?
    
    Yes, though it's small. `pa.types.is_nested()` now returns `True` for 
run-end encoded types where it previously returned `False`. Anything branching 
on that predicate will take the nested path for these types, which is the 
intended answer and what the C++ implementation has always given. Nothing 
inside pyarrow reads `is_nested` or `_NESTED_TYPES`, so the effect is limited 
to callers.
    
    * GitHub Issue: #50847
    
    Authored-by: nishad shabbir <[email protected]>
    Signed-off-by: AlenkaF <[email protected]>
---
 python/pyarrow/tests/test_types.py | 3 +++
 python/pyarrow/types.py            | 3 ++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/python/pyarrow/tests/test_types.py 
b/python/pyarrow/tests/test_types.py
index e0d74775e05..4f251d14334 100644
--- a/python/pyarrow/tests/test_types.py
+++ b/python/pyarrow/tests/test_types.py
@@ -244,7 +244,10 @@ def test_is_nested_or_struct():
     assert types.is_nested(pa.large_list(pa.int32()))
     assert types.is_nested(pa.list_view(pa.int32()))
     assert types.is_nested(pa.large_list_view(pa.int32()))
+    assert types.is_nested(pa.map_(pa.string(), pa.int32()))
+    assert types.is_nested(pa.run_end_encoded(pa.int32(), pa.string()))
     assert not types.is_nested(pa.int32())
+    assert not types.is_nested(pa.dictionary(pa.int32(), pa.string()))
 
 
 def test_is_union():
diff --git a/python/pyarrow/types.py b/python/pyarrow/types.py
index ab4e5d1b992..b72427e54d0 100644
--- a/python/pyarrow/types.py
+++ b/python/pyarrow/types.py
@@ -45,7 +45,8 @@ _TEMPORAL_TYPES = ({lib.Type_TIMESTAMP,
 _UNION_TYPES = {lib.Type_SPARSE_UNION, lib.Type_DENSE_UNION}
 _NESTED_TYPES = {lib.Type_LIST, lib.Type_FIXED_SIZE_LIST, lib.Type_LARGE_LIST,
                  lib.Type_LIST_VIEW, lib.Type_LARGE_LIST_VIEW,
-                 lib.Type_STRUCT, lib.Type_MAP} | _UNION_TYPES
+                 lib.Type_STRUCT, lib.Type_MAP,
+                 lib.Type_RUN_END_ENCODED} | _UNION_TYPES
 
 
 class TypesEnum(IntEnum):

Reply via email to