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-149044: Implement PEP 820 – PySlot: Unified slot system for the C API by encukou · Pull Request #149055 · python/cpython

Conversation

@encukou

@encukou encukou commented Apr 27, 2026 •
edited by github-actions Bot
Loading

Uh oh!

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

Copy link
Copy Markdown
Member
  • Issue: Implement PEP 820 – PySlot: Unified slot system for the C API #149044

📚 Documentation preview 📚: https://cpython-previews--149055.org.readthedocs.build/

Sorry, something went wrong.

Uh oh!

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

All reactions
encukou added 30 commits April 24, 2026 13:40
@encukou
Add header for internal slot iterator API
3b13a93
@encukou
Add public API and a generated list of slots
0396743
@encukou
Add slot iterator implementation & use it for types
6da3bb1
@encukou
Unify duplicate & NULL handling
a8e018f
@encukou
Simplify slot handling in typeobject.c
b96acd4
@encukou
Port PyType_GetSlot; remove typeslots.inc
f3a6d7c
@encukou
Port module creation
5f13d2e
@encukou
Simplify internal API
4660f2f
@encukou
Switch modexport over to new slots
6c29000
@encukou
Fix up NULL handling
dfb342c
@encukou
Move PyType_FromMetaclass to slots
110464d
@encukou
PyType_FromSlots
6fb0046
@encukou
slots.csv update
866eafc
@encukou
squash up
325f1a8
@encukou
Put slot info in generated switches
e22e3af
@encukou
Handle PyType_Spec specially
fea6e21
@encukou
Clean up the generator
a89405c
@encukou
Remove slots.csv
114a4fa
@encukou
Prettier generation
8dc5d88
@encukou
Tighten module creation
796dd75
@encukou
Fix math
b942f10
@encukou
Remove PySlot_HAS_FALLBACK
6a53b4c
@encukou
Bump version
f352558
@encukou
Better comments
bd78c06
@encukou
Limit deprecations to new-style slots
181df86
@encukou
Start on docs
644ae46
@encukou
Require some slots to be static
0433d1e
@encukou
Add to Stable ABI
b3131a3
@encukou
blurb, versionadded, whatsnew
b35230d
@encukou
Don't deprecate mixing the bases slots/args
ae0ea29
@bedevere-app bedevere-app Bot added the awaiting core review label Apr 28, 2026
ZeroIntensity
ZeroIntensity reviewed Apr 28, 2026
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.

Documentation looks pretty good. I haven't looked at all of the C code yet.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Doc/c-api/slots.rst Resolved

Uh oh!

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

Comment thread Doc/c-api/slots.rst Resolved

Uh oh!

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

@AlexWaygood
AlexWaygood removed their request for review April 28, 2026 14:06
@brettcannon
brettcannon removed their request for review April 28, 2026 16:44
encukou
encukou commented Apr 30, 2026
View reviewed changes
Comment thread Doc/c-api/slots.rst Resolved

Uh oh!

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

encukou and others added 2 commits April 30, 2026 12:07
@encukou @ZeroIntensity
Apply suggestions from code review
986b24e
Co-authored-by: Peter Bierma <[email protected]>
@encukou
Merge branch 'main' into slots-pep820-mrg
3404bba
@read-the-docs-community

read-the-docs-community Bot commented Apr 30, 2026 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #32533679 | 📁 Comparing 1d09dac against main (a386a52)

  🔍 Preview build  

65 files changed · + 2 added · ± 63 modified

+ Added

  • c-api/sentinel.html
  • c-api/slots.html

± Modified

  • glossary.html
  • c-api/concrete.html
  • c-api/extension-modules.html
  • c-api/index.html
  • c-api/lifecycle.html
  • c-api/module.html
  • c-api/perfmaps.html
  • c-api/stable.html
  • c-api/synchronization.html
  • c-api/type.html
  • and 53 more...
All reactions

Sorry, something went wrong.

Uh oh!

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

