Skip to content

Commit daf4bd5

Browse files
Merge branch 'v1.5-variegata' into pycapsuleinterface
2 parents 155e388 + a0d9bdf commit daf4bd5

3 files changed

Lines changed: 13 additions & 3 deletions

File tree

src/duckdb_py/arrow/arrow_array_stream.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ unique_ptr<ArrowArrayStreamWrapper> PythonTableArrowArrayStreamFactory::Produce(
110110
auto capsule = py::reinterpret_borrow<py::capsule>(arrow_obj_handle);
111111
auto stream = capsule.get_pointer<struct ArrowArrayStream>();
112112
if (!stream->release) {
113-
throw InternalException("ArrowArrayStream was released by another thread/library");
113+
throw InvalidInputException("This ArrowArrayStream has already been consumed and cannot be scanned again.");
114114
}
115115
res->arrow_array_stream = *stream;
116116
stream->release = nullptr;
@@ -154,7 +154,7 @@ void PythonTableArrowArrayStreamFactory::GetSchemaInternal(py::handle arrow_obj_
154154
auto capsule = py::reinterpret_borrow<py::capsule>(arrow_obj_handle);
155155
auto stream = capsule.get_pointer<struct ArrowArrayStream>();
156156
if (!stream->release) {
157-
throw InternalException("ArrowArrayStream was released by another thread/library");
157+
throw InvalidInputException("This ArrowArrayStream has already been consumed and cannot be scanned again.");
158158
}
159159
if (stream->get_schema(stream, &schema.arrow_schema)) {
160160
throw InvalidInputException("Failed to get Arrow schema from stream: %s",

tests/fast/arrow/test_arrow_pycapsule.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ def test_automatic_reexecution(self, duckdb_cursor):
7171
assert len(res1) == 100
7272
assert res1 == res2
7373

74+
def test_pycapsule_rescan_error_type(self, duckdb_cursor):
75+
"""Issue #105: re-executing a relation backed by a consumed PyCapsule."""
76+
pa = pytest.importorskip("pyarrow")
77+
tbl = pa.table({"a": [1]})
78+
capsule = tbl.__arrow_c_stream__() # noqa: F841
79+
rel = duckdb_cursor.sql("SELECT * FROM capsule")
80+
rel.fetchall() # consumes the capsule
81+
with pytest.raises(duckdb.InvalidInputException):
82+
rel.fetchall() # re-execution should be InvalidInputException, not InternalException
83+
7484
def test_consumer_interface_roundtrip(self, duckdb_cursor):
7585
def create_table():
7686
class MyTable:

0 commit comments

Comments
 (0)