Tracking issue for free-threaded Python (Py_GIL_DISABLED) support. Companion to the umbrella 3.14 tracker #2610.
Why FT is different from a normal GIL build
- PyObject_HEAD is 16 bytes larger; the refcount is split across ob_ref_local + ob_ref_shared and must be read via Py_REFCNT (a real exported symbol on 3.14+).
- Build detection: sys._is_gil_enabled() (added in 3.13) returns False on FT.
- The GIL has been silently serialising every pythonnet static cache, lock-free counter, finalizer-thread interaction, and Reflection.Emit use site. All of those need explicit synchronisation under FT.
Hazards in pythonnet (resolved by PR #2721)
| Area |
What broke |
How it was fixed |
| Refcount / ABI |
Single-offset read |
Py_REFCNT P/Invoke + ObjectHeadOffset = 16 for FT |
| Type-creation race |
Duplicate cache.Add; partial-type visibility |
Two-cache (cache + _inProgressCache) under _cacheCreateLock |
| GCHandle in tp_clear/tp_dealloc |
Double-free under main-thread + finalizer-thread race |
Interlocked.Exchange on the slot |
| Reflection.Emit |
Concurrent DefineType corrupts IL / throws "Duplicate type name" |
Lock both CreateDerivedType and DelegateManager.GetDispatcher |
| Static collections |
Plain Dictionary/HashSet/List thread-safety issues |
ConcurrentDictionary where possible; Interlocked/Volatile for single-cell state; locks for nested mutation and ordered list semantics |
| Finalizer-thread / Py_Finalize interaction |
Stale ob_ref_local reads after teardown crash the process |
Runtime._Py_IsFinalizing() guards on all decref-from-finalizer paths |
| Chained ClassDerived.Finalize IL |
Nested Python-derived classes with __namespace__ chained through emitted Finalize methods, queuing the same __pyobj__ twice → PyObject_GC_Del on freed memory |
Skip the base-Finalize chain when the base is itself pythonnet-emitted (IPythonDerivedType) |
See PR #2721 for the per-file detail.
References
Reactions are currently unavailable
Tracking issue for free-threaded Python (Py_GIL_DISABLED) support. Companion to the umbrella 3.14 tracker #2610.
Why FT is different from a normal GIL build
Hazards in pythonnet (resolved by PR #2721)
See PR #2721 for the per-file detail.
References