@ngoldbaum ngoldbaum mentioned this pull request May 2, 2026
Supporting 3.15.0b1 and finishing off support for the 3.15 ABI PyO3/pyo3#6012
Closed
ngoldbaum
ngoldbaum reviewed May 3, 2026
View reviewed changes

@ngoldbaum ngoldbaum 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.

I wrote FFI bindings for this PR for PyO3 this afternoon and spotted several minor issues.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Include/slots.h
Comment on lines +48 to +52
#define PySlot_PTR(NAME, VALUE) \
{(NAME), PySlot_INTPTR, {0}, {(void*)(VALUE)}}

#define PySlot_PTR_STATIC(NAME, VALUE) \
{(NAME), PySlot_INTPTR | PySlot_STATIC, {0}, {(void*)(VALUE)}}

@ngoldbaum ngoldbaum May 3, 2026 •
edited
Loading

Uh oh!

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

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.

Can you spell these last two with the explicit names of the struct fields like the ones above? Also while you're touching this code, IMO these two definitions should come before PySlot_END.

Sorry, something went wrong.

Uh oh!

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

All reactions

@encukou encukou May 4, 2026

Copy link
Copy Markdown
Member Author

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.

These macros are for code compatible with C++11 and below, which doesn't support designated initializers (that is, the explicit names).

So, both style issues are intentional :) I added a comment.

Sorry, something went wrong.

Uh oh!

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

ngoldbaum reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
Comment thread Include/slots.h Resolved

Uh oh!

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

Comment thread Include/slots.h
#define PySlot_STATIC 0x02
#define PySlot_INTPTR 0x04

#define Py_slot_invalid 0xffff

@ngoldbaum ngoldbaum May 3, 2026

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.

for consistency should this be called Py_slot_INVALID maybe?

Sorry, something went wrong.

Uh oh!

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

All reactions

@encukou encukou May 4, 2026

Copy link
Copy Markdown
Member Author

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.

That would be consistent with the wrong thing. Slot IDs are named Py_tp_repr, Py_mod_exec, etc. Flags are a new thing, so they follow the current style guide: mixed prefix + uppercase.

Sorry, something went wrong.

Uh oh!

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

ngoldbaum reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
Comment thread Include/slots_generated.h
#define _Py_SLOT_COMPAT_VALUE(OLD, NEW) OLD
#endif

#define Py_slot_end 0

@ngoldbaum ngoldbaum May 3, 2026

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.

Maybe worth adding a comment above these that they're all u16 values?

Sorry, something went wrong.

Uh oh!

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

All reactions

@encukou encukou May 4, 2026

Copy link
Copy Markdown
Member Author

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.

In C, the preprocessor macros are just numbers :)
In PyType_Slot, these values are used as int.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Include/object.h Resolved

Uh oh!

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

Comment thread Include/slots_generated.h
#define Py_tp_finalize 80
#define Py_am_send 81
#define Py_tp_vectorcall 82
#define Py_tp_token 83

@ngoldbaum ngoldbaum May 3, 2026

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.

Everything through here is duplicated with typeslots.h. Was that intentional? It probably makes sense for there to be only one source of truth for these constants.

Sorry, something went wrong.

Uh oh!

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

All reactions

@encukou encukou May 4, 2026

Copy link
Copy Markdown
Member Author

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.

Thanks for the catch! I seem to have dropped the commit that removes the unused file.

Sorry, something went wrong.

Uh oh!

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

All reactions
ngoldbaum
ngoldbaum reviewed May 4, 2026
View reviewed changes
Comment thread Include/slots.h
#ifndef _Py_HAVE_SLOTS_H
#define _Py_HAVE_SLOTS_H

typedef void (*_Py_funcptr_t)(void);

@ngoldbaum ngoldbaum May 4, 2026

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.

PyO3 needs to wrap this type directly so you might as well give this a public non-underscored name.

Sorry, something went wrong.

Uh oh!

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

All reactions

@encukou encukou May 4, 2026

Copy link
Copy Markdown
Member Author

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.

Can PyO3 use the underlying type, or better yet, some “generic C function pointer” type?

Sorry, something went wrong.

Uh oh!

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

All reactions

