11"Test InteractiveConsole and InteractiveInterpreter from code module"
2+ import os
23import sys
34import traceback
45import unittest
@@ -44,7 +45,7 @@ def test_ps1(self):
4445 "code.sys.ps1" ,
4546 EOFError ('Finished' )
4647 ]
47- self .console .interact ()
48+ self .console .interact (use_pyrepl = False )
4849 output = '' .join ('' .join (call [1 ]) for call in self .stdout .method_calls )
4950 self .assertIn ('>>> ' , output )
5051 self .assertNotHasAttr (self .sysmod , 'ps1' )
@@ -55,7 +56,7 @@ def test_ps1(self):
5556 EOFError ('Finished' )
5657 ]
5758 self .sysmod .ps1 = 'custom1> '
58- self .console .interact ()
59+ self .console .interact (use_pyrepl = False )
5960 output = '' .join ('' .join (call [1 ]) for call in self .stdout .method_calls )
6061 self .assertIn ('custom1> ' , output )
6162 self .assertEqual (self .sysmod .ps1 , 'custom1> ' )
@@ -66,7 +67,7 @@ def test_ps2(self):
6667 "code.sys.ps2" ,
6768 EOFError ('Finished' )
6869 ]
69- self .console .interact ()
70+ self .console .interact (use_pyrepl = False )
7071 output = '' .join ('' .join (call [1 ]) for call in self .stdout .method_calls )
7172 self .assertIn ('... ' , output )
7273 self .assertNotHasAttr (self .sysmod , 'ps2' )
@@ -77,14 +78,14 @@ def test_ps2(self):
7778 EOFError ('Finished' )
7879 ]
7980 self .sysmod .ps2 = 'custom2> '
80- self .console .interact ()
81+ self .console .interact (use_pyrepl = False )
8182 output = '' .join ('' .join (call [1 ]) for call in self .stdout .method_calls )
8283 self .assertIn ('custom2> ' , output )
8384 self .assertEqual (self .sysmod .ps2 , 'custom2> ' )
8485
8586 def test_console_stderr (self ):
8687 self .infunc .side_effect = ["'antioch'" , "" , EOFError ('Finished' )]
87- self .console .interact ()
88+ self .console .interact (use_pyrepl = False )
8889 for call in list (self .stdout .method_calls ):
8990 if 'antioch' in '' .join (call [1 ]):
9091 break
@@ -96,7 +97,7 @@ def test_syntax_error(self):
9697 " x = ?" ,
9798 "" ,
9899 EOFError ('Finished' )]
99- self .console .interact ()
100+ self .console .interact (use_pyrepl = False )
100101 output = '' .join ('' .join (call [1 ]) for call in self .stderr .method_calls )
101102 output = output [output .index ('(InteractiveConsole)' ):]
102103 output = output [:output .index ('\n now exiting' )]
@@ -113,7 +114,7 @@ def test_syntax_error(self):
113114
114115 def test_indentation_error (self ):
115116 self .infunc .side_effect = [" 1" , EOFError ('Finished' )]
116- self .console .interact ()
117+ self .console .interact (use_pyrepl = False )
117118 output = '' .join ('' .join (call [1 ]) for call in self .stderr .method_calls )
118119 output = output [output .index ('(InteractiveConsole)' ):]
119120 output = output [:output .index ('\n now exiting' )]
@@ -129,7 +130,7 @@ def test_indentation_error(self):
129130
130131 def test_unicode_error (self ):
131132 self .infunc .side_effect = ["'\ud800 '" , EOFError ('Finished' )]
132- self .console .interact ()
133+ self .console .interact (use_pyrepl = False )
133134 output = '' .join ('' .join (call [1 ]) for call in self .stderr .method_calls )
134135 output = output [output .index ('(InteractiveConsole)' ):]
135136 output = output [output .index ('\n ' ) + 1 :]
@@ -148,7 +149,7 @@ def test_sysexcepthook(self):
148149 EOFError ('Finished' )]
149150 hook = mock .Mock ()
150151 self .sysmod .excepthook = hook
151- self .console .interact ()
152+ self .console .interact (use_pyrepl = False )
152153 hook .assert_called ()
153154 hook .assert_called_with (self .sysmod .last_type ,
154155 self .sysmod .last_value ,
@@ -170,7 +171,7 @@ def test_sysexcepthook_syntax_error(self):
170171 EOFError ('Finished' )]
171172 hook = mock .Mock ()
172173 self .sysmod .excepthook = hook
173- self .console .interact ()
174+ self .console .interact (use_pyrepl = False )
174175 hook .assert_called ()
175176 hook .assert_called_with (self .sysmod .last_type ,
176177 self .sysmod .last_value ,
@@ -190,7 +191,7 @@ def test_sysexcepthook_indentation_error(self):
190191 self .infunc .side_effect = [" 1" , EOFError ('Finished' )]
191192 hook = mock .Mock ()
192193 self .sysmod .excepthook = hook
193- self .console .interact ()
194+ self .console .interact (use_pyrepl = False )
194195 hook .assert_called ()
195196 hook .assert_called_with (self .sysmod .last_type ,
196197 self .sysmod .last_value ,
@@ -208,7 +209,7 @@ def test_sysexcepthook_indentation_error(self):
208209 def test_sysexcepthook_crashing_doesnt_close_repl (self ):
209210 self .infunc .side_effect = ["1/0" , "a = 123" , "print(a)" , EOFError ('Finished' )]
210211 self .sysmod .excepthook = 1
211- self .console .interact ()
212+ self .console .interact (use_pyrepl = False )
212213 self .assertEqual (['write' , ('123' , ), {}], self .stdout .method_calls [0 ])
213214 error = "" .join (call .args [0 ] for call in self .stderr .method_calls if call [0 ] == 'write' )
214215 self .assertIn ("Error in sys.excepthook:" , error )
@@ -222,7 +223,7 @@ def test_sysexcepthook_raising_BaseException(self):
222223 def raise_base (* args , ** kwargs ):
223224 raise BaseException (s )
224225 self .sysmod .excepthook = raise_base
225- self .console .interact ()
226+ self .console .interact (use_pyrepl = False )
226227 self .assertEqual (['write' , ('123' , ), {}], self .stdout .method_calls [0 ])
227228 error = "" .join (call .args [0 ] for call in self .stderr .method_calls if call [0 ] == 'write' )
228229 self .assertIn ("Error in sys.excepthook:" , error )
@@ -236,26 +237,26 @@ def raise_base(*args, **kwargs):
236237 raise SystemExit
237238 self .sysmod .excepthook = raise_base
238239 with self .assertRaises (SystemExit ):
239- self .console .interact ()
240+ self .console .interact (use_pyrepl = False )
240241
241242 def test_banner (self ):
242243 # with banner
243244 self .infunc .side_effect = EOFError ('Finished' )
244- self .console .interact (banner = 'Foo' )
245+ self .console .interact (banner = 'Foo' , use_pyrepl = False )
245246 self .assertEqual (len (self .stderr .method_calls ), 3 )
246247 banner_call = self .stderr .method_calls [0 ]
247248 self .assertEqual (banner_call , ['write' , ('Foo\n ' ,), {}])
248249
249250 # no banner
250251 self .stderr .reset_mock ()
251252 self .infunc .side_effect = EOFError ('Finished' )
252- self .console .interact (banner = '' )
253+ self .console .interact (banner = '' , use_pyrepl = False )
253254 self .assertEqual (len (self .stderr .method_calls ), 2 )
254255
255256 def test_exit_msg (self ):
256257 # default exit message
257258 self .infunc .side_effect = EOFError ('Finished' )
258- self .console .interact (banner = '' )
259+ self .console .interact (banner = '' , use_pyrepl = False )
259260 self .assertEqual (len (self .stderr .method_calls ), 2 )
260261 err_msg = self .stderr .method_calls [1 ]
261262 expected = 'now exiting InteractiveConsole...\n '
@@ -264,7 +265,7 @@ def test_exit_msg(self):
264265 # no exit message
265266 self .stderr .reset_mock ()
266267 self .infunc .side_effect = EOFError ('Finished' )
267- self .console .interact (banner = '' , exitmsg = '' )
268+ self .console .interact (banner = '' , exitmsg = '' , use_pyrepl = False )
268269 self .assertEqual (len (self .stderr .method_calls ), 1 )
269270
270271 # custom exit message
@@ -273,7 +274,7 @@ def test_exit_msg(self):
273274 'bye! \N{GREEK SMALL LETTER ZETA} \N{CYRILLIC SMALL LETTER ZHE} '
274275 )
275276 self .infunc .side_effect = EOFError ('Finished' )
276- self .console .interact (banner = '' , exitmsg = message )
277+ self .console .interact (banner = '' , exitmsg = message , use_pyrepl = False )
277278 self .assertEqual (len (self .stderr .method_calls ), 2 )
278279 err_msg = self .stderr .method_calls [1 ]
279280 expected = message + '\n '
@@ -283,7 +284,7 @@ def test_exit_msg(self):
283284 def test_cause_tb (self ):
284285 self .infunc .side_effect = ["raise ValueError('') from AttributeError" ,
285286 EOFError ('Finished' )]
286- self .console .interact ()
287+ self .console .interact (use_pyrepl = False )
287288 output = '' .join ('' .join (call [1 ]) for call in self .stderr .method_calls )
288289 expected = dedent ("""
289290 AttributeError
@@ -304,7 +305,7 @@ def test_cause_tb(self):
304305 def test_context_tb (self ):
305306 self .infunc .side_effect = ["try: ham\n except: eggs\n " ,
306307 EOFError ('Finished' )]
307- self .console .interact ()
308+ self .console .interact (use_pyrepl = False )
308309 output = '' .join ('' .join (call [1 ]) for call in self .stderr .method_calls )
309310 expected = dedent ("""
310311 Traceback (most recent call last):
@@ -335,12 +336,60 @@ def setUp(self):
335336 def test_exit (self ):
336337 # default exit message
337338 self .infunc .side_effect = ["exit()" ]
338- self .console .interact (banner = '' )
339+ self .console .interact (banner = '' , use_pyrepl = False )
339340 self .assertEqual (len (self .stderr .method_calls ), 2 )
340341 err_msg = self .stderr .method_calls [1 ]
341342 expected = 'now exiting InteractiveConsole...\n '
342343 self .assertEqual (err_msg , ['write' , (expected ,), {}])
343344
344345
346+ class TestInteractiveConsoleUsePyrepl (unittest .TestCase , MockSys ):
347+ """Tests for the use_pyrepl parameter of InteractiveConsole.interact()."""
348+
349+ def setUp (self ):
350+ self .console = code .InteractiveConsole ()
351+ self .mock_sys ()
352+
353+ def test_use_pyrepl_false_uses_basic_repl (self ):
354+ """When use_pyrepl=False, the basic REPL should be used."""
355+ self .infunc .side_effect = ["'test'" , EOFError ('Finished' )]
356+ self .console .interact (banner = '' , use_pyrepl = False )
357+ # Should have used code.input (the basic REPL)
358+ self .infunc .assert_called ()
359+
360+ @mock .patch .object (os , 'getenv' , return_value = '1' )
361+ def test_python_basic_repl_env_uses_basic_repl (self , mock_getenv ):
362+ """When PYTHON_BASIC_REPL is set, the basic REPL should be used."""
363+ self .infunc .side_effect = ["'test'" , EOFError ('Finished' )]
364+ self .console .interact (banner = '' )
365+ # Should have used code.input (the basic REPL)
366+ self .infunc .assert_called ()
367+
368+ def test_use_pyrepl_false_with_input (self ):
369+ """Test that use_pyrepl=False correctly processes input."""
370+ self .infunc .side_effect = [
371+ "x = 1" ,
372+ "x" ,
373+ EOFError ('Finished' )
374+ ]
375+ self .console .interact (banner = '' , use_pyrepl = False )
376+ output = '' .join ('' .join (call [1 ]) for call in self .stdout .method_calls )
377+ self .assertIn ('1' , output )
378+
379+
380+ class TestInteractFunctionUsePyrepl (unittest .TestCase , MockSys ):
381+ """Tests for the use_pyrepl parameter of the top-level interact() function."""
382+
383+ def setUp (self ):
384+ self .mock_sys ()
385+
386+ def test_interact_use_pyrepl_false (self ):
387+ """When use_pyrepl=False, the basic REPL should be used."""
388+ self .infunc .side_effect = ["'test'" , EOFError ('Finished' )]
389+ with mock .patch ('code.input' , create = True , side_effect = self .infunc ):
390+ code .interact (banner = '' , use_pyrepl = False )
391+ self .infunc .assert_called ()
392+
393+
345394if __name__ == "__main__" :
346395 unittest .main ()
0 commit comments