[Python-Dev] Documenting the Py3k coercion rules (was Re: Getting values stored inside sets)
Nick Coghlan
ncoghlan at gmail.com
Sat Apr 4 07:54:23 CEST 2009
Raymond Hettinger wrote:
>
> [Nick Coghlan]
>> It doesn't quite work the way RDM desribed it - he missed a step.
>
> Thanks for the clarification. We ought to write-out the process
> somewhere in a FAQ.
The closest we currently have to that is the write-up of the coercion
rules in 2.x:
http://docs.python.org/reference/datamodel.html#id5
Unfortunately, that mixes in a lot of CPython specific special cases
along with the old coerce() builtin that obscure the basic behaviour for
__op__ and __rop__ pairs.
Here's an initial stab at a write-up of the coercion rules for Py3k that
is accurate without getting too CPython specific:
"""
Given "a OP b", the coercion sequence is:
1. Try "a.__op__(b)"
2. If "a.__op__" doesn't exist or the call returns NotImplemented, try
"b.__rop__(a)"
3. If "b.__rop__" doesn't exist or the call returns NotImplemented,
raise TypeError identifying "type(a)" and "type(b)" as unsupported
operands for OP
4. If step 1 or 2 is successful, then the result of the call is the
value of the expression
Given "a OP= b" the coercion sequence is:
1. Try "a = a.__iop__(b)"
2. If "a.__iop__" doesn't exist or the call returns not implemented, try
"a = a OP b" using the normal binary coercion rules above
Special cases:
- if "type(b)" is a strict subclass of "type(a)", then "b.__rop__" is
tried before "a.__op__". This allows subclasses to ensure an instance of
the subclass is returned when interacting with instances of the parent
class.
- rich comparisons are associated into __op__/__rop__ pairs as follows:
__eq__/__eq__ (i.e. a == b is considered equivalent to b == a)
__ne__/__ne__ (i.e. a != b is considered equivalent to b != a)
__lt__/__gt__ (i.e. a < b is considered equivalent to b > a)
__le__/__ge__ (i.e. a <= b is considered equivalent to b >= a)
- __rpow__ is never invoked for the 3 argument form of pow(), as the
coercion rules only apply to binary operations. In this case, a
NotImplemented return from the call to __pow__ is converted immediately
into a TypeError.
"""
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
More information about the Python-Dev
mailing list