Repository navigation
Use PyModule_AddObjectRef over PyModule_AddObject - #1059
Conversation
644c858 to
ac6319c
Compare
sobolevn
left a comment
There was a problem hiding this comment.
This is a nice first step! What would I ideally recommend?
- Create
ADD_MODULE_REFmacro that will abstract away this check +goto error - In
error:we can clean up all temporary references - We should define these references at the top set as
NULL Py_XDECREFthem on error :)
This would also require to modify existing macros as well.
What do you think?
Can you explain 4? Do you mean on the error check we're doing on the |
|
pseudo-code :) PyObject *temp_module = NULL;
PyObject *temp_obj = NULL;
#define SET_MODULE_REF(ATTR, VALUE) \
do { \
if (PyModule_AddObjectRef(m, (ATTR), (VALUE)) < 0) \
goto error; \
} while (0)
#define IMPORT_TEMP_MODULE(MOD_NAME) \
do { \
Py_XDECREF(temp_module); // clean other existing temp module \
temp_module = PyImport_ImportModule((MOD_NAME));
if (temp_module == NULL) goto error;
} while (0)
SET_MODULE_REF("JSONDecoder", (PyObject *)&JSONDecoder_Type);
// ...
IMPORT_TEMP_MODULE("typing");
SET_REF(typing_union, "Union");
error:
Py_XDECREF(temp_module);
Py_XDECREF(temp_obj); |
|
Reviewed and tested this (built the branch, full unit suite passes). The swap is refcount-correct everywhere, and on failure it is actually safer than before (the old On @sobolevn's macro idea: I like it, but I would do it in a separate PR. The LGTM to merge as a first step. |
Clean up handling of module imports in `PyInit__core`: - Unify error handling; Introduce and always use `error` label to ensure temporary objects are cleaned up (previously we often did `return NULL` early, missing `Py_XDECREF` in a few places) - Introduce a new `SET_MODULE_REF` macro to uniformly handle the "call `PyModule_AddObjectRef`, check for errors" pattern - Introduce a new `IMPORT_TEMP_MODULE` to uniformly handle the "import module as `temp_module`, get attribute from `temp_module` as `temp_obj`, and assign it to the module state" Removes 2 leaks found with `LSan` on (checked locally, as it's turned off in CI) <hr> Based on @sobolevn's suggestion here: msgspec#1059 (review) --------- Co-authored-by: sobolevn <[email protected]>
Use
PyModule_AddObjectRefinstead ofPyModule_AddObject, to make these calls more robust and terse.This also fixes quite a few leaks in error cases. We often used the pattern
where we don't
Py_DECREFin the error case.