A detailed analysis of _zope_interface_coptimizations.c was published at
https://gist.github.com/devdanzin/5afbad864934b165a2cc080f110aa720 by @devdanzin.
We reviewed the report with agent support and verified the findings against the
current source (zope.interface 8.2). This issue is one of several extracted from
that review.
Problem
Declaration import leaks:
Both import_declarations (static types, lines 213-238) and
_zic_state_load_declarations (heap types, lines 2241-2275) leak the
declarations module reference and intermediate attribute references on every
early-return error path. Py_DECREF(declarations) only executes on the success
path.
Module init leaks:
_zic_module_exec at line 2652 does Py_INCREF(rec->adapter_hooks) to account
for a later PyModule_AddObject (which steals a ref). If the function fails
before reaching PyModule_AddObject, the extra reference is never consumed.
Same pattern for heap types created via PyType_FromModuleAndSpec — each gets
Py_INCREF for a later PyModule_AddObject that may never execute.
Fix
Declaration imports — use a goto error cleanup pattern:
declarations = PyImport_ImportModule("zope.interface.declarations");
if (declarations == NULL) return -1;
builtin_impl_specs = PyObject_GetAttrString(
declarations, "BuiltinImplementationSpecifications");
if (builtin_impl_specs == NULL) goto error;
empty = PyObject_GetAttrString(declarations, "_empty");
if (empty == NULL) goto error;
// ... success path ...
Py_DECREF(declarations);
return 0;
error:
Py_DECREF(declarations);
return -1;
Module init — either defer Py_INCREF until just before PyModule_AddObject,
or switch to PyModule_AddObjectRef (available since 3.10, does not steal
references) and remove the extra Py_INCREF calls entirely.
Scope
Largest of the seven issues. Refactors error paths in import_declarations,
_zic_state_load_declarations, and _zic_module_exec. Only affects error and
init-failure paths.
Tests
Not feasible from pure Python. These leaks only occur when module
initialization or declaration import partially fails — conditions that require
internal C-level failures (e.g., PyObject_GetAttrString returning NULL for a
valid module attribute). Cannot be triggered from Python without monkeypatching
the import machinery in unsafe ways.
Code review of the goto error pattern is the appropriate verification.
The existing test suite implicitly tests the success path of these functions on
every test run.
Performance impact
Zero. These functions run once at module import time. No runtime paths affected.
A detailed analysis of
_zope_interface_coptimizations.cwas published athttps://gist.github.com/devdanzin/5afbad864934b165a2cc080f110aa720 by @devdanzin.
We reviewed the report with agent support and verified the findings against the
current source (zope.interface 8.2). This issue is one of several extracted from
that review.
Problem
Declaration import leaks:
Both
import_declarations(static types, lines 213-238) and_zic_state_load_declarations(heap types, lines 2241-2275) leak thedeclarationsmodule reference and intermediate attribute references on everyearly-return error path.
Py_DECREF(declarations)only executes on the successpath.
Module init leaks:
_zic_module_execat line 2652 doesPy_INCREF(rec->adapter_hooks)to accountfor a later
PyModule_AddObject(which steals a ref). If the function failsbefore reaching
PyModule_AddObject, the extra reference is never consumed.Same pattern for heap types created via
PyType_FromModuleAndSpec— each getsPy_INCREFfor a laterPyModule_AddObjectthat may never execute.Fix
Declaration imports — use a
goto errorcleanup pattern:Module init — either defer
Py_INCREFuntil just beforePyModule_AddObject,or switch to
PyModule_AddObjectRef(available since 3.10, does not stealreferences) and remove the extra
Py_INCREFcalls entirely.Scope
Largest of the seven issues. Refactors error paths in
import_declarations,_zic_state_load_declarations, and_zic_module_exec. Only affects error andinit-failure paths.
Tests
Not feasible from pure Python. These leaks only occur when module
initialization or declaration import partially fails — conditions that require
internal C-level failures (e.g.,
PyObject_GetAttrStringreturning NULL for avalid module attribute). Cannot be triggered from Python without monkeypatching
the import machinery in unsafe ways.
Code review of the
goto errorpattern is the appropriate verification.The existing test suite implicitly tests the success path of these functions on
every test run.
Performance impact
Zero. These functions run once at module import time. No runtime paths affected.