diff --git a/src/cpyrt/CPPConstructor.h b/src/cpyrt/CPPConstructor.h index 0566df0..d0bc7b2 100644 --- a/src/cpyrt/CPPConstructor.h +++ b/src/cpyrt/CPPConstructor.h @@ -22,6 +22,7 @@ class CPPConstructor : public CPPMethod { protected: bool InitExecutor_(Executor*&, CallContext* ctxt = nullptr) override; + bool ResultIsPyObject() const override { return false; } }; // specialization for multiple inheritance disambiguation diff --git a/src/cpyrt/CPPMethod.cxx b/src/cpyrt/CPPMethod.cxx index 3fe3e37..e9a1d7f 100644 --- a/src/cpyrt/CPPMethod.cxx +++ b/src/cpyrt/CPPMethod.cxx @@ -186,7 +186,8 @@ inline PyObject* cpyrt::CPPMethod::ExecuteFast(void* self, ptrdiff_t offset, // Windows, so instead leaves the error be #ifdef _WIN32 if (PyErr_Occurred()) { - Py_XDECREF(result); + if (ResultIsPyObject()) + Py_XDECREF(result); result = nullptr; } #endif diff --git a/src/cpyrt/CPPMethod.h b/src/cpyrt/CPPMethod.h index 54429a2..8c66a1d 100644 --- a/src/cpyrt/CPPMethod.h +++ b/src/cpyrt/CPPMethod.h @@ -91,6 +91,10 @@ class CPPMethod : public PyCallable { virtual bool InitExecutor_(Executor*&, CallContext* ctxt = nullptr); + // whether fExecutor's result is a real PyObject* (ConstructorExecutor + // returns the new object's address instead) + virtual bool ResultIsPyObject() const { return true; } + private: void Copy_(const CPPMethod&); void Destroy_();