@ngoldbaum ngoldbaum May 4, 2026

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.

Unfortunately no, because Rust doesn't let you cast between function pointer types without using unsafe and std::mem::transmute. That said, in my second draft of this, I isolated the unsafety into a PySlot_FUNC rust macro that hides the wrapped function pointer, so I take back my comment from last night.

Sorry, something went wrong.

Uh oh!

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

encukou reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@encukou encukou May 4, 2026

Copy link
Copy Markdown
Member Author

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.

Keep in mind this is not the correct function type, just a function type. At this level, unsafe transmuation is exactly what you need in Rust.
(A safer layer on top of the ABI would need to have separate C-specific and C++-specific variants, and presumably a Rust-specific one as well. I didn't get that into 3.15.)

Sorry, something went wrong.

Uh oh!

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

All reactions
encukou added 2 commits May 4, 2026 08:43
@encukou
Merge in the main branch
e21eb07
@encukou
Address review comments
bef20e9
@encukou

encukou commented May 4, 2026

Copy link
Copy Markdown
Member Author

I intend to merge this today (or early tomorrow) to get it in 3.15, as postponing to 3.16 would be very inconvenient. Beta is for fixing features (or removing, if this turns out to be a bad idea after all).

hugovk 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.

@encukou encukou mentioned this pull request May 4, 2026
gh-149101: Implement PEP 788 #149116
Merged
ZeroIntensity
ZeroIntensity approved these changes May 4, 2026
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.

I think this is in a mergeable state. I read through all of the PEP, documentation, and code, and I couldn't find any glaring issues.

I left a number of non-blocking questions/comments; feel free to ignore them for now and address them after the beta freeze.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Doc/c-api/slots.rst Resolved

Uh oh!

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

Comment thread Include/internal/pycore_slots.h Resolved

Uh oh!

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

Comment thread Include/internal/pycore_slots.h Resolved

Uh oh!

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

Comment thread Include/slots.h Resolved

Uh oh!

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

Comment thread Lib/test/test_capi/test_misc.py
Comment on lines 925 to 929
self.assertRaisesRegex(
SystemError,
"Py_tp_bases is not a tuple",
TypeError,
"metaclass conflict",
_testcapi.create_heapctype_with_none_bases_slot
)

@ZeroIntensity ZeroIntensity May 4, 2026

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.

Hmm, this seems like a downgrade in terms of the error message. I don't see a change to create_heapctype_with_none_bases_slot in this PR, so is there a reason the error changed?

Sorry, something went wrong.

Uh oh!

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

encukou reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@encukou encukou May 4, 2026

Copy link
Copy Markdown
Member Author

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.

Yeah, that's a side effect from merging Py_tp_base & Py_tp_bases -- the latter strictly required a tuple of types, so it had this message.
This is a silly restriction. I'll document lifting it.

Sorry, something went wrong.

Uh oh!

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

All reactions

@encukou encukou May 4, 2026

Copy link
Copy Markdown
Member Author

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.

(And I'll get SC permission to update the PEP, or revert this.)

Sorry, something went wrong.

Uh oh!

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

ZeroIntensity reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@encukou encukou Jun 10, 2026

Copy link
Copy Markdown
Member Author

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.

Turns out the PEP already specifies merging Py_tp_base & Py_tp_bases. Fix in #151252

Sorry, something went wrong.

Uh oh!

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

ZeroIntensity reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
Comment thread Objects/moduleobject.c Resolved

Uh oh!

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

Comment thread Objects/moduleobject.c
Comment on lines +794 to 796
}
break;
}

@ZeroIntensity ZeroIntensity May 4, 2026

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.

What happens if there's a slot other than Py_slot_invalid or Py_mod_exec here? Does _PySlotIterator_Next somehow handle that ahead-of-time?

Sorry, something went wrong.

Uh oh!

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

All reactions

@encukou encukou May 4, 2026

Copy link
Copy Markdown
Member Author

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.

This is PyModule_ExecDef; it ignores slots other than Py_mod_exec.

