summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2010-07-30 09:14:20 (GMT)
committerGeorg Brandl <georg@python.org>2010-07-30 09:14:20 (GMT)
commit46b9afc862974e5855f0ca8a181096945483c86e (patch)
tree8ad8005224efaf00ef06fbb4c609b5eb6091d6ad
parent44f8bf941109c24d36d7d6e4dd05080a0191f3d9 (diff)
downloadcpython-46b9afc862974e5855f0ca8a181096945483c86e.zip
cpython-46b9afc862974e5855f0ca8a181096945483c86e.tar.gz
cpython-46b9afc862974e5855f0ca8a181096945483c86e.tar.bz2
#1472251: remove addition of "\n" to code given to pdb.run[eval](), the bug in exec() that made this necessary has been fixed. Also document that you can give code objects to run() and runeval(), and add some tests to test_pdb.
-rw-r--r--Doc/library/pdb.rst22
-rw-r--r--Lib/bdb.py9
-rw-r--r--Lib/test/test_pdb.py47
3 files changed, 59 insertions, 19 deletions
diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst
index 4e79bad..6da5332 100644
--- a/Doc/library/pdb.rst
+++ b/Doc/library/pdb.rst
@@ -85,21 +85,21 @@ slightly different way:
.. function:: run(statement, globals=None, locals=None)
- Execute the *statement* (given as a string) under debugger control. The
- debugger prompt appears before any code is executed; you can set breakpoints
- and type :pdbcmd:`continue`, or you can step through the statement using
- :pdbcmd:`step` or :pdbcmd:`next` (all these commands are explained below).
- The optional *globals* and *locals* arguments specify the environment in
- which the code is executed; by default the dictionary of the module
- :mod:`__main__` is used. (See the explanation of the built-in :func:`exec`
- or :func:`eval` functions.)
+ Execute the *statement* (given as a string or a code object) under debugger
+ control. The debugger prompt appears before any code is executed; you can
+ set breakpoints and type :pdbcmd:`continue`, or you can step through the
+ statement using :pdbcmd:`step` or :pdbcmd:`next` (all these commands are
+ explained below). The optional *globals* and *locals* arguments specify the
+ environment in which the code is executed; by default the dictionary of the
+ module :mod:`__main__` is used. (See the explanation of the built-in
+ :func:`exec` or :func:`eval` functions.)
.. function:: runeval(expression, globals=None, locals=None)
- Evaluate the *expression* (given as a string) under debugger control. When
- :func:`runeval` returns, it returns the value of the expression. Otherwise
- this function is similar to :func:`run`.
+ Evaluate the *expression* (given as a string or a code object) under debugger
+ control. When :func:`runeval` returns, it returns the value of the
+ expression. Otherwise this function is similar to :func:`run`.
.. function:: runcall(function, *args, **kwds)
diff --git a/Lib/bdb.py b/Lib/bdb.py
index cee71a4..572e591 100644
--- a/Lib/bdb.py
+++ b/Lib/bdb.py
@@ -364,8 +364,9 @@ class Bdb:
if line: s = s + lprefix + line.strip()
return s
- # The following two methods can be called by clients to use
- # a debugger to debug a statement, given as a string.
+ # The following methods can be called by clients to use
+ # a debugger to debug a statement or an expression.
+ # Both can be given as a string, or a code object.
def run(self, cmd, globals=None, locals=None):
if globals is None:
@@ -375,8 +376,6 @@ class Bdb:
locals = globals
self.reset()
sys.settrace(self.trace_dispatch)
- if not isinstance(cmd, types.CodeType):
- cmd = cmd+'\n'
try:
exec(cmd, globals, locals)
except BdbQuit:
@@ -393,8 +392,6 @@ class Bdb:
locals = globals
self.reset()
sys.settrace(self.trace_dispatch)
- if not isinstance(expr, types.CodeType):
- expr = expr+'\n'
try:
return eval(expr, globals, locals)
except BdbQuit:
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index 7af903d..4af8516 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -1,5 +1,4 @@
-# A test suite for pdb; at the moment, this only validates skipping of
-# specified test modules (RFE #5142).
+# A test suite for pdb; not very comprehensive at the moment.
import imp
import sys
@@ -123,6 +122,50 @@ def test_pdb_skip_modules_with_callback():
"""
+def pdb_invoke(method, arg):
+ """Run pdb.method(arg)."""
+ import pdb; getattr(pdb, method)(arg)
+
+
+def test_pdb_run_with_incorrect_argument():
+ """Testing run and runeval with incorrect first argument.
+
+ >>> pti = PdbTestInput(['continue',])
+ >>> with pti:
+ ... pdb_invoke('run', lambda x: x)
+ Traceback (most recent call last):
+ TypeError: exec() arg 1 must be a string, bytes or code object
+
+ >>> with pti:
+ ... pdb_invoke('runeval', lambda x: x)
+ Traceback (most recent call last):
+ TypeError: eval() arg 1 must be a string, bytes or code object
+ """
+
+
+def test_pdb_run_with_code_object():
+ """Testing run and runeval with code object as a first argument.
+
+ >>> with PdbTestInput(['step','x', 'continue']):
+ ... pdb_invoke('run', compile('x=1', '<string>', 'exec'))
+ > <string>(1)<module>()
+ (Pdb) step
+ --Return--
+ > <string>(1)<module>()->None
+ (Pdb) x
+ 1
+ (Pdb) continue
+
+ >>> with PdbTestInput(['x', 'continue']):
+ ... x=0
+ ... pdb_invoke('runeval', compile('x+1', '<string>', 'eval'))
+ > <string>(1)<module>()->None
+ (Pdb) x
+ 1
+ (Pdb) continue
+ """
+
+
def test_main():
from test import test_pdb
support.run_doctest(test_pdb, verbosity=True)