66import io
77import os
88import pdb
9+ import re
910import sys
1011import types
1112import codecs
@@ -5006,6 +5007,20 @@ def setUpClass(cls):
50065007 if readline .backend == "editline" :
50075008 raise unittest .SkipTest ("libedit readline is not supported for pdb" )
50085009
5010+ def _run_pty (self , script , input , env = None ):
5011+ if env is None :
5012+ # By default, we use basic repl for the test.
5013+ # Subclass can overwrite this method and set env to use advanced REPL
5014+ env = os .environ | {'PYTHON_BASIC_REPL' : '1' }
5015+ output = run_pty (script , input , env = env )
5016+ # filter all control characters
5017+ # Strip ANSI CSI sequences (good enough for most REPL/prompt output)
5018+ output = re .sub (r"\x1b\[[0-?]*[ -/]*[@-~]" , "" , output .decode ("utf-8" ))
5019+ return output
5020+
5021+ def _pyrepl_available (self ):
5022+ return pdb ._pyrepl_available ()
5023+
50095024 def test_basic_completion (self ):
50105025 script = textwrap .dedent ("""
50115026 import pdb; pdb.Pdb().set_trace()
@@ -5017,12 +5032,12 @@ def test_basic_completion(self):
50175032 # then add ntin and complete 'contin' to 'continue'
50185033 input = b"co\t \t ntin\t \n "
50195034
5020- output = run_pty (script , input )
5035+ output = self . _run_pty (script , input )
50215036
5022- self .assertIn (b 'commands' , output )
5023- self .assertIn (b 'condition' , output )
5024- self .assertIn (b 'continue' , output )
5025- self .assertIn (b 'hello!' , output )
5037+ self .assertIn ('commands' , output )
5038+ self .assertIn ('condition' , output )
5039+ self .assertIn ('continue' , output )
5040+ self .assertIn ('hello!' , output )
50265041
50275042 def test_expression_completion (self ):
50285043 script = textwrap .dedent ("""
@@ -5039,11 +5054,11 @@ def test_expression_completion(self):
50395054 # Continue
50405055 input += b"c\n "
50415056
5042- output = run_pty (script , input )
5057+ output = self . _run_pty (script , input )
50435058
5044- self .assertIn (b 'special' , output )
5045- self .assertIn (b 'species' , output )
5046- self .assertIn (b '$_frame' , output )
5059+ self .assertIn ('special' , output )
5060+ self .assertIn ('species' , output )
5061+ self .assertIn ('$_frame' , output )
50475062
50485063 def test_builtin_completion (self ):
50495064 script = textwrap .dedent ("""
@@ -5057,9 +5072,9 @@ def test_builtin_completion(self):
50575072 # Continue
50585073 input += b"c\n "
50595074
5060- output = run_pty (script , input )
5075+ output = self . _run_pty (script , input )
50615076
5062- self .assertIn (b 'special' , output )
5077+ self .assertIn ('special' , output )
50635078
50645079 def test_convvar_completion (self ):
50655080 script = textwrap .dedent ("""
@@ -5075,10 +5090,10 @@ def test_convvar_completion(self):
50755090 # Continue
50765091 input += b"c\n "
50775092
5078- output = run_pty (script , input )
5093+ output = self . _run_pty (script , input )
50795094
5080- self .assertIn (b '<frame at 0x' , output )
5081- self .assertIn (b '102' , output )
5095+ self .assertIn ('<frame at 0x' , output )
5096+ self .assertIn ('102' , output )
50825097
50835098 def test_local_namespace (self ):
50845099 script = textwrap .dedent ("""
@@ -5094,9 +5109,9 @@ def f():
50945109 # Continue
50955110 input += b"c\n "
50965111
5097- output = run_pty (script , input )
5112+ output = self . _run_pty (script , input )
50985113
5099- self .assertIn (b 'I love Python' , output )
5114+ self .assertIn ('I love Python' , output )
51005115
51015116 @unittest .skipIf (sys .platform .startswith ('freebsd' ),
51025117 '\\ x08 is not interpreted as backspace on FreeBSD' )
@@ -5116,9 +5131,9 @@ def test_multiline_auto_indent(self):
51165131 input += b"f(-21-21)\n "
51175132 input += b"c\n "
51185133
5119- output = run_pty (script , input )
5134+ output = self . _run_pty (script , input )
51205135
5121- self .assertIn (b '42' , output )
5136+ self .assertIn ('42' , output )
51225137
51235138 def test_multiline_completion (self ):
51245139 script = textwrap .dedent ("""
@@ -5134,9 +5149,9 @@ def test_multiline_completion(self):
51345149 input += b"fun\t ()\n "
51355150 input += b"c\n "
51365151
5137- output = run_pty (script , input )
5152+ output = self . _run_pty (script , input )
51385153
5139- self .assertIn (b '42' , output )
5154+ self .assertIn ('42' , output )
51405155
51415156 @unittest .skipIf (sys .platform .startswith ('freebsd' ),
51425157 '\\ x08 is not interpreted as backspace on FreeBSD' )
@@ -5162,10 +5177,10 @@ def func():
51625177 c
51635178 """ ).encode ()
51645179
5165- output = run_pty (script , input )
5180+ output = self . _run_pty (script , input )
51665181
5167- self .assertIn (b '5' , output )
5168- self .assertNotIn (b 'Error' , output )
5182+ self .assertIn ('5' , output )
5183+ self .assertNotIn ('Error' , output )
51695184
51705185 def test_interact_completion (self ):
51715186 script = textwrap .dedent ("""
@@ -5189,11 +5204,45 @@ def test_interact_completion(self):
51895204 # continue
51905205 input += b"c\n "
51915206
5192- output = run_pty (script , input )
5207+ output = self ._run_pty (script , input )
5208+
5209+ self .assertIn ("'disp' is not defined" , output )
5210+ self .assertIn ('special' , output )
5211+ self .assertIn ('84' , output )
5212+
5213+
5214+ @unittest .skipIf (not pdb ._pyrepl_available (), "pyrepl is not available" )
5215+ class PdbTestReadlinePyREPL (PdbTestReadline ):
5216+ def _run_pty (self , script , input ):
5217+ # Override the env to make sure pyrepl is used in this test class
5218+ return super ()._run_pty (script , input , env = {** os .environ })
5219+
5220+ def test_pyrepl_used (self ):
5221+ script = textwrap .dedent ("""
5222+ import pdb
5223+ db = pdb.Pdb()
5224+ print(db.pyrepl_input)
5225+ """ )
5226+ input = b""
5227+ output = self ._run_pty (script , input )
5228+ self .assertIn ('PdbPyReplInput' , output )
5229+
5230+ def test_pyrepl_multiline_change (self ):
5231+ script = textwrap .dedent ("""
5232+ import pdb; pdb.Pdb().set_trace()
5233+ """ )
5234+
5235+ input = b"def f():\n "
5236+ # Auto-indent should work here
5237+ input += b"return x"
5238+ # The following command tries to add the argument x in f()
5239+ # up, left, left (in the parenthesis now), "x", down, down (at the end)
5240+ input += b"\x1b OA\x1b OD\x1b ODx\x1b OB\x1b OB\n \n "
5241+ input += b"f(40 + 2)\n "
5242+ input += b"c\n "
51935243
5194- self .assertIn (b"'disp' is not defined" , output )
5195- self .assertIn (b'special' , output )
5196- self .assertIn (b'84' , output )
5244+ output = self ._run_pty (script , input )
5245+ self .assertIn ('42' , output )
51975246
51985247
51995248def load_tests (loader , tests , pattern ):
0 commit comments