11"Test InteractiveConsole and InteractiveInterpreter from code module"
22import sys
3+ import traceback
34import unittest
45from textwrap import dedent
56from contextlib import ExitStack
@@ -30,6 +31,7 @@ def mock_sys(self):
3031
3132
3233class TestInteractiveConsole (unittest .TestCase , MockSys ):
34+ maxDiff = None
3335
3436 def setUp (self ):
3537 self .console = code .InteractiveConsole ()
@@ -61,21 +63,118 @@ def test_console_stderr(self):
6163 raise AssertionError ("no console stdout" )
6264
6365 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' )]
6570 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 )
71113
72114 def test_sysexcepthook (self ):
73- self .infunc .side_effect = ["raise ValueError('')" ,
115+ self .infunc .side_effect = ["def f():" ,
116+ " raise ValueError('BOOM!')" ,
117+
6D38
"" ,
118+ "f()" ,
74119 EOFError ('Finished' )]
75120 hook = mock .Mock ()
76121 self .sysmod .excepthook = hook
77122 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 ' ])
79178
80179 def test_sysexcepthook_crashing_doesnt_close_repl (self ):
81180 self .infunc .side_effect = ["1/0" , "a = 123" , "print(a)" , EOFError ('Finished' )]
@@ -167,6 +266,11 @@ def test_cause_tb(self):
167266 ValueError
168267 """ )
169268 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 )
170274
171275 def test_context_tb (self ):
172276 self .infunc .side_effect = ["try: ham\n except: eggs\n " ,
@@ -185,6 +289,11 @@ def test_context_tb(self):
185289 NameError: name 'eggs' is not defined
186290 """ )
187291 self .assertIn (expected , output )
292
38BA
code>+ 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 )
188297
189298
190299class TestInteractiveConsoleLocalExit (unittest .TestCase , MockSys ):
0 commit comments