Skip to content

gh-139103: Improve namedtuple scaling in free-threaded build - #144332

Merged
colesbury merged 9 commits into
python:mainfrom
colesbury:gh-139103-named-tuple
Feb 6, 2026
Merged

gh-139103: Improve namedtuple scaling in free-threaded build#144332
colesbury merged 9 commits into
python:mainfrom
colesbury:gh-139103-named-tuple

Conversation

@colesbury

@colesburycolesbury commented Jan 29, 2026

Copy link
Copy Markdown
Contributor

Add _Py_type_getattro_stackref, a variant of type attribute lookup that returns _PyStackRef instead of PyObject*. This allows returning deferred references in the free-threaded build, reducing reference count contention when accessing type attributes.

This improves scaling of namedtuple instantiation across multiple threads.

Add `_Py_type_getattro_stackref`, a variant of type attribute lookup
that returns `_PyStackRef` instead of `PyObject*`. This allows returning
deferred references in the free-threaded build, reducing reference count
contention when accessing type attributes.
This significantly improves scaling of namedtuple instantiation across
multiple threads.
Comment threadInclude/internal/pycore_object.h Outdated
@colesbury

Copy link
Copy Markdown
ContributorAuthor

FYI, I think I'm going to try splitting out parts of this into other PRs.

@vstinner

Copy link
Copy Markdown
Member

FYI, I think I'm going to try splitting out parts of this into other PRs.

Thanks, since this PR is quite big :-)

@colesbury
colesbury marked this pull request as ready for review February 3, 2026 18:06
@colesbury
colesbury requested a review from mpageFebruary 3, 2026 18:06
Comment threadObjects/funcobject.c Outdated
staticmethod *sm = (staticmethod *)
PyType_GenericAlloc(&PyStaticMethod_Type, 0);
if (sm != NULL) {
_PyObject_SetDeferredRefcount((PyObject *)sm);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also call it in sm_init()? If not, should we move this _PyObject_SetDeferredRefcount() call to typeobject.c after the two PyStaticMethod_New() calls?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... maybe? We'll need to guard the call to _PyObject_SetDeferredRefcount() because calling it multiple times on the same object will trigger an assertion failure.

I'll update this after your PR is merged

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I merged for classmethod/staticmethod fix in the main branch.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've put the calls to _PyObject_SetDeferredRefcount() in sm_new() and PyStaticMethod_New() so that it's called exactly once during construction.

Comment threadObjects/funcobject.c Outdated
Comment threadObjects/funcobject.c Outdated
colesburyand others added 3 commits February 5, 2026 10:52
Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Victor Stinner <vstinner@python.org>

@vstinnervstinner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. The C changes LGTM.

Comment threadInclude/internal/pycore_function.h Outdated
Co-authored-by: Victor Stinner <vstinner@python.org>
Comment threadObjects/object.c
@colesbury
colesbury merged commit d891b2b into python:mainFeb 6, 2026
71 checks passed
@colesbury
colesbury deleted the gh-139103-named-tuple branch February 6, 2026 14:43
thunder-coding pushed a commit to thunder-coding/cpython that referenced this pull request Feb 15, 2026
…ythongh-144332)
Add `_Py_type_getattro_stackref`, a variant of type attribute lookup
that returns `_PyStackRef` instead of `PyObject*`. This allows returning
deferred references in the free-threaded build, reducing reference count
contention when accessing type attributes.
This significantly improves scaling of namedtuple instantiation across
multiple threads.
* Add blurb
* Rename PyObject_GetAttrStackRef to _PyObject_GetAttrStackRef
* Apply suggestion from @vstinner
Co-authored-by: Victor Stinner <vstinner@python.org>
* Apply suggestion from @vstinner
Co-authored-by: Victor Stinner <vstinner@python.org>
* format
* Update Include/internal/pycore_function.h
Co-authored-by: Victor Stinner <vstinner@python.org>
---------
Co-authored-by: Victor Stinner <vstinner@python.org>
ljfp pushed a commit to ljfp/cpython that referenced this pull request Apr 25, 2026
…ythongh-144332)
Add `_Py_type_getattro_stackref`, a variant of type attribute lookup
that returns `_PyStackRef` instead of `PyObject*`. This allows returning
deferred references in the free-threaded build, reducing reference count
contention when accessing type attributes.
This significantly improves scaling of namedtuple instantiation across
multiple threads.
* Add blurb
* Rename PyObject_GetAttrStackRef to _PyObject_GetAttrStackRef
* Apply suggestion from @vstinner
Co-authored-by: Victor Stinner <vstinner@python.org>
* Apply suggestion from @vstinner
Co-authored-by: Victor Stinner <vstinner@python.org>
* format
* Update Include/internal/pycore_function.h
Co-authored-by: Victor Stinner <vstinner@python.org>
---------
Co-authored-by: Victor Stinner <vstinner@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@colesbury@vstinner@mpage