Skip to content

gh-159136: Avoid stop-the-world when setting function name attributes - #159269

Draft
nascheme wants to merge 3 commits into
python:mainfrom
nascheme:gh-159136-func-attrs
Draft

nascheme wants to merge 3 commits into
python:mainfrom
nascheme:gh-159136-func-attrs

Conversation

@nascheme

@nascheme nascheme commented Oct 12, 2026 •

Copy link
Copy Markdown
Member

Setting __name__, __qualname__, __doc__ or __module__ on a function stopped the world in the free-threaded build since gh-154826 and gh-154851, making functools.wraps() orders of magnitude slower with multiple threads.

Use the per-object critical section and _PyObject_XSetRefDelayed() instead, as gen_set_name() already does. Use acquire loads in the readers and hold strong references across error reporting, tracing, and eval-frame recording that may execute Python or detach the thread. The __code__, __defaults__, __kwdefaults__ and __closure__ setters still stop the world to clear func_version.

Document synchronization requirements for direct field access and the lifetime of borrowed function attributes.

Benchmark results (release free-threaded build, each thread creates its own function, 5000 iterations, time in seconds):

workload build 1t 2t 4t 8t
set __name__ main 0.002 4.95 4.86 5.99
set __name__ this PR 0.001 0.001 0.001 0.002
set __name__ + __doc__ main 0.004 7.70 10.02 11.47
set __name__ + __doc__ this PR 0.002 0.002 0.001 0.002
functools.wraps main 0.014 18.53 22.58 28.79
functools.wraps this PR 0.010 0.010 0.010 0.014

Note: this PR was created with assistance from LLM agents (Claude Fable and GPT 6.1 Sol).

…ibutes

Setting __name__, __qualname__, __doc__ or __module__ on a function
stopped the world in the free-threaded build since pythongh-154826 and
pythongh-154851, making functools.wraps() orders of magnitude slower with
multiple threads.

Use the per-object critical section and _PyObject_XSetRefDelayed()
instead, as gen_set_name() already does.  Use acquire loads in the
readers and hold strong references across error reporting, tracing, and
eval-frame recording that may execute Python or detach the thread.  The
__code__, __defaults__, __kwdefaults__ and __closure__ setters still
stop the world to clear func_version.

Document synchronization requirements for direct field access and the
lifetime of borrowed function attributes.
@read-the-docs-community

read-the-docs-community Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #35106100 | 📁 Comparing 7837be5 against main (0768eed)

  🔍 Preview build  

6 files changed · ± 6 modified

± Modified

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.

1 participant