Comparisons and sorting of a numeric class....

Andrew Robinson andrew3 at r3dsolutions.com
Mon Jan 12 23:16:52 EST 2015


Hmm....
>> LOL ... no exception was raised... and we know if the assertion Failed, an
>> exception ought to be raised:
> The assertion did not fail. There are three parts, and as long as one
> of them is true, the assertion will pass:
>
> 1) x isn't an instance of bool
> 2) x is the object known as True
> 3) x is the object known as False
>
> You just gave an example of the first part of the invariant. That's an
> instance of tuple, which is not a subclass of bool, ergo isinstance(x,
> bool) returns False, negating that makes True, and the assertion
> passes. [1]

Uh ... yeah... and so an assertion meant to test if something is or is 
not a bool let a non-bool pass the assertion.  That seems rather ... 
silly, and useless, ... and so I really doubt the assertion -- based on 
it's behavior --can distinguish an actual bool from a subclassed one or 
a totally unrelated object ...

I mean, let's start by testing if x as an actual boolean will cause the 
assertion to act differently from a fake-non bool object which we 
already tried.

x=True
 >>> x=True
 >>> assert not isinstance(x, bool) or x is True or x is False
 >>>
Wow. No difference in behavior.

So (as a test) it can't distinguish between an actual boolean and a 
faked one.
They both pass the assertion.  So -- What good is this assertion? It 
tells us nothing useful when executed.

Also what if we put in a subclass....

Instead of pretending what if -- let's actually REPLACE python's built 
in bool class with an emulation that ALLOWS subclassing and THEN let's 
TEST my hypothesis that the assert statement you gave me can't tell the 
difference between bools any anthing else by it's actions...  ( ooooh 
... another back-door that Guido forgot about... or perhaps purposely 
left open...)

class bool( int ):
     def __new__(self,data): return super( bool, self).__new__(self, 
[0,1][data!=0] )
     def __repr__(self): return [ 'True', 'False' ][self>0]

__builtins__.bool=bool
__builtins__.True=bool( 1==1 )
__builtins__.False=bool( 1==0 )

And, running it in the python interpreter...

 >>> class bool( int ):
...     def __new__(self,data): return super( bool, self).__new__(self, 
[0,1][data!=0] )
...     def __repr__(self): return [ 'True', 'False' ][self>0]
...
 >>> __builtins__.bool=bool
 >>> __builtins__.True=bool( 1==1 )
 >>> __builtins__.False=bool( 1==0 )
 >>>
 >>> type(True)
<class '__main__.bool'>

I now have proof that the replacement succeeded.
So let's subclass bool !!!

 >>> class subBool(bool): pass
...
 >>>

and now, let's see if your assertion believes a subclass of bool is a 
bool...
 >>> x=subBool(0)
 >>> assert not isinstance(x, bool) or x is True or x is False
 >>>

Wow. No change.
So -- it doesn't fail when the object ISN'T a bool, it doesn't fail when 
the object IS a bool, and it doesn't fail when the object is a subclass 
of bool; and #1 matches that of a True bool! or if #1 doesn't match that 
of a true bool.

 >>> isinstance( x, bool ) ,
True
 >>> isinstance( True, bool )
True

Therefore, your explantion ( so far ) of how to interpret the invariant, 
is consistent with it explicitly and *precisely* 'passing'  all possible 
instances of subclasses of bool, all instances of non-bools, and all 
instances of bools.  Yes, the assertion you chose passes precisely 
ANYTHING! (facetous use of precise.).

It's a worthless assertion in the sense that it has no explicit logic to 
DISTINGUISH what Guido/Python does want a bool to be from what you have 
said and implied Guido doesn't want (even though I've never seen Guido 
agree with you on this assertion thing...) .
>> So -- your assertion, at least as shown, is pretty useless in helping
>> determine why subclassing is not allowed, or instances of subclasses that
>> are not distinct from their superclasses existing instance.
> It exactly defines the nature of Python's bool type: there are
> precisely two instances of it.
>
> ChrisA
>
> [1] Which puts me in mind of https://www.youtube.com/watch?v=D0yYwBzKAyY

Uh, no, -- your assertion excludes nothing you've been telling me is not 
a bool by contract -- so it doesn't 'define' anything precisely because 
it's by definition inaccurate.  it's simply an invariant form of spam 
with three terms you can interpret any way you like.

Where did you get that assertion from anyway and how is it related to 
Guido and formal definitions of the python language ???  Are you really 
trying to imply that Guido wrote that assertion ?

> On Tue, Jan 13, 2015 at 12:59 PM, Andrew Robinson
> <andrew3 at r3dsolutions.com>  wrote:
>> There is no need to copy data from an initialized superclass instance into a
>> subclass instance that has no new data, but only rebind -- or add a
>> binding/proxy object -- to bind the superclass instance to the subclass
>> methods.
>>
>> eg: what is now standard practice to create a new copy of the superclass:
>>
>> class myFalse( bool ): __new__( self, data ): return super( myFalse, self
>> ).__new__(self,data)
>>
>> Could be replaced by a general purpose proxy meant to handle singleton
>> subclassing:
>>
>> class myFalse( bool ):  __new__( self ): return
>> bind_superinstance_to_subclass( False, myFalse )
> I don't understand. What do you expect this to be doing? Are you
> trying to replace the original False with your new subclass?
>
No.  I'm trying to make a subclass be a wrapper for an existing 
superclass's instance's data.
It is creating something equivalent to a proxy object ; since singletons 
have no need of data, there is no reason to create a new instance; 
Therefore a fake instance will do.  In C++ (Which Guido quoted in his 
reasoning though he was wrong about what it can do), a fake instance 
would generally be created by typecasting a base class instance as a 
subclass instance... but in python, a proxy object is generally used for 
the same task.

eg: when wanting to access super objects in C++, you could typecast a 
pointer to the subclass object as a pointer to the superclass object; 
but in python, typecasts don't exist so the same job is done -- via 
super(), by returning a proxy object.

To understand what a subclass of bool would do without an instance; Here 
is an example of a C-Python interpreter session after the python source 
code of the super() proxy type was modified to allow binding subclass 
methods to an existing superclass instance:

 >>> x=myFalse( False )
 >>> print x is False
 >>> False
 >>> print x==False
 >>> True
 >>> print isinstance( x, myFalse)
 >>> True
 >>> print isinstance( x, bool )
 >>> True
 >>> print isinstance( x, int )
 >>> True
 >>> print super( x, int ).__self__  # Revert the proxy object to the 
superclass instance,this is a kludge.
 >>> False

Note: False is the actual False object being returned as __self__, 
because the instance False was chosen to be bound to the proxy object 
and I thought that __self__ degenerating to the bound instance would be 
a reasonable action;  If I had set x=myFalse( True ), it should return 
the singleton 'True' instead.

 >>> print x
 >>> False
 >>> print type(x) # This could return various things, depending on how 
the proxy is implemented...
 >>> <super>

So, you see -- The subclass is implemented as a transparent proxy object 
to an instance of bool; it's NOT an instance of the subclass myFalse in 
reality -- but it acts 100% like an instance of myFalse would, except 
for '__self__' and type().

There are probably other ways to achieve this same goal, but one is 
enough for explanation.  This is taking too much time...






More information about the Python-list mailing list