Hello, I filed a bug report with the django folks too ( http://code.djangoproject.com/ticket/12256). We determined that the issue isn't specific to django's use of metaclasses, but is in fact an issue with some older versions of python. This class:
class Foo(object): def __init__(self, x): self.x = x def __unicode__(self): print self.x Generates the same TypeError when you call unicode(type(Foo())). My python is 2.5.1. I wasn't able to duplicate the issue on my Mac under python 2.6.2. I haven't been able to find a bug about this in the python bug list though. On Mon, Nov 23, 2009 at 9:16 AM, detlev <det...@die-offenbachs.de> wrote: > Hello again, > > On Sonntag, 22. November 2009, Seth Hill wrote: > > On Nov 22, 2009, at 3:33 AM, detlev wrote: > > > On Samstag, 21. November 2009, Seth Hill wrote: > > >> I'm working with a django 1.1 project, trying to get debugging going. > > >> I'm working with a form in a view function. I set a breakpoint in the > > >> view function, and get a TypeError in DebugClientBase.py:1608. It > > >> looks like the debugger is going through the locals and calling > > >> unicode() on all of them. Some of the locals in this case don't > > >> support the unicode method. When the debugger calls the unicode() > > >> method, it triggers an exception inside the running wsgi server. I > > >> get an error message on the web page, and the debug session stops > > >> working. > > >> > > >> My code looks like: > > >> > > >> forms.py: > > >> class NewCustomerForm(forms.Form): > > >> name = forms.CharField() > > >> # etc > > >> > > >> views.py: > > >> def create_customer(request): > > >> if request.method == "POST": # breakpoint here > > >> form = NewCustomerForm(request.POST) > > >> if form.is_valid(): # exception occurs when stepping > > >> to here > > >> > > >> > > >> The line in DebugClientBase.py looks like: > > >> valtypestr = unicode(type(value))[1:-1] > > > > > > I don't understand, why type(value) does not support the unicode() > > > method. > > > > Now that you mention it, I don't either. I've been digging a little > > deeper, and it seems that this is django's problem: > > > > A django.forms.forms.Form class defines __metaclass__ = > > DeclarativeFieldsMetaclass (see source code http:// > > code.djangoproject.com/browser/django/trunk/django/forms/forms.py: > > 336). I'm not entirely sure what it does, but I gather that it > > converts the class attributes into fields which can be accessed by a > > class instance. > > > > Anyway, the metaclass seems to be promoting the __unicode__ function > > > > of Form to type(Form): > > >>> f = Form() > > >>> type(f) > > > > <class 'django.forms.forms.Form'> > > That seems to be a Django bug because the net result is, that you cannot > convert the result of type(f) to a unicode string. > > > > > >>> unicode(type(f)) > > > > Traceback (most recent call last): > > File "<console>", line 1, in <module> > > TypeError: unbound method __unicode__() must be called with Form > > instance as first argument (got nothing instead) > > > > >>> type(Form) > > > > <class 'django.forms.forms.DeclarativeFieldsMetaclass'> > > > > >>> import inspect > > >>> inspect.getsource(type(f).__unicode__) > > > > ' def __unicode__(self):\n return self.as_table()\n' > > > > Can you please check, what ist returned by > "inspect.getsource(type(f).__repr__)"? > > >>> inspect.getsource(type(f).__repr__) Traceback (most recent call last): File "<console>", line 1, in <module> File "C:\Software\Python25\lib\inspect.py", line 629, in getsource lines, lnum = getsourcelines(object) File "C:\Software\Python25\lib\inspect.py", line 618, in getsourcelines lines, lnum = findsource(object) File "C:\Software\Python25\lib\inspect.py", line 461, in findsource file = getsourcefile(object) or getfile(object) File "C:\Software\Python25\lib\inspect.py", line 383, in getsourcefile filename = getfile(object) File "C:\Software\Python25\lib\inspect.py", line 363, in getfile raise TypeError('arg is not a module, class, method, ' TypeError: arg is not a module, class, method, function, traceback, frame, or code object I assume this means that __repr__ hasn't been defined (not in source code anyway). However, this also doesn't work even if I do define __repr__: >>> class Foo(Form): ... def __repr__(self): ... return 'called repr' ... >>> inspect.getsource(Foo().__repr___) Traceback (most recent call last): File "<console>", line 1, in <module> File "C:\Software\Python25\lib\inspect.py", line 629, in getsource lines, lnum = getsourcelines(object) File "C:\Software\Python25\lib\inspect.py", line 618, in getsourcelines lines, lnum = findsource(object) File "C:\Software\Python25\lib\inspect.py", line 468, in findsource raise IOError('could not get source code') IOError: could not get source code >>> repr(Foo()) 'called repr' But that might be because I'm doing it on the console. > What is needed by the eric4 debugger backend is a method to return the type > of > a variable as a string. > This is kinda wacky, but might work: t = type(value) if not t is type: t = type(t) valtypestr = unicode(t)[1:-1] If f = Foo(), and Foo defines a metaclass, then type(f) isn't <type 'type'>. However, type(type(f)) should be. > > > > > Anyway, the effect is still that if you are running the debugger and > > have a Form instance as a local variable, it will blow up. I would be > > willing to be that debugging a Model instance would have a similar > > effect (since it also uses a metaclass). > > > > Maybe, instead of below a workaround should be: > > > > if type(value) is type: > > valtypestr = unicode(type(value))[1:-1] > > else: > > valtypestr = repr(type(value))[1:-1] > > > > However, even when doing that I suppose some metaclass could screw up > > __repr__ just like django's DeclarativeFieldsMetaclass did with > > __unicode__. (?) > > > > >> I've "fixed" the error by wrapping the line in a try: > > >> > > >> try: > > >> valtypestr = unicode(type(value))[1:-1] > > >> except TypeError: > > >> valtypestr = repr(type(value))[1:-1] > > >> > > Regards > Detlev > -- > Detlev Offenbach > det...@die-offenbachs.de >
_______________________________________________ Eric mailing list Eric@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/eric