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-157649: Fix Py_CLEAR()/Py_SETREF() on C++ by vstinner · Pull Request #158070 · python/cpython

Conversation

@vstinner

@vstinner vstinner commented Sep 24, 2026 •
edited by bedevere-app Bot
Loading

Uh oh!

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

Copy link
Copy Markdown
Member

On C++, do not use decltype() in _Py_TYPEOF since it produces invalid code in Py_CLEAR() and Py_SETREF(). Instead, implement Py_CLEAR() and Py_SETREF() using "auto" on C++11 and newer.

Add Py_CLEAR() and Py_SETREF() tests on an array.

  • Issue: Py_CLEAR/Py_SETREF() regression on the main branch with C++: SEGV with simple numpy program #157649

Sorry, something went wrong.

Uh oh!

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

All reactions
@vstinner
pythongh-157649: Fix Py_CLEAR()/Py_SETREF() on C++
d448889
On C++, do not use decltype() in _Py_TYPEOF since it produces invalid
code in Py_CLEAR() and Py_SETREF(). Instead, implement Py_CLEAR() and
Py_SETREF() using "auto" on C++11 and newer.

Add Py_CLEAR() and Py_SETREF() tests on an array.
@bedevere-app bedevere-app Bot mentioned this pull request Sep 24, 2026
Py_CLEAR/Py_SETREF() regression on the main branch with C++: SEGV with simple numpy program #157649
Closed
@bedevere-app bedevere-app Bot added the awaiting core review label Sep 24, 2026
@vstinner vstinner added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Sep 24, 2026
@bedevere-bot

bedevere-bot commented Sep 24, 2026

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @vstinner for commit d448889 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F158070%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

All reactions

Sorry, something went wrong.

Uh oh!

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

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Sep 24, 2026
@vstinner

vstinner commented Sep 24, 2026

Copy link
Copy Markdown
Member Author

cc @da-woods @h-vetinari @chris-eibl @picnixz

All reactions

Sorry, something went wrong.

Uh oh!

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

@h-vetinari

h-vetinari commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

This LGTM, though I'm not very knowledgeable about the macros here.

