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