Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #21198 -- Prevented invalid use of @python_2_unicode_compatible.

Thanks jpic for the report and chmodas for working on a patch.

Reverts 2ea80b9. Refs #19362.
  • Loading branch information...
commit 589dc49e129f63801c54c15e408c944a345b3dfe 1 parent 570d9c2
Aymeric Augustin authored October 13, 2013
5  django/db/models/base.py
@@ -450,11 +450,6 @@ def __repr__(self):
450 450
 
451 451
     def __str__(self):
452 452
         if six.PY2 and hasattr(self, '__unicode__'):
453  
-            if type(self).__unicode__ == Model.__str__:
454  
-                klass_name = type(self).__name__
455  
-                raise RuntimeError("%s.__unicode__ is aliased to __str__. Did"
456  
-                                   " you apply @python_2_unicode_compatible"
457  
-                                   " without defining __str__?" % klass_name)
458 453
             return force_text(self).encode('utf-8')
459 454
         return '%s object' % self.__class__.__name__
460 455
 
4  django/utils/encoding.py
@@ -28,6 +28,10 @@ def python_2_unicode_compatible(klass):
28 28
     returning text and apply this decorator to the class.
29 29
     """
30 30
     if six.PY2:
  31
+        if '__str__' not in klass.__dict__:
  32
+            raise ValueError("@python_2_unicode_compatible cannot be applied "
  33
+                             "to %s because it doesn't define __str__()." %
  34
+                             klass.__name__)
31 35
         klass.__unicode__ = klass.__str__
32 36
         klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
33 37
     return klass
3  tests/commands_sql/models.py
... ...
@@ -1,13 +1,10 @@
1 1
 from django.db import models
2  
-from django.utils.encoding import python_2_unicode_compatible
3 2
 
4 3
 
5  
-@python_2_unicode_compatible
6 4
 class Comment(models.Model):
7 5
     pass
8 6
 
9 7
 
10  
-@python_2_unicode_compatible
11 8
 class Book(models.Model):
12 9
     title = models.CharField(max_length=100, db_index=True)
13 10
     comments = models.ManyToManyField(Comment)
8  tests/str/models.py
@@ -28,14 +28,6 @@ def __str__(self):
28 28
         return self.headline
29 29
 
30 30
 @python_2_unicode_compatible
31  
-class BrokenArticle(models.Model):
32  
-    headline = models.CharField(max_length=100)
33  
-    pub_date = models.DateTimeField()
34  
-
35  
-    def __unicode__(self):      # instead of __str__
36  
-        return self.headline
37  
-
38  
-@python_2_unicode_compatible
39 31
 class InternationalArticle(models.Model):
40 32
     headline = models.CharField(max_length=100)
41 33
     pub_date = models.DateTimeField()
12  tests/str/tests.py
@@ -7,7 +7,7 @@
7 7
 from django.test import TestCase
8 8
 from django.utils import six
9 9
 
10  
-from .models import Article, BrokenArticle, InternationalArticle
  10
+from .models import Article, InternationalArticle
11 11
 
12 12
 
13 13
 class SimpleTests(TestCase):
@@ -21,16 +21,6 @@ def test_basic(self):
21 21
         self.assertEqual(str(a), str('Area man programs in Python'))
22 22
         self.assertEqual(repr(a), str('<Article: Area man programs in Python>'))
23 23
 
24  
-    @skipIf(six.PY3, "tests Model's default __str__ method under Python 2")
25  
-    def test_broken(self):
26  
-        # Regression test for #19362.
27  
-        a = BrokenArticle.objects.create(
28  
-            headline='Girl wins €12.500 in lottery',
29  
-            pub_date=datetime.datetime(2005, 7, 28)
30  
-        )
31  
-        six.assertRaisesRegex(self, RuntimeError, "Did you apply "
32  
-            "@python_2_unicode_compatible without defining __str__\?", str, a)
33  
-
34 24
     def test_international(self):
35 25
         a = InternationalArticle.objects.create(
36 26
             headline='Girl wins €12.500 in lottery',
10  tests/utils_tests/test_encoding.py
@@ -5,7 +5,8 @@
5 5
 import datetime
6 6
 
7 7
 from django.utils import six
8  
-from django.utils.encoding import force_bytes, force_text, filepath_to_uri
  8
+from django.utils.encoding import (force_bytes, force_text, filepath_to_uri,
  9
+        python_2_unicode_compatible)
9 10
 
10 11
 
11 12
 class TestEncodingUtils(unittest.TestCase):
@@ -43,3 +44,10 @@ def test_filepath_to_uri(self):
43 44
             'upload/%D1%87%D1%83%D0%B1%D0%B0%D0%BA%D0%B0.mp4')
44 45
         self.assertEqual(filepath_to_uri('upload\\чубака.mp4'.encode('utf-8')),
45 46
             'upload/%D1%87%D1%83%D0%B1%D0%B0%D0%BA%D0%B0.mp4')
  47
+
  48
+    @unittest.skipIf(six.PY3, "tests a class not defining __str__ under Python 2")
  49
+    def test_decorated_class_without_str(self):
  50
+        with self.assertRaises(ValueError):
  51
+            @python_2_unicode_compatible
  52
+            class NoStr(object):
  53
+                pass

0 notes on commit 589dc49

Please sign in to comment.
Something went wrong with that request. Please try again.