Collected lower-priority findings for consideration:
Version compatibility cleanup
11 dead #if PY_VERSION_HEX >= 0x03090000 guards across 8 files — minimum is 3.10, can be unconditionally removed
19 deprecated PyModule_AddObject calls — should migrate to PyModule_AddObjectRef (available since 3.10, the minimum version). 10 of these are unchecked (see Copy-paste bug in init_containerlistchange + unchecked PyModule_AddObject x10 + cached_property stores NULL #261 ).
Py_TPFLAGS_HAVE_VERSION_TAG in 2 type specs (atomdict.cpp:349,430) — no-op since Python 3.0
PyErr_Fetch/PyErr_Restore in modifyguard.h:42,60 — deprecated in 3.12, clean migration to PyErr_GetRaisedException/PyErr_SetRaisedException
PyMapping_HasKey fallback for 3.10-3.12 (catom.cpp:454-460) suppresses exceptions
Private API uses
_Py_NewReference in eventbinder.cpp:170 and signalconnector.cpp:184 (freelist reuse) — private API, may change across versions
_PyObject_GetDictPtr in catom.cpp:383 — private API, no public equivalent with identical semantics
pythoncapi-compat adoption would eliminate the active PyMapping_HasKeyWithError version guard and enable forward API migrations
Free-threading readiness
2 freelists (EventBinder, SignalConnector) without synchronization — would race under Py_GIL_DISABLED
Global GuardMap and RefMap (catom.cpp:653, atomref.cpp:37) — process-global mutable state
Non-atomic bitfield operations on CAtom flags
set_slot TOCTOU between validation and store
ObserverPool unprotected container operations
No Py_MOD_GIL_NOT_USED declared in either module
Type slot notes
MethodWrapper and AtomMethodWrapper have PyObject* members but no Py_TPFLAGS_HAVE_GC — GC can't break cycles through these types
sortedmap_modexec returns false(0) not -1 — wrong return convention for Py_mod_exec (should return -1 on error)
Module state
Multi-phase init without per-module state : Both PyModuleDef have m_size=0 despite ~47 global PyObject* variables. HIGH migration difficulty.
Py_TPFLAGS_IMMUTABLETYPE not set on any type (available since 3.10)
Found by cext-review-toolkit .
Collected lower-priority findings for consideration:
Version compatibility cleanup
#if PY_VERSION_HEX >= 0x03090000guards across 8 files — minimum is 3.10, can be unconditionally removedPyModule_AddObjectcalls — should migrate toPyModule_AddObjectRef(available since 3.10, the minimum version). 10 of these are unchecked (see Copy-paste bug in init_containerlistchange + unchecked PyModule_AddObject x10 + cached_property stores NULL #261).Py_TPFLAGS_HAVE_VERSION_TAGin 2 type specs (atomdict.cpp:349,430) — no-op since Python 3.0PyErr_Fetch/PyErr_Restoreinmodifyguard.h:42,60— deprecated in 3.12, clean migration toPyErr_GetRaisedException/PyErr_SetRaisedExceptionPyMapping_HasKeyfallback for 3.10-3.12 (catom.cpp:454-460) suppresses exceptionsPrivate API uses
_Py_NewReferenceineventbinder.cpp:170andsignalconnector.cpp:184(freelist reuse) — private API, may change across versions_PyObject_GetDictPtrincatom.cpp:383— private API, no public equivalent with identical semanticspythoncapi-compatadoption would eliminate the activePyMapping_HasKeyWithErrorversion guard and enable forward API migrationsFree-threading readiness
Py_GIL_DISABLEDGuardMapandRefMap(catom.cpp:653,atomref.cpp:37) — process-global mutable stateset_slotTOCTOU between validation and storePy_MOD_GIL_NOT_USEDdeclared in either moduleType slot notes
MethodWrapperandAtomMethodWrapperhavePyObject*members but noPy_TPFLAGS_HAVE_GC— GC can't break cycles through these typessortedmap_modexecreturnsfalse(0) not -1 — wrong return convention forPy_mod_exec(should return -1 on error)Module state
PyModuleDefhavem_size=0despite ~47 globalPyObject*variables. HIGH migration difficulty.Py_TPFLAGS_IMMUTABLETYPEnot set on any type (available since 3.10)Found by cext-review-toolkit.