O03, dunders and the slots behind them - #133
Merged
Merged
Conversation
O02 walked past the seventy odd function pointer fields in the middle of the type struct. This lesson is about those and about the table of ninety four rows that connects them to the names you actually write. The table gets walked both ways. Backwards by add_operators when a C type is made ready, which is where int.__add__ comes from. Forwards by fixup_slot_dispatchers when you write a class, which puts a generic dispatcher in the slot that looks your function up on the type every time it runs. Four things people learn as separate rules come out of that: a dunder set on an instance is ignored, one assigned to a class takes effect at once and on every subclass, __getitem__ alone makes a class iterable because it fills sq_item, and __eq__ without __hash__ leaves a literal None in the class dict, put there by two mechanisms meeting. Two glossary terms: slot and slot wrapper. Six diagrams. Every cell prints the same thing on 3.14, on 3.15 and in the browser.
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.
O02 opened the type struct and walked straight past the interesting part. In the middle of it are about seventy fields that are function pointers, and the interpreter reads them directly:
repr(x)is a load out ofPy_TYPE(x)->tp_reprand an indirect call.But nobody writes
tp_repr. You write__repr__. The thing in between is a table of ninety four rows in typeobject.c, and this lesson is about that table being walked in both directions.What the lesson covers:
add_operatorsturns every filled slot on a C type into a slot wrapper in the class dict, which is whereint.__add__andobject.__repr__come from, andtype(int.__add__).__name__is how you tell one from an ordinary methodfixup_slot_dispatchersputs a generic dispatcher into every slot whose dunder you defined, and that dispatcher looks the name up on the type each time it runs__repr__set on an instance is ignored: it really is in the instance dict, you can call it by name, andrepr()goes through the slot and never looks theretype.__setattr__callsupdate_slot__len__fillsmp_lengthandsq_length, which is why a class with only a length gets truthiness__getitem__fillsmp_subscriptandsq_item, andsq_itemis the old sequence protocol, so a class with one__getitem__and nothing else is iterable and supportsin__add__and__radd__sharenb_add, so the dispatcher has the decision written into it: the reflected call goes first only if the right hand type is a subclass and defines the method itself rather than inheriting it__eq__without__hash__is not a rule, it isoverrides_hashstopping the slot being inherited and thentype_ready_set_hashwriting a literalNoneinto the class dict, which you can look atEverything is cited against
v3.15.0rc1:slotdefsand the comment above it,TPSLOT,SLOT0,SLOT1BINFULL,add_operators,fixup_slot_dispatchers,update_slot,overrides_hashandtype_ready_set_hash.Six diagrams. Every cell prints exactly the same thing on 3.14, on 3.15 and in the browser probe, so nothing in this one needed a version note. The probe is at 31 lessons and 328 cells.
Two glossary terms went in: slot and slot wrapper. GLOSSARY.md is at 113.
Part of #23.