33from __future__ import unicode_literals
44
55import sys
6+ import re
7+ from textwrap import dedent
68
79from curtsies .fmtfuncs import bold , green , magenta , cyan , red , plain
810
1315pypy = 'PyPy' in sys .version
1416
1517
18+ def remove_ansi (s ):
19+ return re .sub (r'(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]' .encode ('ascii' ), b'' , s )
20+
21+
1622class TestInterpreter (unittest .TestCase ):
17- def test_syntaxerror (self ):
23+ def interp_errlog (self ):
1824 i = interpreter .Interp ()
1925 a = []
26+ i .write = a .append
27+ return i , a
28+
29+ def err_lineno (self , a ):
30+ strings = [x .__unicode__ () for x in a ]
31+ print ('looking for lineno' )
32+ for line in reversed (strings ):
33+ clean_line = remove_ansi (line )
34+ print (clean_line )
35+ m = re .search (r'line (\d+)[,]' , clean_line )
36+ if m :
37+ print ('found!' , m .group (1 ))
38+ return int (m .group (1 ))
39+ return None
2040
21- def append_to_a ( message ):
22- a . append ( message )
41+ def test_syntaxerror ( self ):
42+ i , a = self . interp_errlog ( )
2343
24- i .write = append_to_a
2544 i .runsource ('1.1.1.1' )
2645
2746 if pypy :
@@ -41,13 +60,7 @@ def append_to_a(message):
4160 self .assertEquals (plain ('' ).join (a ), expected )
4261
4362 def test_traceback (self ):
44- i = interpreter .Interp ()
45- a = []
46-
47- def append_to_a (message ):
48- a .append (message )
49-
50- i .write = append_to_a
63+ i , a = self .interp_errlog ()
5164
5265 def f ():
5366 return 1 / 0
@@ -88,22 +101,22 @@ def test_runsource_bytes_over_128_syntax_error_py3(self):
88101 i = interpreter .Interp (encoding = b'latin-1' )
89102 i .showsyntaxerror = mock .Mock (return_value = None )
90103
91- i .runsource ("a = b'\xfe '" , encode = True )
104+ i .runsource ("a = b'\xfe '" )
92105 i .showsyntaxerror .assert_called_with (mock .ANY )
93106
94107 @unittest .skipIf (py3 , "encode is Python 2 only" )
95108 def test_runsource_bytes_over_128_syntax_error_py2 (self ):
96109 i = interpreter .Interp (encoding = b'latin-1' )
97110
98- i .runsource (b"a = b'\xfe '" , encode = True )
111+ i .runsource (b"a = b'\xfe '" )
99112 self .assertIsInstance (i .locals ['a' ], type (b'' ))
100113 self .assertEqual (i .locals ['a' ], b"\xfe " )
101114
102115 @unittest .skipIf (py3 , "encode is Python 2 only" )
103116 def test_runsource_unicode (self ):
104117 i = interpreter .Interp (encoding = b'latin-1' )
105118
106- i .runsource ("a = u'\xfe '" , encode = True )
119+ i .runsource ("a = u'\xfe '" )
107120 self .assertIsInstance (i .locals ['a' ], type (u'' ))
108121 self .assertEqual (i .locals ['a' ], u"\xfe " )
109122
@@ -114,3 +127,119 @@ def test_getsource_works_on_interactively_defined_functions(self):
114127 import inspect
115128 inspected_source = inspect .getsource (i .locals ['foo' ])
116129 self .assertEquals (inspected_source , source )
130+
131+ @unittest .skipIf (py3 , "encode only does anything in Python 2" )
132+ def test_runsource_unicode_autoencode_and_noencode (self ):
133+ """error line numbers should be fixed"""
134+
135+ # Since correct behavior for unicode is the same
136+ # for auto and False, run the same tests
137+ for encode in ['auto' , False ]:
138+ i , a = self .interp_errlog ()
139+ i .runsource (u'[1 + 1,\n abc]' , encode = encode )
140+ self .assertEqual (self .err_lineno (a ), 2 )
141+
142+ i , a = self .interp_errlog ()
143+ i .runsource (u'[1 + 1,\n abc]' , encode = encode )
144+ self .assertEqual (self .err_lineno (a ), 2 )
145+
146+ i , a = self .interp_errlog ()
147+ i .runsource (u'#encoding: utf-8\n abc' , encode = encode )
148+ self .assertEqual (self .err_lineno (a ), 2 )
149+
150+ i , a = self .interp_errlog ()
151+ i .runsource (u'#encoding: utf-8\n abc' ,
152+ filename = 'x.py' , encode = encode )
153+ self .assertIn ('SyntaxError: encoding' ,
154+ '' .join ('' .join (remove_ansi (x .__unicode__ ()) for x in a )))
155+
156+ @unittest .skipIf (py3 , "encode only does anything in Python 2" )
157+ def test_runsource_unicode_encode (self ):
158+ i , _ = self .interp_errlog ()
159+ with self .assertRaises (ValueError ):
160+ i .runsource (u'1 + 1' , encode = True )
161+
162+ i , _ = self .interp_errlog ()
163+ with self .assertRaises (ValueError ):
164+ i .runsource (u'1 + 1' , filename = 'x.py' , encode = True )
165+
166+ @unittest .skipIf (py3 , "encode only does anything in Python 2" )
167+ def test_runsource_bytestring_noencode (self ):
168+ i , a = self .interp_errlog ()
169+ i .runsource (b'[1 + 1,\n abc]' , encode = False )
170+ self .assertEqual (self .err_lineno (a ), 2 )
171+
172+ i , a = self .interp_errlog ()
173+ i .runsource (b'[1 + 1,\n abc]' , filename = 'x.py' , encode = False )
174+ self .assertEqual (self .err_lineno (a ), 2 )
175+
176+ i , a = self .interp_errlog ()
177+ i .runsource (dedent (b'''\
178+ #encoding: utf-8
179+
180+ ["%s",
181+ abc]''' % (u'åß∂ƒ' .encode ('utf8' ),)), encode = False )
182+ self .assertEqual (self .err_lineno (a ), 4 )
183+
184+ i , a = self .interp_errlog ()
185+ i .runsource (dedent (b'''\
186+ #encoding: utf-8
187+
188+ ["%s",
189+ abc]''' % (u'åß∂ƒ' .encode ('utf8' ),)),
190+ filename = 'x.py' , encode = False )
191+ self .assertEqual (self .err_lineno (a ), 4 )
192+
193+ @unittest .skipIf (py3 , "encode only does anything in Python 2" )
194+ def test_runsource_bytestring_encode (self ):
195+ i , a = self .interp_errlog ()
196+ i .runsource (b'[1 + 1,\n abc]' , encode = True )
197+ self .assertEqual (self .err_lineno (a ), 2 )
198+
199+ i , a = self .interp_errlog ()
200+ with self .assertRaises (ValueError ):
201+ i .runsource (b'[1 + 1,\n abc]' , filename = 'x.py' , encode = True )
202+
203+ i , a = self .interp_errlog ()
204+ i .runsource (dedent (b'''\
205+ #encoding: utf-8
206+
207+ [u"%s",
208+ abc]''' % (u'åß∂ƒ' .encode ('utf8' ),)), encode = True )
209+ self .assertEqual (self .err_lineno (a ), 4 )
210+
211+ i , a = self .interp_errlog ()
212+ with self .assertRaises (ValueError ):
213+ i .runsource (dedent (b'''\
214+ #encoding: utf-8
215+
216+ [u"%s",
217+ abc]''' % (u'åß∂ƒ' .encode ('utf8' ),)),
218+ filename = 'x.py' ,
219+ encode = True )
220+
221+ @unittest .skipIf (py3 , "encode only does anything in Python 2" )
222+ def test_runsource_bytestring_autoencode (self ):
223+ i , a = self .interp_errlog ()
224+ i .runsource (b'[1 + 1,\n abc]' )
225+ self .assertEqual (self .err_lineno (a ), 2 )
226+
227+ i , a = self .interp_errlog ()
228+ i .runsource (b'[1 + 1,\n abc]' , filename = 'x.py' )
229+ self .assertEqual (self .err_lineno (a ), 2 )
230+
231+ i , a = self .interp_errlog ()
232+ i .runsource (dedent (b'''\
233+ #encoding: utf-8
234+
235+ [u"%s",
236+ abc]''' % (u'åß∂ƒ' .encode ('utf8' ),)))
237+ self .assertEqual (self .err_lineno (a ), 4 )
238+
239+ i , a = self .interp_errlog ()
240+ i .runsource (dedent (b'''\
241+ #encoding: utf-8
242+
243+ [u"%s",
244+ abc]''' % (u'åß∂ƒ' .encode ('utf8' ),)))
245+ self .assertEqual (self .err_lineno (a ), 4 )
0 commit comments