[Python-Dev] metaclass insanity

Guido van Rossum guido@python.org
Tue, 05 Nov 2002 10:49:20 -0500


> > > Oh, and while we're at it, here's a bogosity:
> > > 
> > > >>> class C(object):
> > > ...  pass
> > > ... 
> > > >>> C.__module__ 
> > > '__main__'
> > > >>> C.__module__ = 1
> > > >>> C.__module__ 
> > > Traceback (most recent call last):
> > >   File "<stdin>", line 1, in ?
> > > AttributeError: __module__
> > > 
> > > caused by lax testing in type_set_module.
> > 
> > Oops.  Can you fix it?  Or are there complications?
> 
> No, should be easy.
> 
>     if (!PyString_Check(arg)) {
>            PyErr_SetString(PyExc_TypeError,
>                            "don't do that");
>            return -1;
>     }
> 
> or something like that.

I think the fix should be not to typecheck __module__ when returning
it.  If someone sets __module__ to a non-string, that's their problem:

*** typeobject.c	18 Oct 2002 16:33:12 -0000	2.185
--- typeobject.c	5 Nov 2002 15:47:46 -0000
***************
*** 63,69 ****
  	if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
  		return PyString_FromString("__builtin__");
  	mod = PyDict_GetItemString(type->tp_dict, "__module__");
! 	if (mod != NULL && PyString_Check(mod)) {
  		Py_INCREF(mod);
  		return mod;
  	}
--- 63,69 ----
  	if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
  		return PyString_FromString("__builtin__");
  	mod = PyDict_GetItemString(type->tp_dict, "__module__");
! 	if (mod != NULL) {
  		Py_INCREF(mod);
  		return mod;
  	}

--Guido van Rossum (home page: http://www.python.org/~guido/)