11"Test InteractiveConsole and InteractiveInterpreter from code module"
22import sys
3+ import traceback
34import unittest
45from textwrap import dedent
56from contextlib import ExitStack
1112
1213
1314class TestInteractiveConsole (unittest .TestCase ):
15+ maxDiff = None
1416
1517 def setUp (self ):
1618 self .console = code .InteractiveConsole ()
@@ -58,21 +60,118 @@ def test_console_stderr(self):
5860 raise AssertionError ("no console stdout" )
5961
6062 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' )]
6267 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 )
68110
69111 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()" ,
71116 EOFError ('Finished' )]
72117 hook = mock .Mock ()
73118 self .sysmod .excepthook = hook
74119 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 ' ])
76175
77176 def test_sysexcepthook_crashing_doesnt_close_repl (self ):
78177 self .infunc .side_effect = ["1/0" , "a = 123" , "print(a)" , EOFError ('Finished' )]
@@ -164,6 +263,11 @@ def test_cause_tb(self):
164263 ValueError
165264 """ )
166265 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 )
167271
168272 def test_context_tb (self ):
169273 self .infunc .side_effect = ["try: ham\n except: eggs\n " ,
@@ -182,6 +286,11 @@ def test_context_tb(self):
182286 NameError: name 'eggs' is not defined
183287 """ )
184288 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 )
185294
186295
187296if __name__ == "__main__" :
0 commit comments