[Python-Dev] python 3 niggle: None < 1 raises TypeError

MRAB python at mrabarnett.plus.com
Fri Feb 14 18:55:46 CET 2014


On 2014-02-14 08:04, Chris Withers wrote:
> Hi All,
>
> Sending this to python-dev as I'm wondering if this was considered when
> the choice to have objects of different types raise a TypeError when
> ordered...
>
> So, the concrete I case I have is implementing stable ordering for the
> python Range objects that psycopg2 uses. These have 3 attributes that
> can either be None or, for sake of argument, a numeric value.
>
> To implement __lt__ in Python 2, I could do:
>
>       def __lt__(self, other):
>           if not isinstance(other, Range):
>               return True
>           return ((self._lower, self._upper, self._bounds) <
>                   (other._lower, other._upper, other._bounds))
>
> Because None < 1 raises a TypeError, in Python 3 I have to do:
>
>       def __lt__(self, other):
>           if not isinstance(other, Range):
>               return NotImplemented
>           for attr in '_lower', '_upper', '_bounds':
>               self_value = getattr(self, attr)
>               other_value = getattr(other, attr)
>               if self_value == other_value:
>                   pass
>               elif self_value is None:
>                   return True
>               elif other_value is None:
>                   return False
>               else:
>                   return self_value < other_value
>           return False
>
> Am I missing something? How can I get this method down to a sane size?
>
How about this:

      def make_key(item):
          return [(x is not None, x or 0) for i in [item._lower, 
item._upper, item._bounds]]

      def __lt__(self, other):
          if not isinstance(other, Range):
              return NotImplemented

	return make_key(self) < make_key(other)

It'll make None less than any number.



More information about the Python-Dev mailing list