|
1 | 1 | """ |
2 | | -This module redefines str on Python 2.x to be the unicode type. |
| 2 | +This module redefines str on Python 2.x to be the unicode type and |
| 3 | +provides a decorator called python_2_unicode_compatible to be applied to |
| 4 | +classes. |
3 | 5 |
|
4 | 6 | It is designed to be used together with the unicode_literals import as |
5 | 7 | follows: |
|
25 | 27 |
|
26 | 28 | This module is designed to be imported together with unicode_literals on |
27 | 29 | Python 2 to bring the meaning of str() back into alignment with |
28 | | -unprefixed |
29 | | -string literals. |
| 30 | +unprefixed string literals. |
| 31 | +
|
| 32 | +Note that str() would then normally call the __unicode__ method on |
| 33 | +objects in Python 2. Therefore this module also defines a simple |
| 34 | +decorator called python_2_unicode_compatible (borrowed from |
| 35 | +django.utils.encoding) which defines __unicode__ and __str__ methods |
| 36 | +under Python 2. To support Python 2 and 3 with a single code base, simply |
| 37 | +define a __str__ method returning text and apply the |
| 38 | +python_2_unicode_compatible decorator to the class like this::: |
| 39 | +
|
| 40 | + from future import str_is_unicode |
| 41 | +
|
| 42 | + @python_2_unicode_compatible |
| 43 | + class MyClass(object): |
| 44 | + def __str__(self): |
| 45 | + return u'Unicode string: \u5b54\u5b50' |
| 46 | +
|
| 47 | + a = MyClass() |
| 48 | +
|
| 49 | +Then this is True on both Python 3 and 2::: |
| 50 | +
|
| 51 | + str(a) == bytes(a).decode('utf-8') |
| 52 | +
|
| 53 | +and, on a Unicode-enabled terminal with the right fonts, these both print |
| 54 | +the Chinese name of Confucius::: |
| 55 | +
|
| 56 | + print(a) |
| 57 | + print(str(a)) |
30 | 58 |
|
31 | | -Note that str() will then call the __unicode__ method on objects in |
32 | | -Python 2, whereas print() will call __str__. |
33 | 59 | """ |
34 | 60 |
|
35 | 61 | from __future__ import unicode_literals |
36 | 62 |
|
| 63 | +import __builtin__ |
37 | 64 | import inspect |
| 65 | +import imp |
| 66 | +import logging |
38 | 67 |
|
39 | 68 | from . import six |
40 | 69 |
|
41 | 70 |
|
| 71 | +def python_2_unicode_compatible(klass): |
| 72 | + """ |
| 73 | + A decorator that defines __unicode__ and __str__ methods under Python |
| 74 | + 2. Under Python 3 it does nothing. |
| 75 | + |
| 76 | + To support Python 2 and 3 with a single code base, define a __str__ |
| 77 | + method returning text and apply this decorator to the class. |
| 78 | +
|
| 79 | + The implementation comes from django.utils.encoding. |
| 80 | + """ |
| 81 | + if not six.PY3: |
| 82 | + klass.__unicode__ = klass.__str__ |
| 83 | + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') |
| 84 | + return klass |
| 85 | + |
| 86 | + |
42 | 87 | if not six.PY3: |
43 | 88 | caller = inspect.currentframe().f_back |
44 | 89 | caller.f_globals['str'] = unicode |
|
0 commit comments