Opened 3 years ago

Closed 3 years ago

Last modified 23 months ago

#19928 closed Uncategorized (invalid)

python_2_unicode_compatible breaks Python 2

Reported by: vernondcole Owned by: nobody
Component: Uncategorized Version: master
Severity: Normal Keywords: porting to python 3
Cc: m.r.sopacua@… Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


Following the example in
I made my look like this:

from __future__ import unicode_literals
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
class Ward_Name(models.Model):
    state = models.CharField("State", max_length=55,
        help_text="Nigearin State (large political subdivision)")
    lga = models.CharField("LGA", max_length=255, blank=True,
        help_text="Nigerain Local Government Area (medium political subdivision)")
    ward = models.CharField(max_length=255, blank=True,
        help_text="Ward (small political subdivision)")
    db_ward = models.CharField("Db Ward",max_length=255, blank=True,
        help_text="database altered version of Ward name")
    def __str__(self):
        return str('State={}, LGA={}, Ward={}, called "{}"'.format(
            self.state, self.lga, self.ward, self.db_ward))
    class Meta:
        unique_together = (("lga","ward"))
        index_together = [["lga","ward"]]

Note that the decorator is commented out...
I test using the following code, which works in both Python2.7 and Python3.3
$python x_test

from __future__ import print_function
from import BaseCommand
from nomads.models import Ward_Name

class Command(BaseCommand):
    args = "<(none)>"
    help = 'test reading Ward Name data table'

    def handle(self, *args, **options):

    def test_read(self, *args):
        qs = Ward_Name.objects.all()
        for w in qs:

When I un-comment the decorator the program fails under python 2

$ python x_test
RuntimeError: maximum recursion depth exceeded while calling a Python object

Is the error in the django 1.5 code, the documentation, or my understanding?

(the work-around is easy: just do not use the feature and everything works in both versions)

(My environment is: Ubuntu 12.10 64 bit
django 1.5stable pulled from github this morning

Change History (3)

comment:1 Changed 3 years ago by aaugustin

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

The docs say "you must define a __str__() method returning text".

Your __str__() method returns a bytestring under Python 2.

comment:2 Changed 23 months ago by msopacua

  • Cc m.r.sopacua@… added

I'd like to reopen this issue or create a new one for expanding the documentation. It's very slim on the whole str method in python 2 and specifically doesn't deal with abstract classes. I just spent quite a bit of time debugging this issue, where I had the str() method defined in the abstract class and repeated the decorator on derived classes. I'm guessing this is the error and somehow things get screwed when doing it like that. No matter what I returned in the abstract class I got the recursion error. When I finally reimplemented the method in the derived class and gave back a simple string literal, things went ok.
I'm still figuring out how to deal with it, cause what I really want to return is a property of a foreign key.
Anyway, reopen this, or create a new one?

comment:3 Changed 23 months ago by aaugustin

Don't repeat the decorator on derived classes. It's only appropriate on the class that defines __str__.

Note: See TracTickets for help on using tickets.
Back to Top