filename = None
lineno = None
cond = None
+ module_globals = None
comma = arg.find(',')
if comma > 0:
# parse stuff after comma: "condition"
funcname = code.co_name
lineno = find_first_executable_line(code)
filename = code.co_filename
+ module_globals = func.__globals__
except:
# last thing to try
(ok, filename, ln) = self.lineinfo(arg)
lineno = int(ln)
if not filename:
filename = self.defaultFile()
+ filename = self.canonic(filename)
# Check for reasonable breakpoint
- line = self.checkline(filename, lineno)
+ line = self.checkline(filename, lineno, module_globals)
if line:
# now set the break point
err = self.set_break(filename, line, temporary, cond, funcname)
answer = find_function(item, self.canonic(fname))
return answer or failed
- def checkline(self, filename, lineno):
+ def checkline(self, filename, lineno, module_globals=None):
"""Check whether specified line seems to be executable.
Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank
# this method should be callable before starting debugging, so default
# to "no globals" if there is no current frame
frame = getattr(self, 'curframe', None)
- globs = frame.f_globals if frame else None
- line = linecache.getline(filename, lineno, globs)
+ if module_globals is None:
+ module_globals = frame.f_globals if frame else None
+ line = linecache.getline(filename, lineno, module_globals)
if not line:
self.message('End of file')
return 0
import textwrap
import linecache
import zipapp
+import zipfile
from contextlib import ExitStack, redirect_stdout
from io import StringIO
self.assertIn('42', stdout)
self.assertIn('return x + 1', stdout)
+ def test_zipimport(self):
+ with os_helper.temp_dir() as temp_dir:
+ os.mkdir(os.path.join(temp_dir, 'source'))
+ zipmodule = textwrap.dedent(
+ """
+ def bar():
+ pass
+ """
+ )
+ script = textwrap.dedent(
+ f"""
+ import sys; sys.path.insert(0, {repr(os.path.join(temp_dir, 'zipmodule.zip'))})
+ import foo
+ foo.bar()
+ """
+ )
+
+ with zipfile.ZipFile(os.path.join(temp_dir, 'zipmodule.zip'), 'w') as zf:
+ zf.writestr('foo.py', zipmodule)
+ with open(os.path.join(temp_dir, 'script.py'), 'w') as f:
+ f.write(script)
+
+ stdout, _ = self._run_pdb([os.path.join(temp_dir, 'script.py')], '\n'.join([
+ 'n',
+ 'n',
+ 'b foo.bar',
+ 'c',
+ 'p f"break in {$_frame.f_code.co_name}"',
+ 'q'
+ ]))
+ self.assertIn('break in bar', stdout)
+
class ChecklineTests(unittest.TestCase):
def setUp(self):