]> granicus.if.org Git - python/commitdiff
Fix for SF bug #117241
authorJeremy Hylton <jeremy@alum.mit.edu>
Mon, 30 Oct 2000 17:15:20 +0000 (17:15 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Mon, 30 Oct 2000 17:15:20 +0000 (17:15 +0000)
When a method is called with no regular arguments and * args, defer
the first arg is subclass check until after the * args have been
expanded.

N.B. The CALL_FUNCTION implementation is getting really hairy; should
review it to see if it can be simplified.

Lib/test/test_extcall.py
Python/ceval.c

index 10e4d6c3931e3b74921627e2d4499270a22d3f81..7dddabca65c021fb07c66c39ac9ae2cb9b2d8195 100644 (file)
@@ -144,3 +144,21 @@ for i in range(512):
     d[key] = i
 a, b = f2(1, *(2, 3), **d)
 print len(a), len(b), b == d
+
+class Foo:
+    def method(self, arg1, arg2):
+        return arg1 + arg2
+
+x = Foo()
+print Foo.method(*(x, 1, 2))
+print Foo.method(x, *(1, 2))
+try:
+    print Foo.method(*(1, 2, 3))
+except TypeError, err:
+    print err
+try:
+    print Foo.method(1, *(2, 3))
+except TypeError, err:
+    print err
+
+
index df057b763c05c3e2213d65dd22e6230f91a435fd..ad6e7920a593a1298265168200891d0c98aed431 100644 (file)
@@ -1822,7 +1822,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
                            na++;
                            n++;
                        }
-                       else {
+                       else if (!((flags & 1) && na == 0)) {
                            /* Unbound methods must be called with an
                               instance of the class (or a derived
                               class) as first argument */ 
@@ -1895,6 +1895,20 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
                            if (nstar < 0) {
                                goto extcall_fail;
                            }
+                           if (class && self == NULL && na == 0) {
+                               /* * arg is first argument of method,
+                                  so check it is isinstance of class */
+                               self = PyTuple_GET_ITEM(stararg, 0);
+                               if (!(PyInstance_Check(self) &&
+                                     PyClass_IsSubclass((PyObject *)
+                                  (((PyInstanceObject *)self)->in_class),
+                                                        class))) {
+                                   PyErr_SetString(PyExc_TypeError,
+           "unbound method must be called with instance as first argument");
+                                   x = NULL;
+                                   break;
+                               }
+                           }
                        }
                        if (nk > 0) {
                            if (kwdict == NULL) {