Ticket #21733: 21733.patch

File 21733.patch, 2.4 KB (added by Aymeric Augustin, 11 years ago)
  • django/utils/encoding.py

    commit d71e54a8bba804fe10a8919fe21d0f2fae7cdc52
    Author: Aymeric Augustin <aymeric.augustin@m4x.org>
    Date:   Sat Jan 4 20:52:24 2014 +0100
    
        Fixed #21733 -- Infinite recursion in @python_2_unicode_compatible.
        
        Applying the decorator twice to the same class now raises an exception
        instead of triggering an infinite recursion.
        
        Thanks ntucker for the report.
    
    diff --git a/django/utils/encoding.py b/django/utils/encoding.py
    index ee67df3..8a32d7f 100644
    a b def python_2_unicode_compatible(klass):  
    3434            raise ValueError("@python_2_unicode_compatible cannot be applied "
    3535                             "to %s because it doesn't define __str__()." %
    3636                             klass.__name__)
     37        elif hasattr(klass.__str__, '_python_2_unicode_compatible'):
     38            raise ValueError("@python_2_unicode_compatible was already "
     39                             "applied to %s." % klass.__name__)
    3740        klass.__unicode__ = klass.__str__
    38         klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
     41        def new_str(self):
     42            return klass.__unicode__(self).encode('utf-8')
     43        new_str._python_2_unicode_compatible = None
     44        klass.__str__ = new_str
    3945    return klass
    4046
    4147
  • tests/utils_tests/test_encoding.py

    diff --git a/tests/utils_tests/test_encoding.py b/tests/utils_tests/test_encoding.py
    index a91f596..1516637 100644
    a b  
    11# -*- encoding: utf-8 -*-
     2
    23from __future__ import unicode_literals
    34
    45import unittest
    class TestEncodingUtils(unittest.TestCase):  
    4748
    4849    @unittest.skipIf(six.PY3, "tests a class not defining __str__ under Python 2")
    4950    def test_decorated_class_without_str(self):
    50         with self.assertRaises(ValueError):
     51        with six.assertRaisesRegex(self, ValueError, "doesn't define __str__"):
    5152            @python_2_unicode_compatible
    5253            class NoStr(object):
    5354                pass
     55
     56    @unittest.skipIf(six.PY3, "tests a class not redefining __str__ under Python 2")
     57    def test_twice_decorated_class(self):
     58        with six.assertRaisesRegex(self, ValueError, "already applied"):
     59            @python_2_unicode_compatible
     60            @python_2_unicode_compatible
     61            class Str(object):
     62                def __str__(self):
     63                    return b''
Back to Top