Hello,

One of the first lessons in the tutorial is to define a __unicode__ method. In 
Python 3, __unicode__ is replaced by __str__ (and __str__ by __bytes__, but 
that method won't be needed in general).

Writing these methods in a way works on both Python 2 and 3 proves surprisingly 
messy. I'd like some feedback before choosing a technique, applying it to 
Django, and documenting it.

Here are a few proposals. Which one do you prefer? Do you have better ideas?


* Proposal 1 — the very explicit way
  + explicit
  + no runtime overhead
  - not DRY
  - much boilerplate code

from __future__ import unicode_literals
from django.utils import six

class MyClass(object):
    if six.PY3:
        def __str__(self):
            return "text ..."
    else:
        def __str__(self):
            return self.__unicode__().encode('utf-8')
        def __unicode__(self):
            return "text ..."


* Proposal 2 — the Python 3 way
  + explicit
  + no runtime overhead
  - 3 lines of boilerplate code

from __future__ import unicode_literals
from django.utils import six

class MyClass(object):
    def __str__(self):
        return "text ..."
    if not six.PY3:
        __unicode__ = __str__
        __str__ = lambda self: self.__unicode__().encode('utf-8')


* Proposal 3 — the magic mixin
  + no boilerplate code
  - not explicit
  - requires writing a __unicode__ method which was removed in Python 3: this 
is non-educational for Python 2 programmers learning Python 3 and complete 
nonsense for Python 3 programmers who have never been exposed to Python 2.

from __future__ import unicode_literals
from django.utils.encoding import StrAndUnicode

class MyClass(StrAndUnicode, object):
    def __unicode__(self):
        return "text ..."


* Proposal 4 — the non-unicode way
  - on Python 2, __unicode__ performs an unnecessary encode / decode
  - on Python 2, __unicode__ will fail if the system encoding isn't utf-8 
(which may happen for a variety of reasons)

from __future__ import unicode_literals
from django.utils import six

class MyClass(object):
    def __str__(self):
        result = "text ..."
        if six.PY3:
            result = result.encode('utf-8')
        return result


At this point I tend to prefer the version 2, because it's explicit, short and 
in line with our goal to write Python 3 code that also works on Python 2. What 
about you?

Best regards,

-- 
Aymeric.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to