experimental-inspect: give slot-wrapper trailing arguments their None default - #6363
Draft
jonasdedden wants to merge 2 commits into
Draft
experimental-inspect: give slot-wrapper trailing arguments their None default#6363jonasdedden wants to merge 2 commits into
experimental-inspect: give slot-wrapper trailing arguments their None default#6363jonasdedden wants to merge 2 commits into
Conversation
jonasdedden
marked this pull request as draft
August 28, 2026 10:23
jonasdedden
force-pushed
the
introspection-slot-arg-defaults
branch
from
August 28, 2026 10:33
b774423 to
0769c4f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What was wrong
PyMethod::parsemarks a protocol method's parameters positional-only but never records that CPython's slot wrappers substituteNonefor an omitted trailing argument. So__pow__(&self, other, modulo: Option<&Self>)was introspected asdef __pow__(self, other: object, modulo: object, /)while the runtime wrapper advertises($self, value, mod=None, /). Same defect for__get__, whose wrapper advertises($self, instance, owner=None, /).The fix
The fact lives on the slot definition, next to the arity it belongs with, rather than in a name match.
SlotDefandSlotFragmentDefgain anoptional_trailing_args: usize, set through the existing const builder chain:PyMethodProtoKind::optional_trailing_argsdelegates to whichever definition applies, andPyMethod::parsepasses the count toFunctionSignature::default_trailing_parameters_to_none(count)beside the existingmake_all_parameters_positional_onlycall. Codegen destructuring sites bind the new field as_, so it stays introspection-only and a future field still forces a decision.__rpow__is included because its wrapper carries the samemod=None.Why a plain count, and why always
NoneThe three affected methods are not an arbitrary selection. Scanning every builtin type for slot wrappers whose
__text_signature__carries a default yields exactly three, and all three default toNone:A non-
Nonesentinel cannot arise. An omitted argument reaches a slot wrapper asNULLat the C level and the wrapper substitutesNone. There is no channel for any other default, so a count is sufficient and not lossy. If Python ever adds a slot wrapper with a different default, the field becomes&'static [Option<&'static str>]and only the three call sites change.Left out
__ipow__. PyO3 gives it a third parameter, but CPython'sIBSLOTentry advertises($self, value, /)andslot_nb_inplace_powerdrops the modulo, so aNonedefault there would not match the runtime. Confirmed theIBSLOTshape againstlist.__iadd__.__text_signature__.