Are steps 1 and the first part of step 3 the same? If so, why does the same step appear twice?
Step 1 requires both __get__ and __set__ (although in fact it is either running __set__ or __delete__ , as well as __get__ ). Step 3 is performed unconditionally if the attribute is not found using steps 1 or 2.
They both occur "when the name is found in C (or in one of the Cs ancestor classes) as the name of the overriding descriptor v"?
No. The "redefinition descriptor" starts step 1; another kind of descriptor or non-descriptor will be considered only in step 3. (Python docs do not use the term “overriding descriptor”, they refer to a descriptor with __set__ or __delete__ as a “data descriptor”, and if the data descriptor has __get__ , __get__ will take precedence over an object found in a dict instance.)
source share