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