__unicode__() works, unicode() blows up.

Discussion in 'Python' started by Roy Smith, Nov 4, 2012.

  1. Roy Smith

    Roy Smith Guest

    Environment:
    Python-2.7.3
    Ubuntu Precise
    mongoengine 0.6.20

    I have a class which includes a __unicode__() method:

    class User(mongoengine.Document):
    def __unicode__(self):
    return self.username

    If I create an instance of this class by calling the constructor
    directly, self.username is None. When I pass that to unicode(), it
    blows up. However, calling __unicode__() directly, works as expected:
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: coercing to Unicode: need string or buffer, NoneType found

    What's going on here? I thought
    (http://docs.python.org/2/library/functions.html#unicode) the latter two
    calls should be identical, but obviously they're not.
     
    Roy Smith, Nov 4, 2012
    #1
    1. Advertisements

  2. Roy Smith

    Roy Smith Guest

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: coercing to Unicode: need string or buffer, NoneType found

    What's going on here? I thought
    (http://docs.python.org/2/library/functions.html#unicode) the latter two
    calls should be identical, but obviously they're not.[/QUOTE]

    Why is it, that no matter how long you stare at a problem, the answer
    comes to you moments after you hit the Post button? :)

    The problem is that __unicode__() is supposed to return a Unicode
    object, and unicode() enforces that. The fix is to change:

    def __unicode__(self):
    return self.username

    to be:

    def __unicode__(self):
    return unicode(self.username)

    This never got noticed before because normally, self.username already is
    a unicode string, so it just works.
     
    Roy Smith, Nov 4, 2012
    #2
    1. Advertisements

  3. Roy Smith

    Aahz Guest

    You apparently need more coffee when programming after waking up! (Or
    even worse, staying up all night.)
     
    Aahz, Nov 4, 2012
    #3
  4. Roy Smith

    Terry Reedy Guest

    Why is it, that no matter how long you stare at a problem, the answer
    comes to you moments after you hit the Post button? :)

    The problem is that __unicode__() is supposed to return a Unicode
    object, and unicode() enforces that. The fix is to change:

    def __unicode__(self):
    return self.username

    to be:

    def __unicode__(self):
    return unicode(self.username)

    This never got noticed before because normally, self.username already is
    a unicode string, so it just works.[/QUOTE]

    The same principle applies to some of the other special methods that sit
    behind builtin functions.
    def __len__(self): return '42' # whoops
    Traceback (most recent call last):
    File "<pyshell#9>", line 1, in <module>
    len(C())
    TypeError: 'str' object cannot be interpreted as an integer
    def __len__(self): return -42 # whoops again
    Traceback (most recent call last):
    File "<pyshell#12>", line 1, in <module>
    len(C())
    ValueError: __len__() should return >= 0
     
    Terry Reedy, Nov 4, 2012
    #4
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.