Py_slot_invalid is the error indicator here (i.e. an exception was set in _PySlotIterator_Next) -- not the standard error API but nicer than the alternatives I tried.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Objects/typeobject.c
Comment on lines +5403 to 5405
memcpy(tp_doc, it.current.sl_ptr, len);
}
break;

@ZeroIntensity ZeroIntensity May 4, 2026

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.

Same question here -- do we want a default: case for debugging?

Sorry, something went wrong.

Uh oh!

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

All reactions

@encukou encukou May 4, 2026

Copy link
Copy Markdown
Member Author

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.

This is the first pass, most slots (especially the function pointers) are handled in the second pass.

_PySlotIterator_Next handles unknown slots, and ones that don't apply to types -- it sets an exception and reports Py_slot_invalid.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Tools/c-analyzer/c_common/scriptutil.py Resolved

Uh oh!

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

Comment thread Include/internal/pycore_slots.h Outdated
_PySlot_KIND slot_struct_kind;
} _PySlotIterator_state;

#define SEEN_ENTRY_BITS (8 * sizeof(unsigned int))

@ZeroIntensity ZeroIntensity May 4, 2026

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.

It doesn't seem like this is used outside slots.c. I think that it would make more sense to move it there, but if you'd really like to keep it in the header, let's be consistent and give this a _Py prefix.

Sorry, something went wrong.

Uh oh!

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

encukou reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting core review labels May 4, 2026
encukou and others added 5 commits May 4, 2026 22:58
@encukou @ZeroIntensity
Apply suggestions from code review
018ce8b
Co-authored-by: Peter Bierma <[email protected]>
Co-authored-by: Petr Viktorin <[email protected]>
@encukou
Prefix a private constant
6c9726a
@encukou
Merge in the main branch
ca86080
@encukou
Doc change in Py_tp_bases
a67116e
@encukou
Fix badly formatted suggestion
1d09dac
@encukou encukou added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label May 4, 2026
@encukou
Merge in the main branch
06b2c3d
@encukou
encukou merged commit 508b498 into python:main May 5, 2026
93 of 103 checks passed

Uh oh!

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

@bedevere-app bedevere-app Bot removed the awaiting merge label May 5, 2026
@encukou
encukou deleted the slots-pep820-mrg branch May 5, 2026 07:18
@chris-eibl chris-eibl mentioned this pull request May 7, 2026
gh-148690: Build Windows freethreaded binaries into separate directory and include python3t.dll on GIL-enabled #149218
Merged
@encukou encukou mentioned this pull request Jun 10, 2026
gh-149044: Improve Py_tp_base[s] docs & error message for non-type bases #151252
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@ngoldbaum ngoldbaum ngoldbaum left review comments
@ZeroIntensity ZeroIntensity ZeroIntensity approved these changes
@markshannon markshannon Awaiting requested review from markshannon markshannon is a code owner
@ericsnowcurrently ericsnowcurrently Awaiting requested review from ericsnowcurrently ericsnowcurrently is a code owner
@ncoghlan ncoghlan Awaiting requested review from ncoghlan ncoghlan is a code owner
@warsaw warsaw Awaiting requested review from warsaw warsaw is a code owner
@FFY00 FFY00 Awaiting requested review from FFY00 FFY00 is a code owner
@kumaraditya303 kumaraditya303 Awaiting requested review from kumaraditya303 kumaraditya303 is a code owner
@AA-Turner AA-Turner Awaiting requested review from AA-Turner AA-Turner is a code owner
@erlend-aasland erlend-aasland Awaiting requested review from erlend-aasland erlend-aasland is a code owner
@emmatyping emmatyping Awaiting requested review from emmatyping emmatyping is a code owner
@corona10 corona10 Awaiting requested review from corona10 corona10 is a code owner
@hugovk hugovk Awaiting requested review from hugovk hugovk is a code owner

Uh oh!

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

Assignees

No one assigned

Labels

🔨 test-with-buildbots Test PR w/ buildbots; report in status section

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.

4 participants

@encukou @bedevere-bot @ngoldbaum @ZeroIntensity
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.