diff --git a/NEWS.md b/NEWS.md index 4ccfc90f..c87421d2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,10 +1,12 @@ # reticulate (development version) +- Fixed error when converting an empty NumPy char array to R (#1662). + - Fixed error when using reticulate with radian (#1668, #1670). - Fixed segfault encountered when running Python finalizer (#1663, #1664) -- Fixed segfault encountered in RStudio when rapidly switching +- Fixed segfault encountered in RStudio when rapidly switching between R and Python chunks in a Quarto document (#1665). - Improved behavior when the conda binary used to create an environment diff --git a/src/python.cpp b/src/python.cpp index 8768073f..31bd3f6b 100644 --- a/src/python.cpp +++ b/src/python.cpp @@ -1550,6 +1550,14 @@ SEXP py_to_r_cpp(PyObject* x, bool convert, bool simple) { case NPY_VSTRING: case NPY_UNICODE: { + rArray = Rf_allocArray(STRSXP, dimsVector); + RObject protectArray(rArray); + + // special case 0-size vectors, because np.nditer() throws: + // ValueError: Iteration of zero-sized operands is not enabled + if (Rf_length(rArray) == 0) + break; + static PyObject* nditerArgs = []() { PyObject* flags = PyTuple_New(1); // iterating over a StringDType requires us to pass 'refs_ok' flag, @@ -1559,7 +1567,7 @@ SEXP py_to_r_cpp(PyObject* x, bool convert, bool simple) { PyTuple_SetItem(args, 1, flags); // steals ref return args; }(); - // PyTuple_SetItem steals reference the array, but it's already wraped + // PyTuple_SetItem steals reference the array, but it's already wrapped // into PyObjectPtr earlier (so it gets deleted after the scope of this function) // To avoid trying to delete it twice, we need to increase its ref count here. PyTuple_SetItem(nditerArgs, 0, (PyObject*)array); @@ -1572,10 +1580,6 @@ SEXP py_to_r_cpp(PyObject* x, bool convert, bool simple) { throw PythonException(py_fetch_error()); } - rArray = Rf_allocArray(STRSXP, dimsVector); - RObject protectArray(rArray); - - for (int i=0; i