I am converting code from python2 to python3 for
newstyle classes using
future. My project is in Django 1.11
I have a class in forms.py as:
class Address: ...rest of code... class AddressForm(Address, forms.ModelForm): ...rest of code...
in Python 2
which is converted to :
from buitlins import object class Address(object): ...rest of code... class AddressForm(Address, forms.ModelForm): ...rest of code...
in Python 3
I have a selenium test that fails when this Form is invoked after it is converted to Python3 with the following error:
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
However, when I remove the import
from buitlins import object the test passes.
But as I have added a future check, I get a future difference error & thus every class has to be converted to newstyle. I want it to work in both Python2 and Python3.
Is there a way this module
builtins module import can affect just one class and not others in the
forms.py file. Or is there some other method to handle this?
The problem you’re running up against seems to be from two different Python 2 modernization tools fighting. You seem to be using the
python_2_unicode_compatible decorator from
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
and inheriting from
newobject, which has this
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')
And because the two have slightly different strategies for providing both
__str__ methods, they ed up calling each other infinitely, which leads to your recursion error.
The module that provides builtins.object provides its own
python_2_unicode_compatible decorator. Have you tried using that over the one from