GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GH-140061: Use _PyObject_IsUniquelyReferenced to check if object is uniquely referenced by sergey-miryanov · Pull Request #140062 · python/cpython

Conversation

@sergey-miryanov

@sergey-miryanov sergey-miryanov commented Oct 13, 2025 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

There are a lot of places where Py_REFCNT(..)==1 used. IIUC it is not correct for no-gil version.

  • Issue: Use _PyObject_IsUniquelyReferenced instead of Py_REFCNT(x) == 1 for free-threaded compatibility #140061

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@sergey-miryanov
Use _PyObject_IsUniquelyReferenced to check if object is uniquely ref…
311f629
…erenced
@sergey-miryanov
sergey-miryanov requested review from markshannon, methane and rhettinger as code owners October 13, 2025 19:48
@bedevere-app bedevere-app Bot added the awaiting review label Oct 13, 2025
@bedevere-app bedevere-app Bot mentioned this pull request Oct 13, 2025
Use _PyObject_IsUniquelyReferenced instead of Py_REFCNT(x) == 1 for free-threaded compatibility #140061
Closed
@sergey-miryanov

sergey-miryanov commented Oct 13, 2025

Copy link
Copy Markdown
Contributor Author

I think it should skip news, but not sure about backporting.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@sergey-miryanov
Fix build on linux
d381a91
@picnixz picnixz added the skip news label Oct 13, 2025
sergey-miryanov added 2 commits October 14, 2025 10:53
@sergey-miryanov
Return Py_REFCNT to test_weakref_capi
d416ac6
@sergey-miryanov
Fix warning in ensure_shared_on_resize
45593e8
@ZeroIntensity ZeroIntensity removed the skip news label Oct 14, 2025
@ZeroIntensity

ZeroIntensity commented Oct 14, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

skip news isn't right -- Py_REFCNT(op) == 1 is an actual bug on the free-threaded build (and sometimes the GILful build), at least when using it for optimizations.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ZeroIntensity
ZeroIntensity reviewed Oct 14, 2025
View reviewed changes

@ZeroIntensity ZeroIntensity left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

When the reference is owned by the eval loop, we need to use PyUnstable_Object_IsUniqueReferencedTemporary instead. I think there are a few cases of that here.

cc @colesbury

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@colesbury
colesbury self-requested a review October 14, 2025 15:59
colesbury
colesbury reviewed Oct 14, 2025
View reviewed changes

@colesbury colesbury left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

  • You need to be careful about changing assert(), especially when the code paths can be called by extensions.
  • There are a number of conditions like Py_REFCNT(result) > 1 that need to be changed, such as in itertooslmodule.c

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Modules/_functoolsmodule.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/_testcapi/object.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/_testcapi/object.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Objects/dictobject.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Objects/unicodeobject.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Objects/longobject.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Objects/longobject.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

colesbury
colesbury reviewed Oct 14, 2025
View reviewed changes
Comment thread Objects/listobject.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

@sergey-miryanov
sergey-miryanov marked this pull request as draft October 14, 2025 18:39
@bedevere-app bedevere-app Bot removed the awaiting review label Oct 14, 2025
sergey-miryanov added 7 commits October 14, 2025 23:40
@sergey-miryanov
Address review suggestions
2989918
@sergey-miryanov
Revert for asserts
d3b0e31
@sergey-miryanov
Revert for ctypes
375bf2c
@sergey-miryanov
Fix functools
86079c4
@sergey-miryanov
Fix Py_REFCNT > 1
b8b54c7
@sergey-miryanov
Fix compilation
307be2c
@sergey-miryanov
Add news entry
83f4b84
@sergey-miryanov

sergey-miryanov commented Oct 14, 2025

Copy link
Copy Markdown
Contributor Author

@ZeroIntensity @colesbury Thanks for review! I have fixed your suggestions, but it fails in TSAN(free-threading). Can you take a look?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ZeroIntensity

ZeroIntensity commented Oct 15, 2025

Copy link
Copy Markdown
Member

