Skip to content

Fix free-threaded Python 3.14t support in C extension#352

Merged
jensens merged 1 commit intozopefoundation:masterfrom
bluedynamics:fix-freethreaded
Feb 17, 2026
Merged

Fix free-threaded Python 3.14t support in C extension#352
jensens merged 1 commit intozopefoundation:masterfrom
bluedynamics:fix-freethreaded

Conversation

@jensens
Copy link
Member

@jensens jensens commented Feb 16, 2026

Summary

  • Declare Py_mod_gil_not_used in module slots so the GIL is not re-enabled on import under free-threaded Python 3.14t (PEP 703)
  • Replace PyDict_GetItem() borrowed references with PyDict_GetItemRef() strong references in all cache lookup functions (_subcache, _getcache, _lookup, _lookup1, _lookupAll, _subscriptions, implementedBy). This prevents use-after-free when another thread clears the cache between the dict lookup return and Py_INCREF().
  • Use Py_TYPE() macro instead of direct ob_type struct access (incompatible with atomic type lookups in free-threaded builds)
  • Add PyDict_GetItemRef polyfill for Python < 3.13 (compiles to the same PyDict_GetItem + Py_INCREF pattern, zero overhead)
  • Add 3.14t to CI matrix and tox envlist

Tested locally on both Python 3.14 (1358 tests pass) and Python 3.14t (1358 tests pass, no GIL re-enable warning). Benchmark shows zero regression on cached adapter lookups (~109ns/call before vs ~106ns/call after).

Refs #332

- Declare Py_mod_gil_not_used so the GIL is not re-enabled on import
- Replace PyDict_GetItem() borrowed refs with PyDict_GetItemRef()
  strong refs in cache lookups to prevent use-after-free races
- Use Py_TYPE() macro instead of direct ob_type struct access
- Add 3.14t to CI and tox envlist

Refs zopefoundation#332
@jensens jensens merged commit 97f29ea into zopefoundation:master Feb 17, 2026
50 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants