From 6446c48e9770afb5ddd73c6fd25ba4f4bf399310 Mon Sep 17 00:00:00 2001 From: Mario Corchero Date: Thu, 1 Feb 2018 15:50:14 +0000 Subject: [PATCH 1/2] Use mod_spec.parent when running modules with pdb At the moment the module name is used, which breaks relative imports when pdb is run against a plain module or submodule. --- Lib/pdb.py | 2 +- Lib/test/test_pdb.py | 6 +++--- .../next/Library/2018-02-01-15-53-35.bpo-32691.VLWVTq.rst | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-02-01-15-53-35.bpo-32691.VLWVTq.rst diff --git a/Lib/pdb.py b/Lib/pdb.py index 366a85b31960a6..60bdb7675c8131 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1532,7 +1532,7 @@ def _runmodule(self, module_name): __main__.__dict__.update({ "__name__": "__main__", "__file__": self.mainpyfile, - "__package__": module_name, + "__package__": mod_spec.parent, "__loader__": mod_spec.loader, "__spec__": mod_spec, "__builtins__": __builtins__, diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 70d8d1d32613fb..3c7a66f66223a2 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1417,7 +1417,7 @@ def test_blocks_at_first_code_line(self): def test_relative_imports(self): self.module_name = 't_main' support.rmtree(self.module_name) - main_file = self.module_name + '/__main__.py' + main_file = self.module_name + '/runme.py' init_file = self.module_name + '/__init__.py' module_file = self.module_name + '/module.py' self.addCleanup(support.rmtree, self.module_name) @@ -1446,8 +1446,8 @@ def test_relative_imports(self): p module.var2 quit """ - stdout, _ = self._run_pdb(['-m', self.module_name], commands) - self.assertTrue(any("VAR from module" in l for l in stdout.splitlines())) + stdout, _ = self._run_pdb(['-m', self.module_name + '.runme'], commands) + self.assertTrue(any("VAR from module" in l for l in stdout.splitlines()), stdout) self.assertTrue(any("VAR from top" in l for l in stdout.splitlines())) self.assertTrue(any("second var" in l for l in stdout.splitlines())) diff --git a/Misc/NEWS.d/next/Library/2018-02-01-15-53-35.bpo-32691.VLWVTq.rst b/Misc/NEWS.d/next/Library/2018-02-01-15-53-35.bpo-32691.VLWVTq.rst new file mode 100644 index 00000000000000..93f898e9c68956 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-01-15-53-35.bpo-32691.VLWVTq.rst @@ -0,0 +1 @@ +Use mod_spec.parent when running modules with pdb From 0b4954363de5670c314b06cc4e739a18324cd125 Mon Sep 17 00:00:00 2001 From: Mario Corchero Date: Fri, 2 Feb 2018 17:11:00 +0000 Subject: [PATCH 2/2] Add a test specific to __main__ vs main module --- Lib/test/test_pdb.py | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 3c7a66f66223a2..9aa38e08dd6e6c 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1417,7 +1417,7 @@ def test_blocks_at_first_code_line(self): def test_relative_imports(self): self.module_name = 't_main' support.rmtree(self.module_name) - main_file = self.module_name + '/runme.py' + main_file = self.module_name + '/__main__.py' init_file = self.module_name + '/__init__.py' module_file = self.module_name + '/module.py' self.addCleanup(support.rmtree, self.module_name) @@ -1446,11 +1446,42 @@ def test_relative_imports(self): p module.var2 quit """ - stdout, _ = self._run_pdb(['-m', self.module_name + '.runme'], commands) + stdout, _ = self._run_pdb(['-m', self.module_name], commands) self.assertTrue(any("VAR from module" in l for l in stdout.splitlines()), stdout) self.assertTrue(any("VAR from top" in l for l in stdout.splitlines())) self.assertTrue(any("second var" in l for l in stdout.splitlines())) + def test_relative_imports_on_plain_module(self): + # Validates running a plain module. See bpo32691 + self.module_name = 't_main' + support.rmtree(self.module_name) + main_file = self.module_name + '/runme.py' + init_file = self.module_name + '/__init__.py' + module_file = self.module_name + '/module.py' + self.addCleanup(support.rmtree, self.module_name) + os.mkdir(self.module_name) + with open(init_file, 'w') as f: + f.write(textwrap.dedent(""" + top_var = "VAR from top" + """)) + with open(main_file, 'w') as f: + f.write(textwrap.dedent(""" + from . import module + pass # We'll stop here and print the vars + """)) + with open(module_file, 'w') as f: + f.write(textwrap.dedent(""" + var = "VAR from module" + """)) + commands = """ + b 3 + c + p module.var + quit + """ + stdout, _ = self._run_pdb(['-m', self.module_name + '.runme'], commands) + self.assertTrue(any("VAR from module" in l for l in stdout.splitlines()), stdout) + def load_tests(*args): from test import test_pdb