Skip to content

[3.9] bpo-28528: Fix pdb.checkline() attribute error when 'curframe' is None (GH-25438) #26053

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,8 @@ def checkline(self, filename, lineno):
"""
# this method should be callable before starting debugging, so default
# to "no globals" if there is no current frame
globs = self.curframe.f_globals if hasattr(self, 'curframe') else None
frame = getattr(self, 'curframe', None)
globs = frame.f_globals if frame else None
line = linecache.getline(filename, lineno, globs)
if not line:
self.message('End of file')
Expand Down
38 changes: 38 additions & 0 deletions Lib/test/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import unittest
import subprocess
import textwrap
import linecache

from contextlib import ExitStack
from io import StringIO
Expand Down Expand Up @@ -1743,10 +1744,47 @@ def test_issue42383(self):
self.assertEqual(stdout.split('\n')[6].rstrip('\r'), expected)


class ChecklineTests(unittest.TestCase):
def setUp(self):
linecache.clearcache() # Pdb.checkline() uses linecache.getline()

def tearDown(self):
support.unlink(support.TESTFN)

def test_checkline_before_debugging(self):
with open(support.TESTFN, "w") as f:
f.write("print(123)")
db = pdb.Pdb()
self.assertEqual(db.checkline(support.TESTFN, 1), 1)

def test_checkline_after_reset(self):
with open(support.TESTFN, "w") as f:
f.write("print(123)")
db = pdb.Pdb()
db.reset()
self.assertEqual(db.checkline(support.TESTFN, 1), 1)

def test_checkline_is_not_executable(self):
with open(support.TESTFN, "w") as f:
# Test for comments, docstrings and empty lines
s = textwrap.dedent("""
# Comment
\"\"\" docstring \"\"\"
''' docstring '''

""")
f.write(s)
db = pdb.Pdb()
num_lines = len(s.splitlines()) + 2 # Test for EOF
for lineno in range(num_lines):
self.assertFalse(db.checkline(support.TESTFN, lineno))


def load_tests(*args):
from test import test_pdb
suites = [
unittest.makeSuite(PdbTestCase),
unittest.makeSuite(ChecklineTests),
doctest.DocTestSuite(test_pdb)
]
return unittest.TestSuite(suites)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix a bug in :mod:`pdb` where :meth:`~pdb.Pdb.checkline` raises
:exc:`AttributeError` if it is called after :meth:`~pdb.Pdb.reset`.