oktaysa...@superonline.com wrote:
Hi all,

I ran into a strange case.

Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32
...
 >>> -1 == True
False
 >>> -1 == False
False

This works though:
 >>> if -1:
    print "OK"

OK

After some head scratching, I realized that:
- bool is a subclass of int and that True and False evaluates to 1 and 0,

Yes, for historical and practical reasons.

so -1 is equal to neither; and

NO builtin objects other than numbers equal to 1 or 0 are equal to True or False.

- The if -1: statement probably works by treating -1 as bool(-1).

'if condition:' *always* works by calling bool() on the condition, which is why one should *never* write 'if bool(exp):'.

But I can't help finding the former comparison behavior odd.

Every object other than numbers equal to 0 or 1 has the same behavior.

I admit that it is odd to write such code but when someone writes -1 == True,

It is odd to write such code because the result of comparing two constants is or could be known when it is written. So while one could write an optimizer to replace such comparisons with the known value at compile time, no one has done so. (There is an optimizer that sometimes replaces arithmetic operations on number constants, but that is because writing code that way may make it clearer: for instance, 1<<13 versus 8192.)

the intention is clearly a boolean comparison, not a numerical value comparison, isn't it?

Nope. Expecially if either side of the expression in the code is a name or collection slot. As far as the compiler is concerned, '-1' is an expression that evaluates to an object and 'True' is another expression that evaulates to another object and '==' is a comparison operator which it compiles to a call to code that calls the appropriate rich comparison methods of either or both of the two objects.

As far as I understand, to do this comparison, python is casting (loosely speaking) True to its numerical value, rather than casting -1 to its boolean value.

I think that this is speaking so loosely as to be misleading. 'Cast' has a couple of meaning, neither of which means 'treat a subclass instance as a base class instance.' Subclass instances are automatically base class instances and are treated as such by default unless there is a subclass method that over-rides the base class method. Bool does *not* over-ride int comparison methods.

>>> bool.__eq__ is int.__eq__
True

I suspect that the only methods to bool are __new__ (which returns one of the only two instances allowed), __str__, and __repr__ (which return 'False' or 'True' instead of '0' or '1'). Bools are ints, not 'cast to' ints.

So, my question is: wouldn't it make more sense to do just the opposite, i.e. cast -1 to its boolean value and do a boolean comparison of the operands, when one of the operands is True or False?

That would require that ints be subclassed from bool, which does not work.

Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to