[Twisted-Python] Raising TypeError in rich comparison methods
Hello everyone, I want to discuss if and when to raise TypeError from Python rich comparison methods. I'm working on a SerialNumber class which represents an RFC1982 serial number value. See https://twistedmatrix.com/trac/ticket/6672 SerialNumber has rich comparison methods to allow it to be compared with other SerialNumber instances. But what should be the behaviour when a SerialNumber is compared to an instance of some foreign type? In https://twistedmatrix.com/trac/ticket/6672?replyto=6#comment:4 JP suggested returning NotImplemented.
The rich comparison methods should probably type check their argument and return NotImplemented if it is not a SNA. This way the TypeError-generating logic provided by the runtime will be invoked instead of an implementation-dependent AttributeError.
I agree there should be type checking here, but after doing some research, I think I prefer to raise an explicit TypeError. Here's why. In Python2, returning NotImplemented from __lt__ always seems to return True and False from __gt__. Python3 reacts more sensibly and raises TypeError. I worry that this may cause Python2 users to think that an L{int} and a L{SerialNumber} can be reliably compared. They can't. I think the "return True / False" behaviour is due to a fallback comparison mechanism in Python. * http://stackoverflow.com/questions/18516827/why-does-0-evaluate-to-true-in-p... Python 2 is more stubborn and when NotImplemented is returned or no hooks have been implemented, the C code ends up in the default_3way_compare() C function, So I've decided to explicitly raise TypeError instead. This makes it clear that you can only compare L{SerialNumber} with L{SerialNumber}; in both Python2 and Python3. It also means I only have to test for the "raise TypeError" behaviour. Does that make sense? Thanks in advance for your feedback. -RichardW.
participants (1)
-
Richard Wall