-
Notifications
You must be signed in to change notification settings - Fork 295
Open
Description
Given a Python 2 codebase that already uses __future__ imports heavily, when dynamically creating classes, the first argument of type() is wrapped in str().
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals
Thing = type(str('Thing'), (object, ), {'attribute': 5})
thing = Thing()
print(thing.attribute) # 5When running futurize, the str() gets replaced with the newstr from builtins
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals
from builtins import str
Thing = type(str('Thing'), (object, ), {'attribute': 5}) # TypeError
thing = Thing()
print(thing.attribute)However, because type() expects the first argument to be a string type, it throws an error when running on Python 2:
Traceback (most recent call last):
File "/snip/type_example.py", line 5, in <module>
Thing = type(str('Thing'), (object, ), {'attribute': 5})
TypeError: type() argument 1 must be string, not newstr
This seems like a bug because it breaks Python 2 compatibility.
Instead, the code should be replaced with:
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals
from future.utils import bytes_to_native_str
Thing = type(bytes_to_native_str(b'Thing'), (object, ), {'attribute': 5})
thing = Thing()
print(thing.attribute)This will make the code compatible with both Python 2 and Python 3.
Metadata
Metadata
Assignees
Labels
No labels