I have a %extend-created constructor that, on failure, throws a Python exception and returns NULL. But the wrapper code (SWIG_NewPointerObj in _wrap_new_X) converts NULL to Py_None and then returns a nonnegative value, indicating success, and the object is created. The generated code _is_ checking for this case and acting differently:
return resultobj == Py_None ? 1 : 0;
However, Python only checks for < 0 as an error case, so 1 means the same as 0 or any other nonnegative value here (return value from tp_init initproc), and -1 should be returned in this case instead. If I change the 1 return to -1, the exception is propagated as expected. The above code is generated by an "if (builtin_ctor)" case in PYTHON::functionWrapper.