Index: Doc/library/pdb.rst =================================================================== --- Doc/library/pdb.rst (wersja 75037) +++ Doc/library/pdb.rst (kopia robocza) @@ -84,21 +84,25 @@ .. function:: run(statement[, globals[, locals]]) - 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 ``continue``, or you can step through the statement using ``step`` or - ``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 + Execute the *statement* (given as a string, an open file object, or a code object) + under debugger control. The debugger prompt appears before any code is executed; + you can set breakpoints and type ``continue``, or you can step through the statement + using ``step`` or ``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 :keyword:`exec` statement or the :func:`eval` built-in function.) +.. versionadded:: 2.7 + Accepting an open file object, or a code object as statement. .. function:: runeval(expression[, globals[, locals]]) - Evaluate the *expression* (given as a string) under debugger control. When - :func:`runeval` returns, it returns the value of the expression. Otherwise this + 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`. +.. versionadded:: 2.7 + Accepting a code object as an expression. .. function:: runcall(function[, argument, ...]) Index: Lib/bdb.py =================================================================== --- Lib/bdb.py (wersja 75037) +++ Lib/bdb.py (kopia robocza) @@ -362,8 +362,10 @@ 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. + # First method also accepts statement as an open file object. def run(self, cmd, globals=None, locals=None): if globals is None: @@ -373,8 +375,6 @@ locals = globals self.reset() sys.settrace(self.trace_dispatch) - if not isinstance(cmd, types.CodeType): - cmd = cmd+'\n' try: exec cmd in globals, locals except BdbQuit: @@ -391,8 +391,6 @@ 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: Index: Lib/test/test_pdb.py =================================================================== --- Lib/test/test_pdb.py (wersja 75037) +++ Lib/test/test_pdb.py (kopia robocza) @@ -1,6 +1,3 @@ -# A test suite for pdb; at the moment, this only validates skipping of -# specified test modules (RFE #5142). - import imp import os import sys @@ -129,6 +126,70 @@ """ +def pdb_invoke(method, arg): + """Run pdb.method with 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, file, or code object + + >>> with pti: + ... pdb_invoke('runeval', lambda x: x) + Traceback (most recent call last): + TypeError: eval() arg 1 must be a string 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', '', 'exec')) + > (1)() + (Pdb) step + --Return-- + > (1)()->None + (Pdb) x + 1 + (Pdb) continue + + >>> with PdbTestInput(['x', 'continue']): + ... x=0 + ... pdb_invoke('runeval', compile('x+1', '', 'eval')) + > (1)()->None + (Pdb) x + 1 + (Pdb) continue + """ + + +def test_pdb_run_with_file_object(): + """Testing run with file object as a first argument. + + >>> def test_run_co(method, co): + ... import pdb;getattr(pdb, method)(co) + ... + >>> f = open(test_support.TESTFN, 'w') + >>> f.write('x = 1') + >>> with PdbTestInput(['x', 'continue']): + ... test_run_co('run', f) # doctest:+ELLIPSIS + > ...(1)()->None + -> x = 1 + (Pdb) x + 1 + (Pdb) continue + >>> f.close() + >>> test_support.unlink(test_support.TESTFN) + """ + + def test_main(): from test import test_pdb test_support.run_doctest(test_pdb, verbosity=True)