You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ap...@apache.org on 2022/08/02 14:33:49 UTC

[arrow] branch master updated: ARROW-17253: [Python] Detect iterator exception instead of crashing (#13764)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new dd962782ee ARROW-17253: [Python] Detect iterator exception instead of crashing (#13764)
dd962782ee is described below

commit dd962782eed88d7c7acb798e98f1b70931e991fb
Author: Antoine Pitrou <an...@python.org>
AuthorDate: Tue Aug 2 16:33:43 2022 +0200

    ARROW-17253: [Python] Detect iterator exception instead of crashing (#13764)
    
    When `pa.array` is given a generator that raises an exception, ensure the exception is correctly detected, even when an explicit size is also given.
    
    Authored-by: Antoine Pitrou <an...@python.org>
    Signed-off-by: Antoine Pitrou <an...@python.org>
---
 cpp/src/arrow/python/python_to_arrow.cc      | 8 ++++++--
 python/pyarrow/tests/test_convert_builtin.py | 8 ++++++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/cpp/src/arrow/python/python_to_arrow.cc b/cpp/src/arrow/python/python_to_arrow.cc
index 024c9c575c..7a94407d2d 100644
--- a/cpp/src/arrow/python/python_to_arrow.cc
+++ b/cpp/src/arrow/python/python_to_arrow.cc
@@ -1114,13 +1114,17 @@ Status ConvertToSequenceAndInferSize(PyObject* obj, PyObject** seq, int64_t* siz
     RETURN_IF_PYERROR();
     for (i = 0; i < n; i++) {
       PyObject* item = PyIter_Next(iter);
-      if (!item) break;
+      if (!item) {
+        // either an error occurred or the iterator ended
+        RETURN_IF_PYERROR();
+        break;
+      }
       PyList_SET_ITEM(lst, i, item);
     }
     // Shrink list if len(iterator) < size
     if (i < n && PyList_SetSlice(lst, i, n, NULL)) {
       Py_DECREF(lst);
-      return Status::UnknownError("failed to resize list");
+      RETURN_IF_PYERROR();
     }
     *seq = lst;
     *size = std::min<int64_t>(i, *size);
diff --git a/python/pyarrow/tests/test_convert_builtin.py b/python/pyarrow/tests/test_convert_builtin.py
index 1eb1d1b08c..732164f9e1 100644
--- a/python/pyarrow/tests/test_convert_builtin.py
+++ b/python/pyarrow/tests/test_convert_builtin.py
@@ -125,6 +125,14 @@ def test_infinite_iterator():
     assert arr1.equals(expected)
 
 
+def test_failing_iterator():
+    with pytest.raises(ZeroDivisionError):
+        pa.array((1 // 0 for x in range(10)))
+    # ARROW-17253
+    with pytest.raises(ZeroDivisionError):
+        pa.array((1 // 0 for x in range(10)), size=10)
+
+
 def _as_list(xs):
     return xs