Pypy+django 1.7.1=ValueError: @python_2_unicode_compatible不能用于CheckMessage,因为它不定义__str__()

时间:2022-04-29 13:25:02

I install pypy and django framework version 1.7.1

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

on execute django-admin.py error:

在执行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__().

this error happens on any django version > 1.6

这个错误发生在任何django版本> 1.6中。

1 个解决方案

#1


0  

It appears that pypy (emulating Python 2.7) implements __str__ and __unicode__ differently so that '__str__' in klass.__dict__ fails.

看起来pypy(仿真Python 2.7)实现了__str__和__unicode__,从而在klass中实现了“__str__”。__dict__失败。

This causes a failure in "encoding.py" and "html.py" in Django utils. Rewriting these as "try/except" blocks solves the problem (some would argue that this is better style too).

这导致了“编码”的失败。py”和“html。py Django跑龙套。将它们重写为“尝试/除去”块可以解决问题(有些人会认为这也是更好的风格)。

The changes can be seen in the code below:

这些变化可以在下面的代码中看到:

django/utils/encoding.py:

django /跑龙套/ 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:

django /跑龙套/ 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

#1


0  

It appears that pypy (emulating Python 2.7) implements __str__ and __unicode__ differently so that '__str__' in klass.__dict__ fails.

看起来pypy(仿真Python 2.7)实现了__str__和__unicode__,从而在klass中实现了“__str__”。__dict__失败。

This causes a failure in "encoding.py" and "html.py" in Django utils. Rewriting these as "try/except" blocks solves the problem (some would argue that this is better style too).

这导致了“编码”的失败。py”和“html。py Django跑龙套。将它们重写为“尝试/除去”块可以解决问题(有些人会认为这也是更好的风格)。

The changes can be seen in the code below:

这些变化可以在下面的代码中看到:

django/utils/encoding.py:

django /跑龙套/ 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:

django /跑龙套/ 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