[Eric] TypeError in DebugClientBase.py

Seth Hill sethrh at gmail.com
Tue Nov 24 21:43:42 GMT 2009


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 <detlev at 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
> detlev at die-offenbachs.de
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.riverbankcomputing.com/pipermail/eric/attachments/20091124/23bc4b2d/attachment.html


More information about the Eric mailing list