~ubuntu-branches/debian/sid/python-django/sid

« back to all changes in this revision

Viewing changes to django/utils/encoding.py

  • Committer: Package Import Robot
  • Author(s): Raphaël Hertzog
  • Date: 2014-09-17 14:15:11 UTC
  • mfrom: (1.3.17) (6.2.18 experimental)
  • Revision ID: package-import@ubuntu.com-20140917141511-icneokthe9ww5sk4
Tags: 1.7-2
* Release to unstable.
* Add a migrate-south sample script to help users apply their South
  migrations. Thanks to Brian May.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
import datetime
5
5
from decimal import Decimal
6
6
import locale
7
 
import warnings
8
7
 
9
8
from django.utils.functional import Promise
10
9
from django.utils import six
11
10
from django.utils.six.moves.urllib.parse import quote
12
11
 
 
12
 
13
13
class DjangoUnicodeDecodeError(UnicodeDecodeError):
14
14
    def __init__(self, obj, *args):
15
15
        self.obj = obj
20
20
        return '%s. You passed in %r (%s)' % (original, self.obj,
21
21
                type(self.obj))
22
22
 
23
 
class StrAndUnicode(object):
24
 
    """
25
 
    A class that derives __str__ from __unicode__.
26
 
 
27
 
    On Python 2, __str__ returns the output of __unicode__ encoded as a UTF-8
28
 
    bytestring. On Python 3, __str__ returns the output of __unicode__.
29
 
 
30
 
    Useful as a mix-in. If you support Python 2 and 3 with a single code base,
31
 
    you can inherit this mix-in and just define __unicode__.
32
 
    """
33
 
    def __init__(self, *args, **kwargs):
34
 
        warnings.warn("StrAndUnicode is deprecated. Define a __str__ method "
35
 
                      "and apply the @python_2_unicode_compatible decorator "
36
 
                      "instead.", DeprecationWarning, stacklevel=2)
37
 
        super(StrAndUnicode, self).__init__(*args, **kwargs)
38
 
 
39
 
    if six.PY3:
40
 
        def __str__(self):
41
 
            return self.__unicode__()
42
 
    else:
43
 
        def __str__(self):
44
 
            return self.__unicode__().encode('utf-8')
45
23
 
46
24
def python_2_unicode_compatible(klass):
47
25
    """
60
38
        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
61
39
    return klass
62
40
 
 
41
 
63
42
def smart_text(s, encoding='utf-8', strings_only=False, errors='strict'):
64
43
    """
65
44
    Returns a text object representing 's' -- unicode on Python 2 and str on
72
51
        return s
73
52
    return force_text(s, encoding, strings_only, errors)
74
53
 
 
54
 
75
55
def is_protected_type(obj):
76
56
    """Determine if the object instance is of a protected type.
77
57
 
81
61
    return isinstance(obj, six.integer_types + (type(None), float, Decimal,
82
62
        datetime.datetime, datetime.date, datetime.time))
83
63
 
 
64
 
84
65
def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
85
66
    """
86
67
    Similar to smart_text, except that lazy instances are resolved to
88
69
 
89
70
    If strings_only is True, don't convert (some) non-string-like objects.
90
71
    """
91
 
    # Handle the common case first, saves 30-40% when s is an instance of
92
 
    # six.text_type. This function gets called often in that setting.
 
72
    # Handle the common case first for performance reasons.
93
73
    if isinstance(s, six.text_type):
94
74
        return s
95
75
    if strings_only and is_protected_type(s):
96
76
        return s
97
77
    try:
98
78
        if not isinstance(s, six.string_types):
99
 
            if hasattr(s, '__unicode__'):
100
 
                s = s.__unicode__()
101
 
            else:
102
 
                if six.PY3:
103
 
                    if isinstance(s, bytes):
104
 
                        s = six.text_type(s, encoding, errors)
105
 
                    else:
106
 
                        s = six.text_type(s)
 
79
            if six.PY3:
 
80
                if isinstance(s, bytes):
 
81
                    s = six.text_type(s, encoding, errors)
107
82
                else:
108
 
                    s = six.text_type(bytes(s), encoding, errors)
 
83
                    s = six.text_type(s)
 
84
            elif hasattr(s, '__unicode__'):
 
85
                s = six.text_type(s)
 
86
            else:
 
87
                s = six.text_type(bytes(s), encoding, errors)
109
88
        else:
110
89
            # Note: We use .decode() here, instead of six.text_type(s, encoding,
111
90
            # errors), so that if s is a SafeBytes, it ends up being a
124
103
                    errors) for arg in s])
125
104
    return s
126
105
 
 
106
 
127
107
def smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
128
108
    """
129
109
    Returns a bytestring version of 's', encoded as specified in 'encoding'.
143
123
 
144
124
    If strings_only is True, don't convert (some) non-string-like objects.
145
125
    """
146
 
    if isinstance(s, six.memoryview):
147
 
        s = bytes(s)
 
126
    # Handle the common case first for performance reasons.
148
127
    if isinstance(s, bytes):
149
128
        if encoding == 'utf-8':
150
129
            return s
151
130
        else:
152
131
            return s.decode('utf-8', errors).encode(encoding, errors)
153
 
    if strings_only and (s is None or isinstance(s, int)):
 
132
    if strings_only and is_protected_type(s):
154
133
        return s
 
134
    if isinstance(s, six.memoryview):
 
135
        return bytes(s)
155
136
    if isinstance(s, Promise):
156
137
        return six.text_type(s).encode(encoding, errors)
157
138
    if not isinstance(s, six.string_types):
181
162
    smart_unicode = smart_text
182
163
    force_unicode = force_text
183
164
 
184
 
smart_str.__doc__ = """\
 
165
smart_str.__doc__ = """
185
166
Apply smart_text in Python 3 and smart_bytes in Python 2.
186
167
 
187
168
This is suitable for writing to sys.stdout (for instance).
188
169
"""
189
170
 
190
 
force_str.__doc__ = """\
 
171
force_str.__doc__ = """
191
172
Apply force_text in Python 3 and force_bytes in Python 2.
192
173
"""
193
174
 
 
175
 
194
176
def iri_to_uri(iri):
195
177
    """
196
178
    Convert an Internationalized Resource Identifier (IRI) portion to a URI
218
200
        return iri
219
201
    return quote(force_bytes(iri), safe=b"/#%[]=:;$&()+,!?*@'~")
220
202
 
 
203
 
221
204
def filepath_to_uri(path):
222
205
    """Convert a file system path to a URI portion that is suitable for
223
206
    inclusion in a URL.
237
220
    # some flexibility for hardcoding separators.
238
221
    return quote(force_bytes(path).replace(b"\\", b"/"), safe=b"/~!*()'")
239
222
 
 
223
 
240
224
def get_system_encoding():
241
225
    """
242
226
    The encoding of the default system locale but falls back to the given