Skip to content

Define synchronization guarantees for Promise state reads on free-threaded Python #115

Description

@coderabbitai

Summary

Make the Promise state-read contract safe for free-threaded CPython, or explicitly define free-threaded Python as unsupported.

Promise currently writes result data before it advances _state. Methods such as done(), result(), exception(), cancelled(), intermediate_promise(), and unpacked_once() read these fields without synchronization.

Rationale

The current design is correct for CPython builds with the GIL. A reader can observe a stale earlier state, which is benign.

Free-threaded CPython does not provide the same GIL-based ordering assumption. A reader could observe a terminal _state before it observes the associated _result, _exception, or _intermediate_promise write. For example, Promise.result() could pass _assert_done() and then see _result is UNCHANGED.

This is not a current production bug for the supported GIL-based runtime. It is future compatibility work.

Affected area

  • promising/promise.py
    • State writers: _set_intermediate_promise_from_loop(), _set_result_from_loop(), _set_exception_from_loop(), _set_state()
    • State readers: done(), result(), exception(), cancelled(), intermediate_promise(), unpacked_once(), and unpacked_once_or_done()

Required changes

  1. Decide whether free-threaded CPython is a supported runtime.
  2. If it is supported, add synchronization that establishes ordering between data writes and _state transitions.
  3. If it is not supported, document this runtime limitation in the package support policy and keep the existing GIL-based contract explicit.
  4. Add tests that cover the selected contract where practical.

Acceptance criteria

  • The project documents whether free-threaded CPython is supported.
  • If supported, state readers cannot observe a terminal state without its matching result, exception, or intermediate value.
  • The implementation and tests preserve the existing behavior on GIL-based CPython.

Backlinks

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions