1
1
"Test InteractiveConsole and InteractiveInterpreter from code module"
2
2
import sys
3
+ import traceback
3
4
import unittest
4
5
from textwrap import dedent
5
6
from contextlib import ExitStack
11
12
12
13
13
14
class TestInteractiveConsole (unittest .TestCase ):
15
+ maxDiff = None
14
16
15
17
def setUp (self ):
16
18
self .console = code .InteractiveConsole ()
@@ -58,21 +60,118 @@ def test_console_stderr(self):
58
60
raise AssertionError ("no console stdout" )
59
61
60
62
def test_syntax_error (self ):
61
- self .infunc .side_effect = ["undefined" , EOFError ('Finished' )]
63
+ self .infunc .side_effect = ["def f():" ,
64
+ " x = ?" ,
65
+ "" ,
66
+ EOFError ('Finished' )]
62
67
self .console .interact ()
63
- for call in self .stderr .method_calls :
64
- if 'NameError' in '' .join (call [1 ]):
65
- break
66
- else :
67
- raise AssertionError ("No syntax error from console" )
68
+ output = '' .join ('' .join (call [1 ]) for call in self .stderr .method_calls )
69
+ output = output [output .index ('(InteractiveConsole)' ):]
70
+ output = output [:output .index ('\n now exiting' )]
71
+ self .assertEqual (output .splitlines ()[1 :], [
72
+ ' File "<console>", line 2' ,
73
+ ' x = ?' ,
74
+ ' ^' ,
75
+ 'SyntaxError: invalid syntax' ])
76
+ self .assertIs (self .sysmod .last_type , SyntaxError )
77
+ self .assertIs (type (self .sysmod .last_value ), SyntaxError )
78
+ self .assertIsNone (self .sysmod .last_traceback )
79
+ self .assertIsNone (self .sysmod .last_value .__traceback__ )
80
+ self .assertIs (self .sysmod .last_exc , self .sysmod .last_value )
81
+
82
+ def test_indentation_error (self ):
83
+ self .infunc .side_effect = [" 1" , EOFError ('Finished' )]
84
+ self .console .interact ()
85
+ output = '' .join ('' .join (call [1 ]) for call in self .stderr .method_calls )
86
+ output = output [output .index ('(InteractiveConsole)' ):]
87
+ output = output [:output .index ('\n now exiting' )]
88
+ self .assertEqual (output .splitlines ()[1 :], [
89
+ ' File "<console>", line 1' ,
90
+ ' 1' ,
91
+ 'IndentationError: unexpected indent' ])
92
+ self .assertIs (self .sysmod .last_type , IndentationError )
93
+ self .assertIs (type (self .sysmod .last_value ), IndentationError )
94
+ self .assertIsNone (self .sysmod .last_traceback )
95
+ self .assertIsNone (self .sysmod .last_value .__traceback__ )
96
+ self .assertIs (self .sysmod .last_exc , self .sysmod .last_value )
97
+
98
+ def test_unicode_error (self ):
99
+ self .infunc .side_effect = ["'\ud800 '" , EOFError ('Finished' )]
100
+ self .console .interact ()
101
+ output = '' .join ('' .join (call [1 ]) for call in self .stderr .method_calls )
102
+ output = output [output .index ('(InteractiveConsole)' ):]
103
+ output = output [output .index ('\n ' ) + 1 :]
104
+ self .assertTrue (output .startswith ('UnicodeEncodeError: ' ), output )
105
+ self .assertIs (self .sysmod .last_type , UnicodeEncodeError )
106
+ self .assertIs (type (self .sysmod .last_value ), UnicodeEncodeError )
107
+ self .assertIsNone (self .sysmod .last_traceback )
108
+ self .assertIsNone (self .sysmod .last_value .__traceback__ )
109
+ self .assertIs (self .sysmod .last_exc , self .sysmod .last_value )
68
110
69
111
def test_sysexcepthook (self ):
70
- self .infunc .side_effect = ["raise ValueError('')" ,
112
+ self .infunc .side_effect = ["def f():" ,
113
+ " raise ValueError('BOOM!')" ,
114
+ "" ,
115
+ "f()" ,
71
116
EOFError ('Finished' )]
72
117
hook = mock .Mock ()
73
118
self .sysmod .excepthook = hook
74
119
self .console .interact ()
75
- self .assertTrue (hook .called )
120
+ hook .assert_called ()
121
+ hook .assert_called_with (self .sysmod .last_type ,
122
+ self .sysmod .last_value ,
123
+ self .sysmod .last_traceback )
124
+ self .assertIs (self .sysmod .last_type , ValueError )
125
+ self .assertIs (type (self .sysmod .last_value ), ValueError )
126
+ self .assertIs (self .sysmod .last_traceback , self .sysmod .last_value .__traceback__ )
127
+ self .assertIs (self .sysmod .last_exc , self .sysmod .last_value )
128
+ self .assertEqual (traceback .format_exception (self .sysmod .last_exc ), [
129
+ 'Traceback (most recent call last):\n ' ,
130
+ ' File "<console>", line 1, in <module>\n ' ,
131
+ ' File "<console>", line 2, in f\n ' ,
132
+ 'ValueError: BOOM!\n ' ])
133
+
134
+ def test_sysexcepthook_syntax_error (self ):
135
+ self .infunc .side_effect = ["def f():" ,
136
+ " x = ?" ,
137
+ "" ,
138
+ EOFError ('Finished' )]
139
+ hook = mock .Mock ()
140
+ self .sysmod .excepthook = hook
141
+ self .console .interact ()
142
+ hook .assert_called ()
143
+ hook .assert_called_with (self .sysmod .last_type ,
144
+ self .sysmod .last_value ,
145
+ self .sysmod .last_traceback )
146
+ self .assertIs (self .sysmod .last_type , SyntaxError )
147
+ self .assertIs (type (self .sysmod .last_value ), SyntaxError )
148
+ self .assertIsNone (self .sysmod .last_traceback )
149
+ self .assertIsNone (self .sysmod .last_value .__traceback__ )
150
+ self .assertIs (self .sysmod .last_exc , self .sysmod .last_value )
151
+ self .assertEqual (traceback .format_exception (self .sysmod .last_exc ), [
152
+ ' File "<console>", line 2\n ' ,
153
+ ' x = ?\n ' ,
154
+ ' ^\n ' ,
155
+ 'SyntaxError: invalid syntax\n ' ])
156
+
157
+ def test_sysexcepthook_indentation_error (self ):
158
+ self .infunc .side_effect = [" 1" , EOFError ('Finished' )]
159
+ hook = mock .Mock ()
160
+ self .sysmod .excepthook = hook
161
+ self .console .interact ()
162
+ hook .assert_called ()
163
+ hook .assert_called_with (self .sysmod .last_type ,
164
+ self .sysmod .last_value ,
165
+ self .sysmod .last_traceback )
166
+ self .assertIs (self .sysmod .last_type , IndentationError )
167
+ self .assertIs (type (self .sysmod .last_value ), IndentationError )
168
+ self .assertIsNone (self .sysmod .last_traceback )
169
+ self .assertIsNone (self .sysmod .last_value .__traceback__ )
170
+ self .assertIs (self .sysmod .last_exc , self .sysmod .last_value )
171
+ self .assertEqual (traceback .format_exception (self .sysmod .last_exc ), [
172
+ ' File "<console>", line 1\n ' ,
173
+ ' 1\n ' ,
174
+ 'IndentationError: unexpected indent\n ' ])
76
175
77
176
def test_sysexcepthook_crashing_doesnt_close_repl (self ):
78
177
self .infunc .side_effect = ["1/0" , "a = 123" , "print(a)" , EOFError ('Finished' )]
@@ -164,6 +263,11 @@ def test_cause_tb(self):
164
263
ValueError
165
264
""" )
166
265
self .assertIn (expected , output )
266
+ self .assertIs (self .sysmod .last_type , ValueError )
267
+ self .assertIs (type (self .sysmod .last_value ), ValueError )
268
+ self .assertIs (self .sysmod .last_traceback , self .sysmod .last_value .__traceback__ )
269
+ self .assertIsNotNone (self .sysmod .last_traceback )
270
+ self .assertIs (self .sysmod .last_exc , self .sysmod .last_value )
167
271
168
272
def test_context_tb (self ):
169
273
self .infunc .side_effect = ["try: ham\n except: eggs\n " ,
@@ -182,6 +286,11 @@ def test_context_tb(self):
182
286
NameError: name 'eggs' is not defined
183
287
""" )
184
288
self .assertIn (expected , output )
289
+ self .assertIs (self .sysmod .last_type , NameError )
290
+ self .assertIs (type (self .sysmod .last_value ), NameError )
291
+ self .assertIs (self .sysmod .last_traceback , self .sysmod .last_value .__traceback__ )
292
+ self .assertIsNotNone (self .sysmod .last_traceback )
293
+ self .assertIs (self .sysmod .last_exc , self .sysmod .last_value )
185
294
186
295
187
296
if __name__ == "__main__" :
0 commit comments