##// END OF EJS Templates
py3compat._modify_str_or_docstring should check against basestring
MinRK -
Show More
@@ -1,175 +1,175 b''
1 # coding: utf-8
1 # coding: utf-8
2 """Compatibility tricks for Python 3. Mainly to do with unicode."""
2 """Compatibility tricks for Python 3. Mainly to do with unicode."""
3 import __builtin__
3 import __builtin__
4 import functools
4 import functools
5 import sys
5 import sys
6 import re
6 import re
7 import types
7 import types
8
8
9 orig_open = open
9 orig_open = open
10
10
11 def no_code(x, encoding=None):
11 def no_code(x, encoding=None):
12 return x
12 return x
13
13
14 def decode(s, encoding=None):
14 def decode(s, encoding=None):
15 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
15 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
16 return s.decode(encoding, "replace")
16 return s.decode(encoding, "replace")
17
17
18 def encode(u, encoding=None):
18 def encode(u, encoding=None):
19 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
19 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
20 return u.encode(encoding, "replace")
20 return u.encode(encoding, "replace")
21
21
22 def cast_unicode(s, encoding=None):
22 def cast_unicode(s, encoding=None):
23 if isinstance(s, bytes):
23 if isinstance(s, bytes):
24 return decode(s, encoding)
24 return decode(s, encoding)
25 return s
25 return s
26
26
27 def cast_bytes(s, encoding=None):
27 def cast_bytes(s, encoding=None):
28 if not isinstance(s, bytes):
28 if not isinstance(s, bytes):
29 return encode(s, encoding)
29 return encode(s, encoding)
30 return s
30 return s
31
31
32 def _modify_str_or_docstring(str_change_func):
32 def _modify_str_or_docstring(str_change_func):
33 @functools.wraps(str_change_func)
33 @functools.wraps(str_change_func)
34 def wrapper(func_or_str):
34 def wrapper(func_or_str):
35 if isinstance(func_or_str, str):
35 if isinstance(func_or_str, basestring):
36 func = None
36 func = None
37 doc = func_or_str
37 doc = func_or_str
38 else:
38 else:
39 func = func_or_str
39 func = func_or_str
40 doc = func.__doc__
40 doc = func.__doc__
41
41
42 doc = str_change_func(doc)
42 doc = str_change_func(doc)
43
43
44 if func:
44 if func:
45 func.__doc__ = doc
45 func.__doc__ = doc
46 return func
46 return func
47 return doc
47 return doc
48 return wrapper
48 return wrapper
49
49
50 if sys.version_info[0] >= 3:
50 if sys.version_info[0] >= 3:
51 PY3 = True
51 PY3 = True
52
52
53 input = input
53 input = input
54 builtin_mod_name = "builtins"
54 builtin_mod_name = "builtins"
55
55
56 str_to_unicode = no_code
56 str_to_unicode = no_code
57 unicode_to_str = no_code
57 unicode_to_str = no_code
58 str_to_bytes = encode
58 str_to_bytes = encode
59 bytes_to_str = decode
59 bytes_to_str = decode
60 cast_bytes_py2 = no_code
60 cast_bytes_py2 = no_code
61
61
62 def isidentifier(s, dotted=False):
62 def isidentifier(s, dotted=False):
63 if dotted:
63 if dotted:
64 return all(isidentifier(a) for a in s.split("."))
64 return all(isidentifier(a) for a in s.split("."))
65 return s.isidentifier()
65 return s.isidentifier()
66
66
67 open = orig_open
67 open = orig_open
68
68
69 MethodType = types.MethodType
69 MethodType = types.MethodType
70
70
71 def execfile(fname, glob, loc=None):
71 def execfile(fname, glob, loc=None):
72 loc = loc if (loc is not None) else glob
72 loc = loc if (loc is not None) else glob
73 exec compile(open(fname).read(), fname, 'exec') in glob, loc
73 exec compile(open(fname).read(), fname, 'exec') in glob, loc
74
74
75 # Refactor print statements in doctests.
75 # Refactor print statements in doctests.
76 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
76 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
77 def _print_statement_sub(match):
77 def _print_statement_sub(match):
78 expr = match.groups('expr')
78 expr = match.groups('expr')
79 return "print(%s)" % expr
79 return "print(%s)" % expr
80
80
81 @_modify_str_or_docstring
81 @_modify_str_or_docstring
82 def doctest_refactor_print(doc):
82 def doctest_refactor_print(doc):
83 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
83 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
84 unfortunately doesn't pick up on our doctests.
84 unfortunately doesn't pick up on our doctests.
85
85
86 Can accept a string or a function, so it can be used as a decorator."""
86 Can accept a string or a function, so it can be used as a decorator."""
87 return _print_statement_re.sub(_print_statement_sub, doc)
87 return _print_statement_re.sub(_print_statement_sub, doc)
88
88
89 # Abstract u'abc' syntax:
89 # Abstract u'abc' syntax:
90 @_modify_str_or_docstring
90 @_modify_str_or_docstring
91 def u_format(s):
91 def u_format(s):
92 """"{u}'abc'" --> "'abc'" (Python 3)
92 """"{u}'abc'" --> "'abc'" (Python 3)
93
93
94 Accepts a string or a function, so it can be used as a decorator."""
94 Accepts a string or a function, so it can be used as a decorator."""
95 return s.format(u='')
95 return s.format(u='')
96
96
97 else:
97 else:
98 PY3 = False
98 PY3 = False
99
99
100 input = raw_input
100 input = raw_input
101 builtin_mod_name = "__builtin__"
101 builtin_mod_name = "__builtin__"
102
102
103 str_to_unicode = decode
103 str_to_unicode = decode
104 unicode_to_str = encode
104 unicode_to_str = encode
105 str_to_bytes = no_code
105 str_to_bytes = no_code
106 bytes_to_str = no_code
106 bytes_to_str = no_code
107 cast_bytes_py2 = cast_bytes
107 cast_bytes_py2 = cast_bytes
108
108
109 import re
109 import re
110 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
110 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
111 def isidentifier(s, dotted=False):
111 def isidentifier(s, dotted=False):
112 if dotted:
112 if dotted:
113 return all(isidentifier(a) for a in s.split("."))
113 return all(isidentifier(a) for a in s.split("."))
114 return bool(_name_re.match(s))
114 return bool(_name_re.match(s))
115
115
116 class open(object):
116 class open(object):
117 """Wrapper providing key part of Python 3 open() interface."""
117 """Wrapper providing key part of Python 3 open() interface."""
118 def __init__(self, fname, mode="r", encoding="utf-8"):
118 def __init__(self, fname, mode="r", encoding="utf-8"):
119 self.f = orig_open(fname, mode)
119 self.f = orig_open(fname, mode)
120 self.enc = encoding
120 self.enc = encoding
121
121
122 def write(self, s):
122 def write(self, s):
123 return self.f.write(s.encode(self.enc))
123 return self.f.write(s.encode(self.enc))
124
124
125 def read(self, size=-1):
125 def read(self, size=-1):
126 return self.f.read(size).decode(self.enc)
126 return self.f.read(size).decode(self.enc)
127
127
128 def close(self):
128 def close(self):
129 return self.f.close()
129 return self.f.close()
130
130
131 def __enter__(self):
131 def __enter__(self):
132 return self
132 return self
133
133
134 def __exit__(self, etype, value, traceback):
134 def __exit__(self, etype, value, traceback):
135 self.f.close()
135 self.f.close()
136
136
137 def MethodType(func, instance):
137 def MethodType(func, instance):
138 return types.MethodType(func, instance, type(instance))
138 return types.MethodType(func, instance, type(instance))
139
139
140 # don't override system execfile on 2.x:
140 # don't override system execfile on 2.x:
141 execfile = execfile
141 execfile = execfile
142
142
143 def doctest_refactor_print(func_or_str):
143 def doctest_refactor_print(func_or_str):
144 return func_or_str
144 return func_or_str
145
145
146
146
147 # Abstract u'abc' syntax:
147 # Abstract u'abc' syntax:
148 @_modify_str_or_docstring
148 @_modify_str_or_docstring
149 def u_format(s):
149 def u_format(s):
150 """"{u}'abc'" --> "u'abc'" (Python 2)
150 """"{u}'abc'" --> "u'abc'" (Python 2)
151
151
152 Accepts a string or a function, so it can be used as a decorator."""
152 Accepts a string or a function, so it can be used as a decorator."""
153 return s.format(u='u')
153 return s.format(u='u')
154
154
155 if sys.platform == 'win32':
155 if sys.platform == 'win32':
156 def execfile(fname, glob=None, loc=None):
156 def execfile(fname, glob=None, loc=None):
157 loc = loc if (loc is not None) else glob
157 loc = loc if (loc is not None) else glob
158 # The rstrip() is necessary b/c trailing whitespace in files will
158 # The rstrip() is necessary b/c trailing whitespace in files will
159 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
159 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
160 # but we still support 2.6). See issue 1027.
160 # but we still support 2.6). See issue 1027.
161 scripttext = __builtin__.open(fname).read().rstrip() + '\n'
161 scripttext = __builtin__.open(fname).read().rstrip() + '\n'
162 # compile converts unicode filename to str assuming
162 # compile converts unicode filename to str assuming
163 # ascii. Let's do the conversion before calling compile
163 # ascii. Let's do the conversion before calling compile
164 if isinstance(fname, unicode):
164 if isinstance(fname, unicode):
165 filename = unicode_to_str(fname)
165 filename = unicode_to_str(fname)
166 else:
166 else:
167 filename = fname
167 filename = fname
168 exec compile(scripttext, filename, 'exec') in glob, loc
168 exec compile(scripttext, filename, 'exec') in glob, loc
169 else:
169 else:
170 def execfile(fname, *where):
170 def execfile(fname, *where):
171 if isinstance(fname, unicode):
171 if isinstance(fname, unicode):
172 filename = fname.encode(sys.getfilesystemencoding())
172 filename = fname.encode(sys.getfilesystemencoding())
173 else:
173 else:
174 filename = fname
174 filename = fname
175 __builtin__.execfile(filename, *where)
175 __builtin__.execfile(filename, *where)
General Comments 0
You need to be logged in to leave comments. Login now