summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2021-05-11 23:48:05 (GMT)
committerGitHub <noreply@github.com>2021-05-11 23:48:05 (GMT)
commitc90ed8e2e79ebd64f72c621b5a2ab06ec4c7210c (patch)
tree4d3a87063be7408cf1d80c4f3db7a5b24513f858
parent6098214b98f843fc8fb9d6042b0c9f96eb90957c (diff)
downloadcpython-c90ed8e2e79ebd64f72c621b5a2ab06ec4c7210c.zip
cpython-c90ed8e2e79ebd64f72c621b5a2ab06ec4c7210c.tar.gz
cpython-c90ed8e2e79ebd64f72c621b5a2ab06ec4c7210c.tar.bz2
bpo-28528: Fix pdb.checkline() attribute error when 'curframe' is None. (GH-25438) (#26050)
Co-authored-by: Thomas Kluyver <takowl@gmail.com> (cherry picked from commit 8563a7052ccd98e6a381d361664ce567afd5eb6e) Co-authored-by: Erlend Egeberg Aasland <erlend.aasland@innova.no>
-rwxr-xr-xLib/pdb.py3
-rw-r--r--Lib/test/test_pdb.py38
-rw-r--r--Misc/NEWS.d/next/Library/2021-04-29-00-48-00.bpo-28528.JLAVWj.rst2
3 files changed, 42 insertions, 1 deletions
diff --git a/Lib/pdb.py b/Lib/pdb.py
index 98dc975..a888a0a 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -752,7 +752,8 @@ class Pdb(bdb.Bdb, cmd.Cmd):
"""
# 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')
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index 870eab4..cd096e7 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -9,6 +9,7 @@ import codecs
import unittest
import subprocess
import textwrap
+import linecache
from contextlib import ExitStack
from io import StringIO
@@ -1807,10 +1808,47 @@ def bœr():
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):
+ os_helper.unlink(os_helper.TESTFN)
+
+ def test_checkline_before_debugging(self):
+ with open(os_helper.TESTFN, "w") as f:
+ f.write("print(123)")
+ db = pdb.Pdb()
+ self.assertEqual(db.checkline(os_helper.TESTFN, 1), 1)
+
+ def test_checkline_after_reset(self):
+ with open(os_helper.TESTFN, "w") as f:
+ f.write("print(123)")
+ db = pdb.Pdb()
+ db.reset()
+ self.assertEqual(db.checkline(os_helper.TESTFN, 1), 1)
+
+ def test_checkline_is_not_executable(self):
+ with open(os_helper.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(os_helper.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)
diff --git a/Misc/NEWS.d/next/Library/2021-04-29-00-48-00.bpo-28528.JLAVWj.rst b/Misc/NEWS.d/next/Library/2021-04-29-00-48-00.bpo-28528.JLAVWj.rst
new file mode 100644
index 0000000..97731ad
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-04-29-00-48-00.bpo-28528.JLAVWj.rst
@@ -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`.