[Python-bugs-list] [ python-Bugs-683726 ] METH_CLASS allows binding to the wrong class

SourceForge.net noreply@sourceforge.net
Mon, 10 Feb 2003 14:16:13 -0800


Bugs item #683726, was opened at 2003-02-09 22:21
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=683726&group_id=5470

Category: Python Interpreter Core
Group: Python 2.3
Status: Open
Resolution: None
Priority: 7
Submitted By: Greg Chapman (glchapman)
Assigned to: Guido van Rossum (gvanrossum)
Summary: METH_CLASS allows binding to the wrong class

Initial Comment:
I just noticed that this doesn't raise an exception:

>>> cmeth = dict.__dict__['fromkeys'].__get__(None, 
list)
>>> cmeth
<built-in method fromkeys of type object at 
0x1E0BB2E0>
>>> cmeth.__self__
<type 'list'>

Looking over the various METH_CLASS 
implementations, it doesn't look like they depend on the 
first (cls) parameter being of any particular type, but it 
might be nice to flag something like the above with an 
exception.

Also, there's this:

>>> cmeth2 = dict.__dict__['fromkeys'].__get__(None, 
42)
>>> cmeth2
<built-in method fromkeys of int object at 0x0074FD90>
>>> print cmeth2.__self__
42

Above, 42 gets passed through to classmethod_get in 
the type parameter, despite the fact that this parameter 
is typed as a PyTypeObject *. Perhpas wrap_descr_get 
should check that its second parameter (if it gets one) is 
a type?
 

----------------------------------------------------------------------

>Comment By: Guido van Rossum (gvanrossum)
Date: 2003-02-10 17:16

Message:
Logged In: YES 
user_id=6380

Looking into this now...


----------------------------------------------------------------------

Comment By: Greg Chapman (glchapman)
Date: 2003-02-10 11:59

Message:
Logged In: YES 
user_id=86307

I'm not entirely sure what the desired semantics for 
classmethod_get should be, but it seems to me they should 
be something like the following:

1) descr.__get__(None)
   descr.__get__(None, None)

This case would construct a PyCFunction using descr's 
d_type.  (What happens if both obj and type are NULL (as 
opposed to None)?  I think that should be a BadInternalCall, 
but perhaps it should also return a function with d_type.)

2) descr.__get__(notNone)
    descr.__get__(notNone, anything)

I think this case should be handled as for other descriptors.  
notNone would be checked to see if it is an instance of 
d_type; if so, a PyCFunction would be constructed using 
type(notNone).

3) descr.__get__(None, notNone)

Here notNone would be checked to ensure it is a type object, 
and then checked to see if it is a subtype of d_type.  If it 
passes these checks, then a PyCFunction is constructed 
using notNone.  (This branch would also handle the case 
where the obj == NULL in classmethod_get).

Alternatively, if it is always safe to assume that obj == NULL 
means that classmethod_get was called by the core library, 
and so the type parameter is correct, there could be a 0'th 
branch for obj == NULL which returns a PyCFunction 
constructed using type.


----------------------------------------------------------------------

Comment By: Greg Chapman (glchapman)
Date: 2003-02-09 22:38

Message:
Logged In: YES 
user_id=86307

I just realized that the above can be used to crash python, so 
I believe some sort of checking has to be added to 
classmethod_get:

>>> cmeth = dict.__dict__['fromkeys'].__get__(None)
>>> cmeth(4)

(above causes and access violation because the cls object 
passed to the fromkeys method is NULL).


----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=683726&group_id=5470