On Jul 12, 11:48 am, samwyse <[EMAIL PROTECTED]> wrote: > On Jul 12, 6:31 am,samwyse<[EMAIL PROTECTED]> wrote: > > > On Jul 8, 8:50 am, Christoph Zwerschke <[EMAIL PROTECTED]> wrote: > > > > With Py 2.5 I get: > > > > new.__class__ = old.__class__ > > > TypeError: __class__ must be set to a class > > Hmmm, under Python 2.4.X, printing repr(old.__class__) gives me this: > <class exceptions.UnicodeDecodeError at 0x00A24F00> > while under 2.5.X, I get this: > <type 'exceptions.UnicodeDecodeError'> > > So, let's try sub-classing the type: > > def modify_message(old, f): > class Empty: pass > new = Empty() > print "old.__class__ =", repr(old.__class__) > print "Empty =", repr(Empty) > new.__class__ = Empty > > class Excpt(old.__class__): pass > print "Excpt =", repr(Excpt) > print "Excpt.__class__ =", repr(Excpt.__class__) > new.__class__ = Excpt > > new.__dict__ = old.__dict__.copy() > new.__str__ = f > return new > > Nope, that gives us the same message: > > old.__class__ = <type 'exceptions.UnicodeDecodeError'> > Empty = <class __main__.Empty at 0x00AB0AB0> > Excpt = <class '__main__.Excpt'> > Excpt.__class__ = <type 'type'> > Traceback (most recent call last): > [...] > TypeError: __class__ must be set to a class > > Excpt certainly appears to be a class. Does anyone smarter than me > know what's going on here?
OK, in classobject.h, we find this: #define PyClass_Check(op) ((op)->ob_type == &PyClass_Type) That seems straightforward enough. And the relevant message appears in classobject.c here: static int instance_setattr(PyInstanceObject *inst, PyObject *name, PyObject *v) [...] if (strcmp(sname, "__class__") == 0) { if (v == NULL || !PyClass_Check(v)) { PyErr_SetString(PyExc_TypeError, "__class__ must be set to a class"); return -1; } Back in our test code, we got these: > Empty = <class __main__.Empty at 0x00AB0AB0> > Excpt = <class '__main__.Excpt'> The first class (Empty) passes the PyClass_Check macro, the second one (Excpt) evidently fails. I'll need to dig deeper. Meanwhile, I still have to wonder why the code doesn't allow __class_ to be assigned a type instead of a class. Why can't we do this in the C code (assuming the appropriate PyType_Check macro): if (v == NULL || !(PyClass_Check(v) || PyType_Check(v))) { -- http://mail.python.org/mailman/listinfo/python-list