@@ -938,26 +938,47 @@ def test_pdb_issue_20766():
938938 pdb 2: <built-in function default_int_handler>
939939 """
940940
941+
941942class PdbTestCase (unittest .TestCase ):
943+ def tearDown (self ):
944+ support .unlink (support .TESTFN )
942945
943- def run_pdb (self , script , commands ):
944- """Run 'script' lines with pdb and the pdb 'commands'."""
945- filename = 'main.py'
946- with open (filename , 'w' ) as f :
947- f .write (textwrap .dedent (script ))
948- self .addCleanup (support .unlink , filename )
946+ def _run_pdb (self , pdb_args , commands ):
949947 self .addCleanup (support .rmtree , '__pycache__' )
950- cmd = [sys .executable , '-m' , 'pdb' , filename ]
951- stdout = stderr = None
952- with subprocess .Popen (cmd , stdout = subprocess .PIPE ,
953- stdin = subprocess .PIPE ,
954- stderr = subprocess .STDOUT ,
955- ) as proc :
948+ cmd = [sys .executable , '-m' , 'pdb' ] + pdb_args
949+ with subprocess .Popen (
950+ cmd ,
951+ stdout = subprocess .PIPE ,
952+ stdin = subprocess .PIPE ,
953+ stderr = subprocess .STDOUT ,
954+ ) as proc :
956955 stdout , stderr = proc .communicate (str .encode (commands ))
957956 stdout = stdout and bytes .decode (stdout )
958957 stderr = stderr and bytes .decode (stderr )
959958 return stdout , stderr
960959
960+ def run_pdb_script (self , script , commands ):
961+ """Run 'script' lines with pdb and the pdb 'commands'."""
962+ filename = 'main.py'
963+ with open (filename , 'w' ) as f :
964+ f .write (textwrap .dedent (script ))
965+ self .addCleanup (support .unlink , filename )
966+ return self ._run_pdb ([filename ], commands )
967+
968+ def run_pdb_module (self , script , commands ):
969+ """Runs the script code as part of a module"""
970+ self .module_name = 't_main'
971+ support .rmtree (self .module_name )
972+ main_file = self .module_name + '/__main__.py'
973+ init_file = self .module_name + '/__init__.py'
974+ os .mkdir (self .module_name )
975+ with open (init_file , 'w' ) as f :
976+ pass
977+ with open (main_file , 'w' ) as f :
978+ f .write (textwrap .dedent (script ))
979+ self .addCleanup (support .rmtree , self .module_name )
980+ return self ._run_pdb (['-m' , self .module_name ], commands )
981+
961982 def _assert_find_function (self , file_content , func_name , expected ):
962983 file_content = textwrap .dedent (file_content )
963984
@@ -1034,7 +1055,7 @@ def bar():
10341055 with open ('bar.py' , 'w' ) as f :
10351056 f .write (textwrap .dedent (bar ))
10361057 self .addCleanup (support .unlink , 'bar.py' )
1037- stdout , stderr = self .run_pdb (script , commands )
1058+ stdout , stderr = self .run_pdb_script (script , commands )
10381059 self .assertTrue (
10391060 any ('main.py(5)foo()->None' in l for l in stdout .splitlines ()),
10401061 'Fail to step into the caller after a return' )
@@ -1071,7 +1092,7 @@ def test_issue16180(self):
10711092 script = "def f: pass\n "
10721093 commands = ''
10731094 expected = "SyntaxError:"
1074- stdout , stderr = self .run_pdb (script , commands )
1095+ stdout , stderr = self .run_pdb_script (script , commands )
10751096 self .assertIn (expected , stdout ,
10761097 '\n \n Expected:\n {}\n Got:\n {}\n '
10771098 'Fail to handle a syntax error in the debuggee.'
@@ -1119,13 +1140,119 @@ def test_header(self):
11191140 pdb .set_trace (header = header )
11201141 self .assertEqual (stdout .getvalue (), header + '\n ' )
11211142
1122- def tearDown (self ):
1123- support .unlink (support .TESTFN )
1143+ def test_run_module (self ):
1144+ script = """print("SUCCESS")"""
1145+ commands = """
1146+ continue
1147+ quit
1148+ """
1149+ stdout , stderr = self .run_pdb_module (script , commands )
1150+ self .assertTrue (any ("SUCCESS" in l for l in stdout .splitlines ()), stdout )
1151+
1152+ def test_module_is_run_as_main (self ):
1153+ script = """
1154+ if __name__ == '__main__':
1155+ print("SUCCESS")
1156+ """
1157+ commands = """
1158+ continue
1159+ quit
1160+ """
1161+ stdout , stderr = self .run_pdb_module (script , commands )
1162+ self .assertTrue (any ("SUCCESS" in l for l in stdout .splitlines ()), stdout )
1163+
1164+ def test_breakpoint (self ):
1165+ script = """
1166+ if __name__ == '__main__':
1167+ pass
1168+ print("SUCCESS")
1169+ pass
1170+ """
1171+ commands = """
1172+ b 3
1173+ quit
1174+ """
1175+ stdout , stderr = self .run_pdb_module (script , commands )
1176+ self .assertTrue (any ("Breakpoint 1 at" in l for l in stdout .splitlines ()), stdout )
1177+ self .assertTrue (all ("SUCCESS" not in l for l in stdout .splitlines ()), stdout )
1178+
1179+ def test_run_pdb_with_pdb (self ):
1180+ commands = """
1181+ c
1182+ quit
1183+ """
1184+ stdout , stderr = self ._run_pdb (["-m" , "pdb" ], commands )
1185+ self .assertIn ("Debug the Python program given by pyfile." , stdout .splitlines ())
1186+
1187+ def test_module_without_a_main (self ):
1188+ module_name = 't_main'
1189+ support .rmtree (module_name )
1190+ init_file = module_name + '/__init__.py'
1191+ os .mkdir (module_name )
1192+ with open (init_file , 'w' ) as f :
1193+ pass
1194+ self .addCleanup (support .rmtree , module_name )
1195+ stdout , stderr = self ._run_pdb (['-m' , module_name ], "" )
1196+ self .assertIn ("ImportError: No module named t_main.__main__" ,
1197+ stdout .splitlines ())
1198+
1199+ def test_blocks_at_first_code_line (self ):
1200+ script = """
1201+ #This is a comment, on line 2
1202+
1203+ print("SUCCESS")
1204+ """
1205+ commands = """
1206+ quit
1207+ """
1208+ stdout , stderr = self .run_pdb_module (script , commands )
1209+ self .assertTrue (any ("__main__.py(4)<module>()"
1210+ in l for l in stdout .splitlines ()), stdout )
1211+
1212+ def test_relative_imports (self ):
1213+ self .module_name = 't_main'
1214+ support .rmtree (self .module_name )
1215+ main_file = self .module_name + '/__main__.py'
1216+ init_file = self .module_name + '/__init__.py'
1217+ module_file = self .module_name + '/module.py'
1218+ self .addCleanup (support .rmtree , self .module_name )
1219+ os .mkdir (self .module_name )
1220+ with open (init_file , 'w' ) as f :
1221+ f .write (textwrap .dedent ("""
1222+ top_var = "VAR from top"
1223+ """ ))
1224+ with open (main_file , 'w' ) as f :
1225+ f .write (textwrap .dedent ("""
1226+ from . import top_var
1227+ from .module import var
1228+ from . import module
1229+ pass # We'll stop here and print the vars
1230+ """ ))
1231+ with open (module_file , 'w' ) as f :
1232+ f .write (textwrap .dedent ("""
1233+ var = "VAR from module"
1234+ var2 = "second var"
1235+ """ ))
1236+ commands = """
1237+ b 5
1238+ c
1239+ p top_var
1240+ p var
1241+ p module.var2
1242+ quit
1243+ """
1244+ stdout , _ = self ._run_pdb (['-m' , self .module_name ], commands )
1245+ self .assertTrue (any ("VAR from module" in l for l in stdout .splitlines ()))
1246+ self .assertTrue (any ("VAR from top" in l for l in stdout .splitlines ()))
1247+ self .assertTrue (any ("second var" in l for l in stdout .splitlines ()))
11241248
11251249
11261250def load_tests (* args ):
11271251 from test import test_pdb
1128- suites = [unittest .makeSuite (PdbTestCase ), doctest .DocTestSuite (test_pdb )]
1252+ suites = [
1253+ unittest .makeSuite (PdbTestCase ),
1254+ doctest .DocTestSuite (test_pdb )
1255+ ]
11291256 return unittest .TestSuite (suites )
11301257
11311258
0 commit comments