It seems that me and Kumar broke that earlier (see #140138), sorry! You can ignore it for now and we'll rebase this once we get it fixed on main.

sergey-miryanov reacted with heart emoji
All reactions
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ZeroIntensity
Merge branch 'main' into 140061-fix-checking-object-uniq-ref
7074ae0
@sergey-miryanov

sergey-miryanov commented Oct 15, 2025

Copy link
Copy Markdown
Contributor Author

@ZeroIntensity Thanks!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner

vstinner commented Oct 15, 2025

Copy link
Copy Markdown
Member

Is this PR ready for a review?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@sergey-miryanov

sergey-miryanov commented Oct 15, 2025

Copy link
Copy Markdown
Contributor Author

@vstinner Yes, it is ready to review. If @colesbury don't have any comments, of course.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner
vstinner marked this pull request as ready for review October 15, 2025 12:33
@bedevere-app bedevere-app Bot added the awaiting review label Oct 15, 2025
@vstinner

vstinner commented Oct 15, 2025

Copy link
Copy Markdown
Member

Ok, I click on [Ready for review] button in this case :-)

sergey-miryanov reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@sergey-miryanov

sergey-miryanov commented Oct 15, 2025

Copy link
Copy Markdown
Contributor Author

Ough, I forgot that I turned it to draft :(

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner

vstinner commented Oct 15, 2025

Copy link
Copy Markdown
Member

Remaining code using Py_REFCNT() with 1:

$ git grep 'Py_REFCNT.*\(==\|<\|<=\|>\|>=\) *1'
Doc/c-api/object.rst:   :c:expr:`Py_REFCNT(op) == 1`.
Doc/c-api/object.rst:   is only used by this thread. :c:expr:`Py_REFCNT(op) == 1` is **not**
Doc/whatsnew/3.14.rst:  a replacement for ``Py_REFCNT(op) == 1`` on :term:`free threaded
Include/internal/pycore_object.h:    return Py_REFCNT(ob) == 1;
Modules/_ctypes/_ctypes.c:   assert (Py_REFCNT(obj) == 1);
Modules/_functoolsmodule.c:            assert(Py_REFCNT(args) == 1);
Modules/_io/bytesio.c:  * Py_REFCNT(buf) == 1, exports == 0.
Modules/_io/bytesio.c:  * Py_REFCNT(buf) > 1.  exports == 0,
Modules/_io/bytesio.c:  * exports > 0.  Py_REFCNT(buf) == 1, any modifications are forbidden.
Modules/_testcapi/object.c:    assert(Py_REFCNT(obj) == 1);
Modules/_testcapi/object.c:    assert(Py_REFCNT(obj) == 1);
Modules/_testcapi/object.c:        assert(Py_REFCNT(obj) == 1); \
Modules/_testcapimodule.c:    assert(Py_REFCNT(obj) == 1);
Modules/itertoolsmodule.c:        assert (npools==0 || Py_REFCNT(result) == 1);
Modules/itertoolsmodule.c:        assert(r == 0 || Py_REFCNT(result) == 1);
Modules/itertoolsmodule.c:        assert(r == 0 || Py_REFCNT(result) == 1);
Modules/itertoolsmodule.c:        assert(r == 0 || Py_REFCNT(result) == 1);
Objects/listobject.c:    assert(Py_REFCNT(self) == 1 || PyMutex_IsLocked(&_PyObject_CAST(self)->ob_mutex));
Objects/longobject.c:                assert(Py_REFCNT(z) == 1);
Objects/longobject.c:                assert(_PyLong_IsZero(z) || Py_REFCNT(z) == 1);
Objects/longobject.c:        assert(Py_REFCNT(z) == 1);
Objects/longobject.c:    assert(Py_REFCNT(obj) == 1);
Objects/longobject.c:    assert(Py_REFCNT(obj) == 1);
Objects/object.c:    CHECK(Py_REFCNT(op) >= 1);
Objects/object.c:    _PyObject_ASSERT(name, Py_REFCNT(name) >= 1);
Objects/setobject.c:    assert(Py_REFCNT(so) == 1);
Objects/typeobject.c:    CHECK(Py_REFCNT(type) >= 1);
Objects/unicodeobject.c:    assert(Py_REFCNT(unicode) == 1);
Objects/unicodeobject.c:            assert(Py_REFCNT(unicode) == 1);
Python/ceval.c:    assert(Py_REFCNT(locals) > 1);
Python/gc_free_threading.c:                _PyObject_ASSERT(op, Py_REFCNT(op) > 1);

There are documentation and assertions. Assertions should continue to use Py_REFCNT(), right?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

vstinner
vstinner approved these changes Oct 15, 2025
View reviewed changes

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

LGTM

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Objects/longobject.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread Modules/_elementtree.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting review labels Oct 15, 2025
@sergey-miryanov

sergey-miryanov commented Oct 15, 2025

Copy link
Copy Markdown
Contributor Author

Assertions should continue to use Py_REFCNT(), right?

As I understand @colesbury - yes.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@sergey-miryanov @vstinner
Apply suggestions from code review
1b2193f
Co-authored-by: Victor Stinner <[email protected]>
@colesbury colesbury added the needs backport to 3.14 bugs and security fixes label Oct 15, 2025
colesbury
colesbury approved these changes Oct 15, 2025
View reviewed changes
@colesbury

colesbury commented Oct 15, 2025

Copy link
Copy Markdown
Contributor

Thanks @sergey-miryanov!

efimov-mikhail reacted with hooray emoji sergey-miryanov reacted with heart emoji
All reactions
  • 🎉 1 reaction
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@colesbury
colesbury merged commit 32c2649 into python:main Oct 15, 2025
4 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@miss-islington-app

miss-islington-app Bot commented Oct 15, 2025

Copy link
Copy Markdown

Thanks @sergey-miryanov for the PR, and @colesbury for merging it 🌮🎉.. I'm working now to backport this PR to: 3.14.
🐍🍒⛏🤖

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting merge label Oct 15, 2025
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Oct 15, 2025
@sergey-miryanov @miss-islington
pythongh-140061: Use _PyObject_IsUniquelyReferenced() to check if o…
2b285c1
…bjects are uniquely referenced (pythongh-140062)

The previous `Py_REFCNT(x) == 1` checks can have data races in the free
threaded build. `_PyObject_IsUniquelyReferenced(x)` is a more conservative
check that is safe in the free threaded build and is identical to
`Py_REFCNT(x) == 1` in the default GIL-enabled build.
(cherry picked from commit 32c2649)

Co-authored-by: Sergey Miryanov <[email protected]>
@bedevere-app

bedevere-app Bot commented Oct 15, 2025

Copy link
Copy Markdown

GH-140157 is a backport of this pull request to the 3.14 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.14 bugs and security fixes label Oct 15, 2025
colesbury pushed a commit that referenced this pull request Oct 15, 2025
@miss-islington @sergey-miryanov
[3.14] gh-140061: Use _PyObject_IsUniquelyReferenced() to check if …
045e349
…objects are uniquely referenced (gh-140062) (gh-140157)

The previous `Py_REFCNT(x) == 1` checks can have data races in the free
threaded build. `_PyObject_IsUniquelyReferenced(x)` is a more conservative
check that is safe in the free threaded build and is identical to
`Py_REFCNT(x) == 1` in the default GIL-enabled build.
(cherry picked from commit 32c2649)

Co-authored-by: Sergey Miryanov <[email protected]>
@sergey-miryanov

sergey-miryanov commented Oct 15, 2025

Copy link
Copy Markdown
Contributor Author

Thanks everyone for review!

vstinner reacted with hooray emoji
All reactions
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

StanFromIreland pushed a commit to StanFromIreland/cpython that referenced this pull request Dec 6, 2025
@sergey-miryanov @StanFromIreland
pythongh-140061: Use _PyObject_IsUniquelyReferenced() to check if o…
f4baa5c
…bjects are uniquely referenced (pythongh-140062)

The previous `Py_REFCNT(x) == 1` checks can have data races in the free
threaded build. `_PyObject_IsUniquelyReferenced(x)` is a more conservative
check that is safe in the free threaded build and is identical to
`Py_REFCNT(x) == 1` in the default GIL-enabled build.
@cmaloney cmaloney mentioned this pull request Sep 12, 2026
gh-156995: Add caution around API behavior change #157292
Open
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@ZeroIntensity ZeroIntensity ZeroIntensity left review comments
@vstinner vstinner vstinner approved these changes
@colesbury colesbury colesbury approved these changes
@rhettinger rhettinger Awaiting requested review from rhettinger rhettinger is a code owner
@methane methane Awaiting requested review from methane methane is a code owner
@markshannon markshannon Awaiting requested review from markshannon markshannon is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@sergey-miryanov @ZeroIntensity @vstinner @colesbury @picnixz
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.