Skip to content

Commit 31f3cd0

Browse files
committed
using dispatch to implement force_bytes and force_text
1 parent 2cfa5d7 commit 31f3cd0

1 file changed

Lines changed: 74 additions & 50 deletions

File tree

wolframclient/utils/encoding.py

Lines changed: 74 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,87 @@
11
from __future__ import absolute_import, print_function, unicode_literals
22

33
from wolframclient.utils import six
4+
from wolframclient.utils.dispatch import Dispatch
45
from wolframclient.utils.functional import map
56

7+
force_text = Dispatch()
68

7-
def force_text(s, encoding="utf-8", errors="strict"):
8-
"""
9-
Similar to smart_text, except that lazy instances are resolved to
10-
strings, rather than kept as lazy objects.
11-
12-
If strings_only is True, don't convert (some) non-string-like objects.
13-
"""
14-
# Handle the common case first for performance reasons.
15-
if isinstance(s, six.text_type):
16-
return s
17-
if not isinstance(s, six.string_types):
18-
if six.PY3:
19-
if isinstance(s, bytes):
20-
s = six.text_type(s, encoding, errors)
21-
else:
22-
s = six.text_type(s)
23-
elif hasattr(s, "__unicode__"):
24-
s = six.text_type(s)
9+
10+
@force_text.dispatch(six.text_type)
11+
def encode(s, encoding="utf-8", errors="strict"):
12+
return s
13+
14+
15+
@force_text.dispatch(six.binary_type, replace_existing=True)
16+
def encode(s, encoding="utf-8", errors="strict"):
17+
return s.decode(encoding, errors)
18+
19+
20+
if not six.PY2:
21+
22+
@force_text.dispatch(object)
23+
def encode(s, encoding="utf-8", errors="strict"):
24+
return six.text_type(s)
25+
26+
27+
else:
28+
29+
@force_text.dispatch(object)
30+
def encode(s, encoding="utf-8", errors="strict"):
31+
if hasattr(s, "__unicode__"):
32+
return six.text_type(s)
2533
else:
26-
s = six.text_type(bytes(s), encoding, errors)
27-
else:
28-
# Note: We use .decode() here, instead of six.text_type(s, encoding,
29-
# errors), so that if s is a SafeBytes, it ends up being a
30-
# SafeText at the end.
31-
s = s.decode(encoding, errors)
34+
return six.text_type(bytes(s), encoding, errors)
35+
36+
37+
force_bytes = Dispatch()
38+
39+
40+
@force_bytes.dispatch(six.string_types)
41+
def encode(s, encoding="utf-8", errors="strict"):
42+
return s.encode(encoding, errors)
43+
44+
45+
@force_bytes.dispatch(six.binary_type, replace_existing=True)
46+
def encode(s, encoding="utf-8", errors="strict"):
3247
return s
3348

3449

35-
def force_bytes(s, encoding="utf-8", errors="strict"):
36-
"""
37-
If strings_only is True, don't convert (some) non-string-like objects.
38-
"""
39-
# Handle the common case first for performance reasons.
40-
if isinstance(s, bytes):
41-
return s
42-
43-
if isinstance(s, six.buffer_types):
44-
return bytes(s)
45-
46-
if not isinstance(s, six.string_types):
47-
try:
48-
if six.PY3:
49-
return six.text_type(s).encode(encoding)
50-
else:
51-
return bytes(s)
52-
except UnicodeEncodeError:
53-
if isinstance(s, Exception):
54-
# An Exception subclass containing non-ASCII data that doesn't
55-
# know how to print itself properly. We shouldn't raise a
56-
# further exception.
57-
return b" ".join(force_bytes(arg, encoding, errors=errors) for arg in s)
58-
return six.text_type(s).encode(encoding, errors)
59-
else:
60-
return s.encode(encoding, errors)
50+
@force_bytes.dispatch(six.buffer_types, replace_existing=True)
51+
def encode(s, encoding="utf-8", errors="strict"):
52+
return six.binary_type(s)
53+
54+
55+
if six.PY2:
56+
57+
@force_bytes.dispatch(memoryview, replace_existing=True)
58+
def encode(s, encoding="utf-8", errors="strict"):
59+
return s.tobytes()
60+
61+
62+
if not six.PY2:
63+
64+
def encode_default(s, encoding="utf-8", errors="strict"):
65+
return six.text_type(s).encode(encoding)
66+
67+
68+
else:
69+
70+
def encode_default(s, encoding="utf-8", errors="strict"):
71+
return six.binary_type(s)
72+
73+
74+
@force_bytes.dispatch(object)
75+
def encode(s, encoding="utf-8", errors="strict"):
76+
try:
77+
return encode_default(s, encoding, errors)
78+
except UnicodeEncodeError:
79+
if isinstance(s, Exception):
80+
# An Exception subclass containing non-ASCII data that doesn't
81+
# know how to print itself properly. We shouldn't raise a
82+
# further exception.
83+
return b" ".join(force_bytes(arg, encoding, errors=errors) for arg in s)
84+
return six.text_type(s).encode(encoding, errors)
6185

6286

6387
def safe_force_text(obj):

0 commit comments

Comments
 (0)