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

Chris Angelico rosuav at gmail.com
Fri Feb 14 10:44:28 CET 2014


On Fri, Feb 14, 2014 at 7:04 PM, Chris Withers <chris at simplistix.co.uk> wrote:
>
> 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?

Can you be certain that all your values are either None or positive
integers? If so, try this:

    def __lt__(self, other):
        if not isinstance(other, Range):
            return True # or NotImplemented, not sure why this change
        return ((self._lower or 0, self._upper or 0, self._bounds or 0) <
                (other._lower or 0, other._upper or 0, other._bounds or 0))

That'll treat all Nones as 0, and compare them accordingly. If you
can't depend on them being positive (eg if you need None to be less
than 0 rather than equal - even more so if you need it to be less than
negative numbers), you'll need to more explicitly check. But this is
nice and tidy, if it works.

ChrisA


More information about the Python-Dev mailing list