Top and Bottom Values [PEP: 326]

Antoon Pardon apardon at forel.vub.ac.be
Thu Sep 28 09:54:04 CEST 2006


On 2006-09-27, Steven D'Aprano <steve at REMOVE.THIS.cybersource.com.au> wrote:
> On Wed, 27 Sep 2006 13:37:40 +0000, Paul McGuire wrote:
>
>> Here's a little more refined version of my previous post:
>> 
>> class StubbornInt(int):
>>     def invariantOp(self,other):
>>         return self
>>     __add__ = invariantOp
>>     __sub__ = invariantOp
>
> [snip rest of code]
>
>> import sys
>> Top = StubbornInt(sys.maxint)
>
> Top shouldn't need to depend on a specific integer value, but then it is
> easy enough to subclass StubbornInt.
>
> However, there is a more serious problem with your definition of Top:
>
>>>> Top > sys.maxint+1
> False
>
> But Top is supposed to bigger than everything, right?
>
> Okay, let's fix it:
>
> class FixedTop(StubbornInt):
>     def __init__(self):
>         super(FixedTop, self).__init__(sys.maxint)
>         self.name = 'Top'
>     def _bigger(self, other):
>         # Top is bigger than everything
>         return True
>     def _smaller(self, other):
>         # Top is smaller than nothing
>         return False
>     __lt__ = __le__ = _smaller
>     __gt__ = __ge__ = _bigger
>
>
> Let's test it out:
>
>>>> Top = FixedTop()
>>>> Top > 45
> True
>>>> Top > sys.maxint
> True
>>>> Top > 2L**512
> True
>>>> Top > None
> True
>>>> Top > "hello"
> True
>
>
> So far so good.
>
> However, the downside of rolling your own Top is the risk that one day
> you'll have something like this:
>
> class Funny:
>     def __init__(self, name):
>         self.name = name
>     def __str__(self):
>         return self.name
>     def __gt__(self, other):
>         return len(str(self)) > len(str(other))
>
> and then you'll have problems:
>
>>>> bottom = Funny("Bottom")
>>>> Top > bottom
> True
>>>> bottom > Top
> True
>
> As far as I can see, the only way to avoid edge cases like this is for Top
> (and Bottom) to be built-ins that are special-cased by Python.

An other problem is that if you roll your own, they wont be accepted in
a lot of buitins where they would make sense. Take itertools.repeat as
it is now and I understand correctly there are two possibilities.

1) Your extreme values are not a subclass of int, then you won't be able
to use them as a times arguments.

2) Your extreme values are a subclass of int, then they will somehow
have an int value and this int value will be used, so that the repeat
won't be an infinite loop.

-- 
Antoon Pardon



More information about the Python-list mailing list