Pypy + django 1.7.1 = ValueError:@ python_2_unicode_compatible不能应用于CheckMessage,因为它没有定义__str __()

时间:2015-01-02 18:19:41

标签: django django-admin pypy

我安装了pypy和django框架版本1.7.1

执行django-admin.py错误:

$ django-admin
Traceback (most recent call last):
  File "app_main.py", line 51, in run_toplevel
  File "/home/se7en/.virtualenvs/pypyenv/bin/django-admin", line 9, in <module>
    load_entry_point('Django==1.7.1', 'console_scripts', 'django-admin')()
  File "/home/se7en/.virtualenvs/pypyenv/site-packages/distribute-0.6.24-py2.7.egg/pkg_resources.py", line 337, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/home/se7en/.virtualenvs/pypyenv/site-packages/distribute-0.6.24-py2.7.egg/pkg_resources.py", line 2279, in load_entry_point
    return ep.load()
  File "/home/se7en/.virtualenvs/pypyenv/site-packages/distribute-0.6.24-py2.7.egg/pkg_resources.py", line 1989, in load
    entry = __import__(self.module_name, globals(),globals(), ['__name__'])
  File "/home/se7en/.virtualenvs/pypyenv/site-packages/django/core/management/__init__.py", line 11, in <module>
    from django.core.management.base import BaseCommand, CommandError, handle_default_options
  File "/home/se7en/.virtualenvs/pypyenv/site-packages/django/core/management/base.py", line 17, in <module>
    from django.core import checks
  File "/home/se7en/.virtualenvs/pypyenv/site-packages/django/core/checks/__init__.py", line 4, in <module>
    from .messages import (CheckMessage,
  File "/home/se7en/.virtualenvs/pypyenv/site-packages/django/core/checks/messages.py", line 16, in <module>
    class CheckMessage(object):
  File "/home/se7en/.virtualenvs/pypyenv/site-packages/django/utils/encoding.py", line 36, in python_2_unicode_compatible
    klass.__name__)
ValueError: @python_2_unicode_compatible cannot be applied to CheckMessage because it doesn't define __str__().

任何django版本都会发生此错误&gt; 1.6

1 个答案:

答案 0 :(得分:0)

似乎pypy(模拟Python 2.7)以不同方式实现__str____unicode__,以致'__str__' in klass.__dict__失败。

这会导致Django utils中的“encoding.py”和“html.py”失败。将这些重写为“try / except”块可以解决问题(有些人会认为这也是更好的风格)。

可以在以下代码中看到更改:

的django / utils的/ encoding.py:

...
def python_2_unicode_compatible(klass):
        """
        A decorator that defines __unicode__ and __str__ methods under Python 2.
        Under Python 3 it does nothing.

        To support Python 2 and 3 with a single code base, define a __str__ method
        returning text and apply this decorator to the class.
        """
        if six.PY2:
            #if '__str__' not in klass.__dict__:
            #    raise ValueError("@python_2_unicode_compatible cannot be applied "
            #                     "to %s because it doesn't define __str__()." %
            #                     klass.__name__)
            #klass.__unicode__ = klass.__str__
            #klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
            try:
                klass.__unicode__ = klass.__str__
            except AttributeError:
                raise ValueError("@python_2_unicode_compatible cannot be applied "
                                 "to %s because it doesn't define __str__()." %
                                 klass.__name__)
            klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
        return klass
...

的django / utils的/ html.py:

...
def html_safe(klass):
        """
        A decorator that defines the __html__ method. This helps non-Django
        templates to detect classes whose __str__ methods return SafeText.
        """
        if '__html__' in klass.__dict__:
            raise ValueError(
                "can't apply @html_safe to %s because it defines "
                "__html__()." % klass.__name__
            )
        if six.PY2:
            #if '__unicode__' not in klass.__dict__:
                #raise ValueError(
                    #"can't apply @html_safe to %s because it doesn't "
                    #"define __unicode__()." % klass.__name__
                #)
            #klass_unicode = klass.__unicode__
            #klass.__unicode__ = lambda self: mark_safe(klass_unicode(self))
            #klass.__html__ = lambda self: unicode(self)  # NOQA: unicode undefined on PY3

            try:
                klass_unicode = klass.__unicode__
            except AttributeError:
                raise ValueError(
                    "can't apply @html_safe to %s because it doesn't "
                    "define __unicode__()." % klass.__name__
                )
            klass.__unicode__ = lambda self: mark_safe(klass_unicode(self))
            klass.__html__ = lambda self: unicode(self)  # NOQA: unicode undefined on PY3
        else:
            #if '__str__' not in klass.__dict__:
                #raise ValueError(
                    #"can't apply @html_safe to %s because it doesn't "
                    #"define __str__()." % klass.__name__
                #)
            #klass_str = klass.__str__
            #klass.__str__ = lambda self: mark_safe(klass_str(self))
            #klass.__html__ = lambda self: str(self)
            try:
                klass_str = klass.__str__
            except AttributeError:
                raise ValueError(
                    "can't apply @html_safe to %s because it doesn't "
                    "define __str__()." % klass.__name__
                )
            klass.__str__ = lambda self: mark_safe(klass_str(self))
            klass.__html__ = lambda self: str(self)
        return klass