bpo-38823: Add a private _PyModule_StealObject API. by brandtbucher · Pull Request #17298 · python/cpython
@vstinner I too prefer it when functions don't steal references. If I were designing a brand new API, I would definitely not do it this way. The issue is that there are dozens of modules with complicated (broken) initialization code that relies on the stealing behavior of PyModule_AddObject (but doesn't properly handle errors). See _ctypes for a good example of code that is much easier to fix if we keep the stealing behvior.
If you still disagree, I can change it to never steal. It's just my impression from looking at the mountain of complex, broken code ahead of me that this is probably the easier route to take, especially since this API is just meant to be a "band-aid" for another broken API.
I added PyModule_AddObjectRef() which uses strong references, rather than only stealing a reference on success.
I also enhanced the documentation to show concrete examples:
https://docs.python.org/dev/c-api/module.html#c.PyModule_AddObjectRef
I modified a few extension to use PyModule_AddObjectRef(). Sometimes, PyModule_AddObject() is more appropriate. Sometimes, PyModule_AddObjectRef() is more appropriate. Both functions are relevant, and I don't see a clear winner.
I agree than fixing existing code is painful, but I hope that new code using mostly PyModule_AddObjectRef() would be simpler to review. I'm not sure that it's simpler to write new code using PyModule_AddObjectRef(), since you might need more Py_DECREF() calls.
My intent is to have more "regular" code about reference counting. See also: https://bugs.python.org/issue42294
Since you wrote that this API is a band aid on a broken API, I consider that you are fine with rejecting it and move on to the new PyModule_AddObjectRef().
Anyway, thanks for you attempt to make the C API less broken :-)