To contribute something slightly non-trivial in response to your ping, the history of why decltype isn't suitable, resp. that there's no unified infra for this between C & C++, is actually quite fun/tragic. To the best of my understanding (based on public posts, I'm not privy to committee-internal details):

  • Bjarne Stroustrup originally wanted to add typeof to C++ as early as 2002 (see references below)
  • C++11 added decltype, though the rationale is more fully explained in the earlier papers, e.g. N1607 (the last in the series to contain a discussion on typeof)
  • Part of the problem was that C++ - in contrast to C - needed to deal with reference-ness, and whether to preserve or keep it. N1478 etc. argue that consequently, two variants of typeof would be necessary, which they didn't want to do. I can't find a direct quote right now (though P2958 below comes close), but I believe there was also an aspect of not taking typeof away from the C standard, and waiting for WG14 to come up with something.
  • [many years later] typeof finally got added to C23, and its variant for removing all qualifier even got renamed specifically for compatibility with compatibility of C++'s original intent and use in mind
  • typeof & typeof_unqual were then reproposed for C++, and tragically/hilariously died a violent committee death.
  • compiler authors provide relief with __typeof__ that does the right thing everywhere, the end.

Looking at the diff, this provides an idea perhaps, in that the C++ case could be ordered after #ifdef _Py_TYPEOF, which would relegate the auto-based implementation only to those compilers who don't know __typeof__; this would provide a more uniform implementation for the 99% case IMO.

All reactions

Sorry, something went wrong.

Uh oh!

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

chris-eibl
chris-eibl requested changes Sep 24, 2026
View reviewed changes
Comment thread Include/cpython/object.h Resolved

Uh oh!

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

Comment thread Include/pyport.h Resolved

Uh oh!

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

@bedevere-app bedevere-app Bot added awaiting changes and removed awaiting core review labels Sep 24, 2026
@bedevere-app

bedevere-app Bot commented Sep 24, 2026

Copy link
Copy Markdown

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

And if you don't make the requested changes, you will be poked with soft cushions!

All reactions

Sorry, something went wrong.

Uh oh!

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

@chris-eibl

chris-eibl commented Sep 24, 2026

Copy link
Copy Markdown
Member

__typeof__; this would provide a more uniform implementation for the 99% case IMO.

True for gcc and clang but not MSVC. Also, strictly speaking, __typeof__ is not part of standard C++.
Your reorder suggestion would be a more defensive change, because this is how it was used in 3.15, where MSVC always took the memcpy path (except when in C23 mode).

All reactions

Sorry, something went wrong.

Uh oh!

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

@h-vetinari

h-vetinari commented Sep 24, 2026 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Contributor

True for gcc and clang but not MSVC.

MSVC would work itself out via your suggested && !defined(__cplusplus). Then the order would be:

  • #ifdef _Py_TYPEOF (roughly equivalent to "has __typeof__") --> use that
  • #elif defined(__cplusplus) && (__cplusplus >= 201103L || _MSVC_LANG >= 201103L) --> use C++11 auto
  • #else --> use memcpy

I'd prefer this because it keeps C++ out of the default path.

All reactions

Sorry, something went wrong.

Uh oh!

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

@chris-eibl

chris-eibl commented Sep 24, 2026 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Member

Yeah, as said above, that would be the least change in behaviour (and no change wrt gcc and clang) compared to 3.15.

Which means auto would not be used in all C++11 code paths (only for MSVC).

Whether we'd like to unify for C++11 or favor __typeof__ is a decision I am on the fence - IMHO there is no clear win here.

All reactions

Sorry, something went wrong.

Uh oh!

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

@da-woods

da-woods commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

I've run it on the relevant parts of the Cython CI and it fixes what I was hoping that it would fix.

chris-eibl reacted with hooray emoji
All reactions
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

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

vstinner added 4 commits September 28, 2026 15:19
@vstinner
Merge branch 'main' into py_clear_auto_MERGE
a87ee9b
@vstinner
Fix Py_XSETREF()
46fc0b4
@vstinner
Don't use __typeof__() on MSVC for C++
8c8df17
@vstinner
Prefer typeof() over C++ auto
27f1d3e
@vstinner

vstinner commented Sep 28, 2026

Copy link
Copy Markdown
Member Author

Ok, I changed the implementation to use _Py_TYPEOF if available, and only use C++ auto if _Py_TYPEOF is not available. memcpy() fallback is used in the two other implementations are not available (MSVC in C++03 mode?).


Adding tests to test_cext and test_cppext became more and more annoying over time, since these "basic C/C++ extensions" became more complex over time. I merged test_cppext into test_cext (PR #158176) to share most code (init, setup, extension.c), especially extension.c which is now used by C and C++. By the way, I also made a change to check for reference leaks (and I had to fix a test for that!): PR #158227.

MSVC does not support __typeof__ in C++, so I'd guard with !defined(__cplusplus).

Oh ok, fixed. Since _Py_TYPEOF() was not used by default on C++ on my first implementation, this bug was not catched by test_cppext.

I'd adjust Py_XSETREF like Py_SETREF and add a test using it. Currently, it would fail because MSVC does not support typeof in C++, see below.

Ooops, I forgot that Py_XSETREF() as a copy-pasta implementation copied from Py_SETREF(). I added tests and also updated Py_XSETREF() implementation to use C++ auto.

All reactions

Sorry, something went wrong.

Uh oh!

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

@vstinner

vstinner commented Sep 28, 2026

Copy link
Copy Markdown
Member Author

@chris-eibl: Oh, the PR is still red because you requested changes. I addressed your review. Would you mind reviewing the updated PR?

Once GitHub Action CI will pass, I will schedule a buildbot run to run test_cext on buildbots.

chris-eibl 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.

chris-eibl
chris-eibl approved these changes Sep 28, 2026
View reviewed changes
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting changes labels Sep 28, 2026
@vstinner vstinner added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Sep 28, 2026
@bedevere-bot

bedevere-bot commented Sep 28, 2026

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @vstinner for commit 27f1d3e 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F158070%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

All reactions

Sorry, something went wrong.

Uh oh!

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

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Sep 28, 2026
@chris-eibl

chris-eibl commented Sep 28, 2026

Copy link
Copy Markdown
Member

Thanks Victor, I think this is the best we can get with the lowest risk: the gcc / clang basically stays untouched, and for MSVC we should get the typeof branch for C and auto for C++.

memcpy() fallback is used in the two other implementations are not available (MSVC in C++03 mode?).

I think we'll rarely get there, except when not gcc, clang or MSVC.

In case of MSVC for versions >= VS 2017, C++14 is the minimum, there is no /std switch for anything lower than C++14.

Hence I think

cpython/Lib/test/test_cext/__init__.py

Lines 143 to 144 in 869a505

def test_build_cpp03(self):
# In public docs, we say C API is compatible with C++11. However,

should be marked with skipIf like

cpython/Lib/test/test_cext/__init__.py

Lines 149 to 150 in 869a505

@unittest.skipIf(MSVC, "MSVC doesn't support /std:c++11")
def test_build_cpp11(self):

You should currently see a warning for test_build_cpp03 in case of MSVC saying "unsupported option /std:c++03" and basically just doing the same as test_build. Which I think does the same as test_build_cpp14, because /std:c++14 is the default?

All reactions

Sorry, something went wrong.

Uh oh!

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

@vstinner

vstinner commented Sep 28, 2026

Copy link
Copy Markdown
Member Author

If test_build_cpp03 is changed, I would prefer to do in a separated PR.

chris-eibl 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.

@vstinner
Restore #ifdef
9af8d8d
@vstinner
vstinner enabled auto-merge (squash) September 28, 2026 17:32
@vstinner

vstinner commented Sep 28, 2026

Copy link
Copy Markdown
Member Author

Tests passed a wide diversity of buildbots, I enable auto-merge.

test_dtrace fails on s390x, but that's a known and unrelated issue.

All reactions

Sorry, something went wrong.

Uh oh!

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

@vstinner
vstinner merged commit 3330712 into python:main Sep 28, 2026
99 of 102 checks passed

Uh oh!

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

@vstinner
vstinner deleted the py_clear_auto branch September 28, 2026 19:18
@bedevere-app bedevere-app Bot removed the awaiting merge label Sep 28, 2026
@vstinner

vstinner commented Sep 28, 2026

Copy link
Copy Markdown
Member Author

Thanks for reviews! I merged my change.

All reactions

Sorry, something went wrong.

Uh oh!

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

vstinner added a commit that referenced this pull request Oct 10, 2026
@vstinner
[3.15] gh-157649: Fix Py_CLEAR()/Py_SETREF() on C++ (#159143)
7ba9a77
* gh-121647: Fix _Py_TYPEOF() on C++ (#157267)

Using MSVC (on Windows), _Py_TYPEOF() prefers decltype()
over __typeof__() on C++.

Fix also _Py_TYPEOF() usage in Py_CLEAR() and Py_SETREF() macros.
Replace "_Py_TYPEOF(dst)*" with "_Py_TYPEOF(&(dst))". In C++,
"_Py_TYPEOF(dst)*" can fail with a compiler error.

(cherry picked from commit bba99f2)

* gh-157649: Fix Py_CLEAR()/Py_SETREF() on C++ (#158070)

On C++, do not use decltype() in _Py_TYPEOF since it produces invalid
code in Py_CLEAR() and Py_SETREF(). Instead, implement Py_CLEAR(),
Py_SETREF() and Py_XSETREF() using "auto" on C++11 and newer.

Add Py_CLEAR(), Py_SETREF() and Py_XSETREF() tests on an array.

(cherry picked from commit 3330712)
@h-vetinari h-vetinari mentioned this pull request Oct 17, 2026
v0.11.2 conda-forge/jaxlib-feedstock#359
Merged
4 of 5 tasks
@vstinner

vstinner commented Nov 2, 2026

Copy link
Copy Markdown
Member Author

Py_SETREF() macros family is a gift which keeps giving: see issue #161185 about strict aliasing.

All reactions

Sorry, something went wrong.

Uh oh!

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

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

Reviewers

@chris-eibl chris-eibl chris-eibl approved these changes

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

@vstinner @bedevere-bot @h-vetinari @chris-eibl @da-woods
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.