Default __nonzero__ impl doesn't throw a TypeError exception
Terry Reedy
tjreedy at udel.edu
Fri Jan 9 15:58:56 EST 2009
Bruno Desthuilliers wrote:
>
> To be more exact: there's no "default __nonzero__".
In Py3, '__nonzero__' has been renamed to __bool__.
All objects are instances of class object,
which indeed has no __bool__ method to be a default
(it does have default __hash__ and __eq__, etc).
> The boolean value of
> an object is eval'd this way:
>
> If the object is None (special cased by the interpreter AFAICT), it is
> false.
Must be, since None.__bool__ does not exist.
> Else if the object implements __nonzero__, it has the boolean value
> returned by __nonzero__.
Leaving None aside, __bool__ is only needed for non-collection classes
(which do not have __len__) if at least 1 instance of the class is
intended to be False. For built-in classes, this means numbers.
> Else if the object implements __len__, it has the boolean value of its
> length.
This method, interpreted more generally as 'object count', essentially
defines collection classes.
> Else if is true.
Thank you for the clarification. Then the __new__ method of class bool
would be implemented in Python as
def __new__(cls, ob):
if ob is None:
return False
elif hasattr(ob, '__bool__'):
b = ob.__bool__()
if b.__class__ is bool:
return b
else:
raise TypeError("__bool__ should return bool, returned %s" %
b.__class__)
elif hasattr(ob, '__len__'):
return len(ob) != 0
# ob.__len__() != 0 does not do len's typecheck on return
else:
return True
Experiments show that 3.0 bool.__new__ does typecheck the return of
ob.__bool__ and raises the error indicated and that __len__ must return
a value that passes len's typecheck.
Terry Jan Reedy
More information about the Python-list
mailing list