Skip to content

Commit 01bffe5

Browse files
committed
fix iadd pythonization for np/array buffers
1 parent c6d623a commit 01bffe5

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

src/Pythonize.cxx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -448,9 +448,25 @@ PyObject* VectorIAdd(PyObject* self, PyObject* args, PyObject* /* kwds */)
448448
if (PyObject_CheckBuffer(fi) && !(CPyCppyy_PyText_Check(fi) || PyBytes_Check(fi))) {
449449
PyObject* vend = PyObject_CallMethodNoArgs(self, PyStrings::gEnd);
450450
if (vend) {
451-
PyObject* result = PyObject_CallMethodObjArgs(self, PyStrings::gInsert, vend, fi, nullptr);
452-
Py_DECREF(vend);
453-
return result;
451+
// when __iadd__ is overriden, the operation does not end with
452+
// calling the __iadd__ method, but also assigns the result to the
453+
// lhs of the iadd. For example, performing vec += arr, Python
454+
// first calls our override, and then does vec = vec.iadd(arr).
455+
PyObject *it = PyObject_CallMethodObjArgs(self, PyStrings::gInsert, vend, fi, nullptr);
456+
Py_DECREF(vend);
457+
458+
if (!it) {
459+
PyErr_SetString(PyExc_TypeError, "std::vector::insert failed");
460+
return nullptr;
461+
}
462+
463+
Py_DECREF(it);
464+
465+
// To prevent Python from assigning the return value of our
466+
// __iadd__ implementation (which is a std::iterator)
467+
// to the std::vector itself, we return self
468+
Py_INCREF(self);
469+
return self;
454470
}
455471
}
456472
}

0 commit comments

Comments
 (0)