Assignments to __class_ broken in Python 2.5?
samwyse
samwyse at gmail.com
Fri Jul 13 07:58:21 EDT 2007
(Yes, I probably should have said CPython in my subject, not Python.
Sorry.)
On Jul 13, 12:56 am, samwyse <samw... at gmail.com> wrote:
> 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))) {
After a good night's sleep, I can see that Empty is a "real" class;
i.e. its repr() is handled by class_repr() in classobject.c. Excpt,
on the other hand, is a type; i.e. its repr is handled by type_repr()
in typeobject.c. (You can tell because class_repr() returns a value
formatted as "<class %s.%s at %p>" whereas type_repr returns a value
formatted as "<%s '%s.%s'>", where the first %s gets filled with
either "type" or "class".)
This is looking more and more like a failure to abide by PEP 252/253.
I think that the patch is simple, but I'm unusre of the
ramifications. I also haven't looked at the 2.4 source to see how
things used to work. Still, I think that I've got a work-around for
OP's problem, I just need to test it under both 2.4 and 2.5.
More information about the Python-list
mailing list