我正在使用newstyle
将future
类的代码从python2转换为python3。我的项目在Django 1.11中
我在forms.py中有一个类:
class Address:
...rest of code...
class AddressForm(Address, forms.ModelForm):
...rest of code...
在Python 2中
转换为:
from buitlins import object
class Address(object):
...rest of code...
class AddressForm(Address, forms.ModelForm):
...rest of code...
在Python 3中
我有一个硒测试,将其转换为Python3后调用此Form时,失败,并出现以下错误:
File "<path_to_venv>/local/lib/python2.7/site-packages/django/utils/six.py", line 842, in <lambda>
klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
File "<path_to_venv>/local/lib/python2.7/site-packages/future/types/newobject.py", line 78, in __unicode__
s = type(self).__str__(self)
RuntimeError: maximum recursion depth exceeded
但是,当我删除导入from buitlins import object
时,测试即通过。
但是当我添加了将来的检查时,我得到了将来的差异错误,因此每个类都必须转换为newstyle。我希望它在Python2和Python3中都能工作。
此模块builtins
模块的导入是否可以影响forms.py
文件中的一个类,而不会影响其他类。还是有其他方法可以解决这个问题?
答案 0 :(得分:4)
您遇到的问题似乎来自两个不同的Python 2现代化工具的对抗。您似乎正在使用django.utils.six
python_2_unicode_compatible
装饰器
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 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')
return klass
并从具有此__unicode__
方法的newobject
继承
def __unicode__(self):
# All subclasses of the builtin object should have __str__ defined.
# Note that old-style classes do not have __str__ defined.
if hasattr(self, '__str__'):
s = type(self).__str__(self)
else:
s = str(self)
if isinstance(s, unicode):
return s
else:
return s.decode('utf-8')
并且由于两者在提供__unicode__
和__str__
方法方面的策略略有不同,因此他们烦躁地无限调用彼此,这会导致递归错误。
提供builtins.object的模块提供了自己的python_2_unicode_compatible
装饰器。您是否尝试过使用django.utils.six
中的那个?
答案 1 :(得分:0)
这是python2方式。
"MyPrivateLibrary.podspec passed validation"
在python3类中,对象隐式继承了对象,因此应该像这样;
class Address(object):
答案 2 :(得分:0)
今天就讨论这个问题,Patrick Haugh主要描述了问题,除了在Django 1.11(问题中的版本以及我正在使用的版本)中未引用six和python_2_unicode_compatible
。在我们的案例中,问题在于django模型是从mixin继承的,mixin是从future.builtins.newobject
继承的。
object.__unicode__
:https://github.com/django/django/blob/stable/1.11.x/django/utils/encoding.py#L77 __unicode__
是未来软件包中__str__
的包装__str__
被实现为django https://github.com/django/django/blob/stable/1.11.x/django/db/models/base.py#L595 我们没有很好的解决方案,除了如果我们需要同时将Future导入为from builtins import object as future_object
之外,还可以通过运行futurize --stage2 -x object
而不是futurize --stage2
来禁用整个修订,< / p>