1. Benjamin Peterson
  2. six
  3. Issues
Issue #15 resolved

Could do with some decorators for the __unicode__ and __str__ rename

Tom Grainger
created an issue

Django uses https://github.com/django/django/blob/master/django/utils/encoding.py#L26

to support both python2 and python3 style __unicode__ and __str__ renames.

the Python 3 porting guide suggests http://docs.python.org/3/howto/pyporting.html#str-unicode

This pattern is likely to be used in lots of projects hoping to support both 3k and 2, so I think it should be included in six.

Comments (8)

  1. Aymeric Augustin

    StrAndUnicode is deprecated; Django now uses: https://github.com/django/django/blob/ef017a5f00/django/utils/encoding.py#L49

    I'm the author of this code and I must admit it has some drawbacks:

    • Decorated __str__ methods must return unicode strings even on Python 2;
    • It's easy to shoot oneself into the foot when combining this with inheritance;
    • Specifically, if you accidentally trigger infinite recursion when a base class derives __unicode__ from __str__ or vice-versa, you're in an ugly situation, because you cannot even print the problematic object! (Yes I'm looking at you django.db.models.Model.)

    Of course, this technique also has some advantages — namely, it allows for reasonably short and explicit code.

    I'd be very happy if that was included in six. We could remove code from Django! I just wanted to state the drawbacks upfront :)

  2. Tom Grainger reporter

    Using a UnicodeMixin similar to django.utils.encoding.StrAndUnicode is recommended in the python 3 porting documentation.

    • Why was that deprecated in django?
    • Should it be removed from this porting documentation also?
  3. Aymeric Augustin

    The Python docs offer a variety of porting techniques. In the paragraph you're referring to, the result is Python 2 code that also works on Python 3 (ie. it defines a Python 2-style __unicode__ method).

    While porting Django, I was very careful to write Python 3 code that also works on Python 2 rather than the opposite.

    I made this choice for Django because I prefer looking at the future than at the past. And since I was building the bike shed I could chose its color :) This technique involves much more work than just trying to get tests to pass under Python 3. It may or may not suit everyone's tastes.

    (Accidentally posted while I was writing my comment -- sorry if you got a notification with an incomplete message).

  4. Benjamin Peterson repo owner

    This surprisingly tricky. We want something which

    • Plays nicely with inheritance.
    • Allows minimal code duplication in client's code.
    • Provides a reasonable fallback implementation if it's desired.
  5. Log in to comment