Issue409355
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2001-03-17 10:10 by loriend, last changed 2022-04-10 16:03 by admin. This issue is now closed.
Messages (14) | |||
---|---|---|---|
msg3911 - (view) | Author: Lorien Dunn (loriend) | Date: 2001-03-17 10:10 | |
I've run into a bug in python 2.0. The real code that the following pseudo code represents throws a TypeError. class MyDerivedClass(MyPurePythonClass,MyBoostClass): def __init__(self): MyPurePythonClass.__init__(self) MyBoostClass.__init__(self) The problem occurs in MyPurePythonClass- Python says "unbound method must be called with class instance 1st argument". This makes sense: I'm passing a meta-class instead of a class. David Abrahams (the main author of boost::python) agrees that this is a Python problem, and that it should affect Zope as well. I think I've found the point in the python 2.0 sorce where it occurs: ceval.c, line 1816 (reformatted for clarity): /* BEGIN CODE SAMPLE */ else { /* Unbound methods must be called with an instance of the class (or a derived class) as first argument */ if (na > 0 && (self = stack_pointer[-n]) != NULL && PyInstance_Check(self) && PyClass_IsSubclass((PyObject *) (((PyInstanceObject*) self)->in_class), class)) /* Handy-dandy */ ; else { PyErr_SetString(PyExc_TypeError, "unbound method must be called with class instance 1st argument"); x = NULL; break; } } /* END CODE SAMPLE */ |
|||
msg3912 - (view) | Author: Tim Peters (tim.peters) * | Date: 2001-03-18 05:29 | |
Logged In: YES user_id=31435 Assigned to Guido, because I bet JimF would refuse to take blame for this <wink>. |
|||
msg3913 - (view) | Author: Nobody/Anonymous (nobody) | Date: 2001-03-18 13:03 | |
Logged In: NO I was a bit surprised to learn that this check was still in the code after issubclass and isinstance had been fixed to work with extension classes. Suppose you checked for a __class__ attribute on the first argument instead (or additionally)? |
|||
msg3914 - (view) | Author: David Abrahams (david_abrahams) | Date: 2001-03-18 13:30 | |
Logged In: YES user_id=52572 Sorry, that anonymous comment is mine. I'm still a bit clumsy with SourceForge. -Dve |
|||
msg3915 - (view) | Author: Guido van Rossum (gvanrossum) * | Date: 2001-03-18 22:22 | |
Logged In: YES user_id=6380 Zope has several workarounds, so isn't affected. But I agree it could be fixed. The test is there because it wants to enforce a concept: 'self' should be an instance of the class that defines the method (where a subclass instance is fine too). But the implementation of the test is based too much on the default implementation of classes. Could someone please submit a patch that replaces the concrete isinstance() test with an isinstance() test similar to that in bltinmodule.c? (Maybe we need to add a new C API, PyObject_IsInstance().) If someone could come up with a check that conve |
|||
msg3916 - (view) | Author: Guido van Rossum (gvanrossum) * | Date: 2001-03-21 19:18 | |
Logged In: YES user_id=6380 I *think* I've fixed this now -- please test with the current CVS. Please let me know if I goofed up, and I'll reopen the bug report. |
|||
msg3917 - (view) | Author: Lorien Dunn (loriend) | Date: 2001-03-22 19:59 | |
Logged In: YES user_id=175701 I'm afraid it still doesn't work :( the line is (from cvs code): ok = PyObject_IsInstance(self, class) and the problem is that ok == 0. Thank you for patching this- I've spent hours trying to figure out enough about the python internals to do it myself. Lorien |
|||
msg3918 - (view) | Author: Guido van Rossum (gvanrossum) * | Date: 2001-03-22 20:03 | |
Logged In: YES user_id=6380 OK, try this. In your Python code, what does isinstance(self, MyPurePythonClass) return? |
|||
msg3919 - (view) | Author: Lorien Dunn (loriend) | Date: 2001-03-22 21:58 | |
Logged In: YES user_id=175701 In the following code it returns 0. MyDerivedClass(MyPurePythonClass, MyBoostClass): def __init__(self): MyBoostClass.__init__(self) isinstance(self, MyPurePythonClass) |
|||
msg3920 - (view) | Author: David Abrahams (david_abrahams) | Date: 2001-03-23 03:09 | |
Logged In: YES user_id=52572 Though I haven't checked out the latest from CVS, I'm at a loss to explain the results Lorien is getting. In particular, Boost.Python class instances have a __class__ attribute, and Boost.Python classes have a __bases__ attribute that is a tuple. Isn't that all that should be needed for isinstance() to work properly?... Aha, now I remember: The first base class in the list controls which metaclass object gets control when a derived class is created. So the declaration of MyDerivedClass below actually creates a regular Python class with a base that is a Boost.Python class. At that point, everything is beyond my control. To get it to work, at least begin by swapping the order of the base classes. I wonder if it would make sense to always defer to the first extension type's type (if any) for subclass creation? It's not a general solution (i.e. what if you have multiple extension types in the __bases__ tuple?) but at least it would handle this case. Surely it's less likely that a regular Python class can make any sane use of methods from an extension class. -Dave |
|||
msg3921 - (view) | Author: Guido van Rossum (gvanrossum) * | Date: 2001-03-23 03:32 | |
Logged In: YES user_id=6380 David, I'm not sure I agree with your theory. At Jim Fulton's request, when creating a subclass, Python actually looks through the base classes for one that's not a regular class, and gives that one control of the subclass creation process. So MyDerivedClass really should be a Boost.Python class! (Lorien can easily verify that by printing self.__class__.) Otherwise, if it was a regular class, the __init__ call woudln't have failed in the first place! Since I don't have Boost (yet), I can't look into this further right now, and I fear it will have to remain unresolved until after the 2.1b2 release. But I'll try to look into it again before the final 2.1 release. |
|||
msg3922 - (view) | Author: Lorien Dunn (loriend) | Date: 2001-03-23 03:38 | |
Logged In: YES user_id=175701 Guido, printing self.__class__ results in the text "<extension class> MyDerivedClass.MyDerivedClass at 8121560" David, swapping the order of the base classes makes no difference. Thanks. |
|||
msg3923 - (view) | Author: Guido van Rossum (gvanrossum) * | Date: 2001-04-10 20:14 | |
Logged In: YES user_id=6380 Sorry, I'm at a loss with this. What does isinstance(self, MyPurePythonClass) return? (Should be 1) Lowering the priority -- unless we get some light quickly, this won't make it into 2.1. |
|||
msg3924 - (view) | Author: Guido van Rossum (gvanrossum) * | Date: 2001-08-11 04:29 | |
Logged In: YES user_id=6380 I'm closing this as a Won't Fix. In 2.2, metaclasses will work differently anyway. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-10 16:03:52 | admin | set | github: 34177 |
2001-03-17 10:10:10 | loriend | create |