[Python-Dev] Advice on numbers.py implementation of binary mixins. (original) (raw)
Raymond Hettinger python at rcn.com
Fri Jun 13 22:06:52 CEST 2008
- Previous message: [Python-Dev] [Python-3000] [Python-3000-checkins] r64217 - in python/branches/py3k/Lib: bsddb/test/test_associate.py bsddb/test/test_join.py bsddb/test/test_lock.py bsddb/test/test_thread.py idlelib/rpc.py idlelib/run.py socketserver.py test/test_threadedtemp
- Next message: [Python-Dev] Advice on numbers.py implementation of binary mixins.
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
PEP-3141 outlines an approach to writing binary operators to allow the right operand to override the operation if the left operand inherits the operation from the ABC.
Here is my first approximation at how to write them for the Integral mixins:
class Integral(Rational):
def __and__(self, other):
if isinstance(other, (type(self), int, long)): # XXX
return int(self) & int(other)
return NotImplemented
def __rand__(self, other):
if isinstance(other, Integral):
return int(other) & int(self)
return NotImplementedThe question for the group is what to put on the XXX line.
Limit it to type(self). This approach claims the least knowledge about other types and uses their rand methods().
Use type(self), int, and long. This approach says that we know that ints and longs can be reasonably converted to an int; however, it means that any int/long subtype cannot use rand to override the mixin's and.
Emulate the PEP as closely as possible and accomodate subclassing without changing behaviors. This approach is a bit complex:
knowntypes = (set(type(self).__mro__) & set(type(other.__mro__)) - set(type(Integral.__mro__)) | set([int, long])) if isinstance(other, tuple(knowntypes)):
I got this by analyzing the possible paths in an inheritance tree:
class P(Integral): pass class Q(P): pass class R(Q): pass r = R(3) class S(Q): def rand(s,o) ... s = S(6) class T(Integral): def rand(s,o) ... t = T(5)
With r&t, there is no common ancestor below Integral, so we want Integral.and() to return NotImplemented and allow T.rand() to do its thing.
With r&s, both r and s share Q as a common ancenstor. By using the mixin and not overriding and(), Q specifies that and() should mean int(r)&int(s) whenever isinstance(r,Q) and isinstance(s,Q).
Approaches 1 & 2 don't search the mro for shared ancestors below the level of Integral. So, when evaluating r&s, Integral.and() only checks that r is not an instance of S, int or long, and it erroneously returns NotImplemented , leaving s.rand() to take over.
What do you guys think?
Raymond
- Previous message: [Python-Dev] [Python-3000] [Python-3000-checkins] r64217 - in python/branches/py3k/Lib: bsddb/test/test_associate.py bsddb/test/test_join.py bsddb/test/test_lock.py bsddb/test/test_thread.py idlelib/rpc.py idlelib/run.py socketserver.py test/test_threadedtemp
- Next message: [Python-Dev] Advice on numbers.py implementation of binary mixins.
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]