##// END OF EJS Templates
Fix for %run on a Python file using non-default encoding.
Thomas Kluyver -
Show More
@@ -1,242 +1,249 b''
1 """Tests for code execution (%run and related), which is particularly tricky.
1 """Tests for code execution (%run and related), which is particularly tricky.
2
2
3 Because of how %run manages namespaces, and the fact that we are trying here to
3 Because of how %run manages namespaces, and the fact that we are trying here to
4 verify subtle object deletion and reference counting issues, the %run tests
4 verify subtle object deletion and reference counting issues, the %run tests
5 will be kept in this separate file. This makes it easier to aggregate in one
5 will be kept in this separate file. This makes it easier to aggregate in one
6 place the tricks needed to handle it; most other magics are much easier to test
6 place the tricks needed to handle it; most other magics are much easier to test
7 and we do so in a common test_magic file.
7 and we do so in a common test_magic file.
8 """
8 """
9 from __future__ import absolute_import
9 from __future__ import absolute_import
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 import os
15 import os
16 import sys
16 import sys
17 import tempfile
17 import tempfile
18
18
19 import nose.tools as nt
19 import nose.tools as nt
20 from nose import SkipTest
20 from nose import SkipTest
21
21
22 from IPython.testing import decorators as dec
22 from IPython.testing import decorators as dec
23 from IPython.testing import tools as tt
23 from IPython.testing import tools as tt
24 from IPython.utils import py3compat
24 from IPython.utils import py3compat
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Test functions begin
27 # Test functions begin
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 def doctest_refbug():
30 def doctest_refbug():
31 """Very nasty problem with references held by multiple runs of a script.
31 """Very nasty problem with references held by multiple runs of a script.
32 See: https://github.com/ipython/ipython/issues/141
32 See: https://github.com/ipython/ipython/issues/141
33
33
34 In [1]: _ip.clear_main_mod_cache()
34 In [1]: _ip.clear_main_mod_cache()
35 # random
35 # random
36
36
37 In [2]: %run refbug
37 In [2]: %run refbug
38
38
39 In [3]: call_f()
39 In [3]: call_f()
40 lowercased: hello
40 lowercased: hello
41
41
42 In [4]: %run refbug
42 In [4]: %run refbug
43
43
44 In [5]: call_f()
44 In [5]: call_f()
45 lowercased: hello
45 lowercased: hello
46 lowercased: hello
46 lowercased: hello
47 """
47 """
48
48
49
49
50 def doctest_run_builtins():
50 def doctest_run_builtins():
51 r"""Check that %run doesn't damage __builtins__.
51 r"""Check that %run doesn't damage __builtins__.
52
52
53 In [1]: import tempfile
53 In [1]: import tempfile
54
54
55 In [2]: bid1 = id(__builtins__)
55 In [2]: bid1 = id(__builtins__)
56
56
57 In [3]: fname = tempfile.mkstemp('.py')[1]
57 In [3]: fname = tempfile.mkstemp('.py')[1]
58
58
59 In [3]: f = open(fname,'w')
59 In [3]: f = open(fname,'w')
60
60
61 In [4]: dummy= f.write('pass\n')
61 In [4]: dummy= f.write('pass\n')
62
62
63 In [5]: f.flush()
63 In [5]: f.flush()
64
64
65 In [6]: t1 = type(__builtins__)
65 In [6]: t1 = type(__builtins__)
66
66
67 In [7]: %run $fname
67 In [7]: %run $fname
68
68
69 In [7]: f.close()
69 In [7]: f.close()
70
70
71 In [8]: bid2 = id(__builtins__)
71 In [8]: bid2 = id(__builtins__)
72
72
73 In [9]: t2 = type(__builtins__)
73 In [9]: t2 = type(__builtins__)
74
74
75 In [10]: t1 == t2
75 In [10]: t1 == t2
76 Out[10]: True
76 Out[10]: True
77
77
78 In [10]: bid1 == bid2
78 In [10]: bid1 == bid2
79 Out[10]: True
79 Out[10]: True
80
80
81 In [12]: try:
81 In [12]: try:
82 ....: os.unlink(fname)
82 ....: os.unlink(fname)
83 ....: except:
83 ....: except:
84 ....: pass
84 ....: pass
85 ....:
85 ....:
86 """
86 """
87
87
88 @py3compat.doctest_refactor_print
88 @py3compat.doctest_refactor_print
89 def doctest_reset_del():
89 def doctest_reset_del():
90 """Test that resetting doesn't cause errors in __del__ methods.
90 """Test that resetting doesn't cause errors in __del__ methods.
91
91
92 In [2]: class A(object):
92 In [2]: class A(object):
93 ...: def __del__(self):
93 ...: def __del__(self):
94 ...: print str("Hi")
94 ...: print str("Hi")
95 ...:
95 ...:
96
96
97 In [3]: a = A()
97 In [3]: a = A()
98
98
99 In [4]: get_ipython().reset()
99 In [4]: get_ipython().reset()
100 Hi
100 Hi
101
101
102 In [5]: 1+1
102 In [5]: 1+1
103 Out[5]: 2
103 Out[5]: 2
104 """
104 """
105
105
106 # For some tests, it will be handy to organize them in a class with a common
106 # For some tests, it will be handy to organize them in a class with a common
107 # setup that makes a temp file
107 # setup that makes a temp file
108
108
109 class TestMagicRunPass(tt.TempFileMixin):
109 class TestMagicRunPass(tt.TempFileMixin):
110
110
111 def setup(self):
111 def setup(self):
112 """Make a valid python temp file."""
112 """Make a valid python temp file."""
113 self.mktmp('pass\n')
113 self.mktmp('pass\n')
114
114
115 def run_tmpfile(self):
115 def run_tmpfile(self):
116 _ip = get_ipython()
116 _ip = get_ipython()
117 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
117 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
118 # See below and ticket https://bugs.launchpad.net/bugs/366353
118 # See below and ticket https://bugs.launchpad.net/bugs/366353
119 _ip.magic('run %s' % self.fname)
119 _ip.magic('run %s' % self.fname)
120
120
121 def run_tmpfile_p(self):
121 def run_tmpfile_p(self):
122 _ip = get_ipython()
122 _ip = get_ipython()
123 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
123 # This fails on Windows if self.tmpfile.name has spaces or "~" in it.
124 # See below and ticket https://bugs.launchpad.net/bugs/366353
124 # See below and ticket https://bugs.launchpad.net/bugs/366353
125 _ip.magic('run -p %s' % self.fname)
125 _ip.magic('run -p %s' % self.fname)
126
126
127 def test_builtins_id(self):
127 def test_builtins_id(self):
128 """Check that %run doesn't damage __builtins__ """
128 """Check that %run doesn't damage __builtins__ """
129 _ip = get_ipython()
129 _ip = get_ipython()
130 # Test that the id of __builtins__ is not modified by %run
130 # Test that the id of __builtins__ is not modified by %run
131 bid1 = id(_ip.user_ns['__builtins__'])
131 bid1 = id(_ip.user_ns['__builtins__'])
132 self.run_tmpfile()
132 self.run_tmpfile()
133 bid2 = id(_ip.user_ns['__builtins__'])
133 bid2 = id(_ip.user_ns['__builtins__'])
134 tt.assert_equals(bid1, bid2)
134 tt.assert_equals(bid1, bid2)
135
135
136 def test_builtins_type(self):
136 def test_builtins_type(self):
137 """Check that the type of __builtins__ doesn't change with %run.
137 """Check that the type of __builtins__ doesn't change with %run.
138
138
139 However, the above could pass if __builtins__ was already modified to
139 However, the above could pass if __builtins__ was already modified to
140 be a dict (it should be a module) by a previous use of %run. So we
140 be a dict (it should be a module) by a previous use of %run. So we
141 also check explicitly that it really is a module:
141 also check explicitly that it really is a module:
142 """
142 """
143 _ip = get_ipython()
143 _ip = get_ipython()
144 self.run_tmpfile()
144 self.run_tmpfile()
145 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
145 tt.assert_equals(type(_ip.user_ns['__builtins__']),type(sys))
146
146
147 def test_prompts(self):
147 def test_prompts(self):
148 """Test that prompts correctly generate after %run"""
148 """Test that prompts correctly generate after %run"""
149 self.run_tmpfile()
149 self.run_tmpfile()
150 _ip = get_ipython()
150 _ip = get_ipython()
151 p2 = _ip.prompt_manager.render('in2').strip()
151 p2 = _ip.prompt_manager.render('in2').strip()
152 nt.assert_equals(p2[:3], '...')
152 nt.assert_equals(p2[:3], '...')
153
153
154 def test_run_profile( self ):
154 def test_run_profile( self ):
155 """Test that the option -p, which invokes the profiler, do not
155 """Test that the option -p, which invokes the profiler, do not
156 crash by invoking execfile"""
156 crash by invoking execfile"""
157 _ip = get_ipython()
157 _ip = get_ipython()
158 self.run_tmpfile_p()
158 self.run_tmpfile_p()
159
159
160
160
161 class TestMagicRunSimple(tt.TempFileMixin):
161 class TestMagicRunSimple(tt.TempFileMixin):
162
162
163 def test_simpledef(self):
163 def test_simpledef(self):
164 """Test that simple class definitions work."""
164 """Test that simple class definitions work."""
165 src = ("class foo: pass\n"
165 src = ("class foo: pass\n"
166 "def f(): return foo()")
166 "def f(): return foo()")
167 self.mktmp(src)
167 self.mktmp(src)
168 _ip.magic('run %s' % self.fname)
168 _ip.magic('run %s' % self.fname)
169 _ip.run_cell('t = isinstance(f(), foo)')
169 _ip.run_cell('t = isinstance(f(), foo)')
170 nt.assert_true(_ip.user_ns['t'])
170 nt.assert_true(_ip.user_ns['t'])
171
171
172 def test_obj_del(self):
172 def test_obj_del(self):
173 """Test that object's __del__ methods are called on exit."""
173 """Test that object's __del__ methods are called on exit."""
174 if sys.platform == 'win32':
174 if sys.platform == 'win32':
175 try:
175 try:
176 import win32api
176 import win32api
177 except ImportError:
177 except ImportError:
178 raise SkipTest("Test requires pywin32")
178 raise SkipTest("Test requires pywin32")
179 src = ("class A(object):\n"
179 src = ("class A(object):\n"
180 " def __del__(self):\n"
180 " def __del__(self):\n"
181 " print 'object A deleted'\n"
181 " print 'object A deleted'\n"
182 "a = A()\n")
182 "a = A()\n")
183 self.mktmp(py3compat.doctest_refactor_print(src))
183 self.mktmp(py3compat.doctest_refactor_print(src))
184 if dec.module_not_available('sqlite3'):
184 if dec.module_not_available('sqlite3'):
185 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
185 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
186 else:
186 else:
187 err = None
187 err = None
188 tt.ipexec_validate(self.fname, 'object A deleted', err)
188 tt.ipexec_validate(self.fname, 'object A deleted', err)
189
189
190 @dec.skip_known_failure
190 @dec.skip_known_failure
191 def test_aggressive_namespace_cleanup(self):
191 def test_aggressive_namespace_cleanup(self):
192 """Test that namespace cleanup is not too aggressive GH-238
192 """Test that namespace cleanup is not too aggressive GH-238
193
193
194 Returning from another run magic deletes the namespace"""
194 Returning from another run magic deletes the namespace"""
195 # see ticket https://github.com/ipython/ipython/issues/238
195 # see ticket https://github.com/ipython/ipython/issues/238
196 class secondtmp(tt.TempFileMixin): pass
196 class secondtmp(tt.TempFileMixin): pass
197 empty = secondtmp()
197 empty = secondtmp()
198 empty.mktmp('')
198 empty.mktmp('')
199 src = ("ip = get_ipython()\n"
199 src = ("ip = get_ipython()\n"
200 "for i in range(5):\n"
200 "for i in range(5):\n"
201 " try:\n"
201 " try:\n"
202 " ip.magic('run %s')\n"
202 " ip.magic('run %s')\n"
203 " except NameError, e:\n"
203 " except NameError, e:\n"
204 " print i;break\n" % empty.fname)
204 " print i;break\n" % empty.fname)
205 self.mktmp(py3compat.doctest_refactor_print(src))
205 self.mktmp(py3compat.doctest_refactor_print(src))
206 _ip.magic('run %s' % self.fname)
206 _ip.magic('run %s' % self.fname)
207 _ip.run_cell('ip == get_ipython()')
207 _ip.run_cell('ip == get_ipython()')
208 tt.assert_equals(_ip.user_ns['i'], 5)
208 tt.assert_equals(_ip.user_ns['i'], 5)
209
209
210 @dec.skip_win32
210 @dec.skip_win32
211 def test_tclass(self):
211 def test_tclass(self):
212 mydir = os.path.dirname(__file__)
212 mydir = os.path.dirname(__file__)
213 tc = os.path.join(mydir, 'tclass')
213 tc = os.path.join(mydir, 'tclass')
214 src = ("%%run '%s' C-first\n"
214 src = ("%%run '%s' C-first\n"
215 "%%run '%s' C-second\n"
215 "%%run '%s' C-second\n"
216 "%%run '%s' C-third\n") % (tc, tc, tc)
216 "%%run '%s' C-third\n") % (tc, tc, tc)
217 self.mktmp(src, '.ipy')
217 self.mktmp(src, '.ipy')
218 out = """\
218 out = """\
219 ARGV 1-: ['C-first']
219 ARGV 1-: ['C-first']
220 ARGV 1-: ['C-second']
220 ARGV 1-: ['C-second']
221 tclass.py: deleting object: C-first
221 tclass.py: deleting object: C-first
222 ARGV 1-: ['C-third']
222 ARGV 1-: ['C-third']
223 tclass.py: deleting object: C-second
223 tclass.py: deleting object: C-second
224 tclass.py: deleting object: C-third
224 tclass.py: deleting object: C-third
225 """
225 """
226 if dec.module_not_available('sqlite3'):
226 if dec.module_not_available('sqlite3'):
227 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
227 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
228 else:
228 else:
229 err = None
229 err = None
230 tt.ipexec_validate(self.fname, out, err)
230 tt.ipexec_validate(self.fname, out, err)
231
231
232 def test_run_i_after_reset(self):
232 def test_run_i_after_reset(self):
233 """Check that %run -i still works after %reset (gh-693)"""
233 """Check that %run -i still works after %reset (gh-693)"""
234 src = "yy = zz\n"
234 src = "yy = zz\n"
235 self.mktmp(src)
235 self.mktmp(src)
236 _ip.run_cell("zz = 23")
236 _ip.run_cell("zz = 23")
237 _ip.magic('run -i %s' % self.fname)
237 _ip.magic('run -i %s' % self.fname)
238 tt.assert_equals(_ip.user_ns['yy'], 23)
238 tt.assert_equals(_ip.user_ns['yy'], 23)
239 _ip.magic('reset -f')
239 _ip.magic('reset -f')
240 _ip.run_cell("zz = 23")
240 _ip.run_cell("zz = 23")
241 _ip.magic('run -i %s' % self.fname)
241 _ip.magic('run -i %s' % self.fname)
242 tt.assert_equals(_ip.user_ns['yy'], 23)
242 tt.assert_equals(_ip.user_ns['yy'], 23)
243
244 def test_unicode(self):
245 """Check that files in odd encodings are accepted."""
246 mydir = os.path.dirname(__file__)
247 na = os.path.join(mydir, 'nonascii.py')
248 _ip.magic('run %s' % na)
249 tt.assert_equals(_ip.user_ns['u'], u'ΠŽΡ‚β„–Π€')
@@ -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, str):
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, 'rb').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