Issue #18401: pdb tests don't read ~/.pdbrc anymore
Patch by Martin Matusiak and Sam Kimbrel.
This commit is contained in:
parent
a1fd0789ed
commit
2eb6eca3e5
|
@ -144,7 +144,7 @@ The ``run*`` functions and :func:`set_trace` are aliases for instantiating the
|
||||||
access further features, you have to do this yourself:
|
access further features, you have to do this yourself:
|
||||||
|
|
||||||
.. class:: Pdb(completekey='tab', stdin=None, stdout=None, skip=None, \
|
.. class:: Pdb(completekey='tab', stdin=None, stdout=None, skip=None, \
|
||||||
nosigint=False)
|
nosigint=False, readrc=True)
|
||||||
|
|
||||||
:class:`Pdb` is the debugger class.
|
:class:`Pdb` is the debugger class.
|
||||||
|
|
||||||
|
@ -160,6 +160,9 @@ access further features, you have to do this yourself:
|
||||||
This allows you to break into the debugger again by pressing :kbd:`Ctrl-C`. If you
|
This allows you to break into the debugger again by pressing :kbd:`Ctrl-C`. If you
|
||||||
want Pdb not to touch the SIGINT handler, set *nosigint* to true.
|
want Pdb not to touch the SIGINT handler, set *nosigint* to true.
|
||||||
|
|
||||||
|
The *readrc* argument defaults to True and controls whether Pdb will load
|
||||||
|
.pdbrc files from the filesystem.
|
||||||
|
|
||||||
Example call to enable tracing with *skip*::
|
Example call to enable tracing with *skip*::
|
||||||
|
|
||||||
import pdb; pdb.Pdb(skip=['django.*']).set_trace()
|
import pdb; pdb.Pdb(skip=['django.*']).set_trace()
|
||||||
|
@ -171,6 +174,9 @@ access further features, you have to do this yourself:
|
||||||
The *nosigint* argument. Previously, a SIGINT handler was never set by
|
The *nosigint* argument. Previously, a SIGINT handler was never set by
|
||||||
Pdb.
|
Pdb.
|
||||||
|
|
||||||
|
.. versionadded:: 3.5
|
||||||
|
The *readrc* argument.
|
||||||
|
|
||||||
.. method:: run(statement, globals=None, locals=None)
|
.. method:: run(statement, globals=None, locals=None)
|
||||||
runeval(expression, globals=None, locals=None)
|
runeval(expression, globals=None, locals=None)
|
||||||
runcall(function, *args, **kwds)
|
runcall(function, *args, **kwds)
|
||||||
|
|
22
Lib/pdb.py
22
Lib/pdb.py
|
@ -52,7 +52,8 @@ If a file ".pdbrc" exists in your home directory or in the current
|
||||||
directory, it is read in and executed as if it had been typed at the
|
directory, it is read in and executed as if it had been typed at the
|
||||||
debugger prompt. This is particularly useful for aliases. If both
|
debugger prompt. This is particularly useful for aliases. If both
|
||||||
files exist, the one in the home directory is read first and aliases
|
files exist, the one in the home directory is read first and aliases
|
||||||
defined there can be overridden by the local file.
|
defined there can be overridden by the local file. This behavior can be
|
||||||
|
disabled by passing the "readrc=False" argument to the Pdb constructor.
|
||||||
|
|
||||||
Aside from aliases, the debugger is not directly programmable; but it
|
Aside from aliases, the debugger is not directly programmable; but it
|
||||||
is implemented as a class from which you can derive your own debugger
|
is implemented as a class from which you can derive your own debugger
|
||||||
|
@ -135,7 +136,7 @@ line_prefix = '\n-> ' # Probably a better default
|
||||||
class Pdb(bdb.Bdb, cmd.Cmd):
|
class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
|
|
||||||
def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
|
def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
|
||||||
nosigint=False):
|
nosigint=False, readrc=True):
|
||||||
bdb.Bdb.__init__(self, skip=skip)
|
bdb.Bdb.__init__(self, skip=skip)
|
||||||
cmd.Cmd.__init__(self, completekey, stdin, stdout)
|
cmd.Cmd.__init__(self, completekey, stdin, stdout)
|
||||||
if stdout:
|
if stdout:
|
||||||
|
@ -158,18 +159,19 @@ class Pdb(bdb.Bdb, cmd.Cmd):
|
||||||
|
|
||||||
# Read $HOME/.pdbrc and ./.pdbrc
|
# Read $HOME/.pdbrc and ./.pdbrc
|
||||||
self.rcLines = []
|
self.rcLines = []
|
||||||
if 'HOME' in os.environ:
|
if readrc:
|
||||||
envHome = os.environ['HOME']
|
if 'HOME' in os.environ:
|
||||||
|
envHome = os.environ['HOME']
|
||||||
|
try:
|
||||||
|
with open(os.path.join(envHome, ".pdbrc")) as rcFile:
|
||||||
|
self.rcLines.extend(rcFile)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(envHome, ".pdbrc")) as rcFile:
|
with open(".pdbrc") as rcFile:
|
||||||
self.rcLines.extend(rcFile)
|
self.rcLines.extend(rcFile)
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
try:
|
|
||||||
with open(".pdbrc") as rcFile:
|
|
||||||
self.rcLines.extend(rcFile)
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.commands = {} # associates a command list to breakpoint numbers
|
self.commands = {} # associates a command list to breakpoint numbers
|
||||||
self.commands_doprompt = {} # for each bp num, tells if the prompt
|
self.commands_doprompt = {} # for each bp num, tells if the prompt
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
# A test suite for pdb; not very comprehensive at the moment.
|
# A test suite for pdb; not very comprehensive at the moment.
|
||||||
|
|
||||||
import doctest
|
import doctest
|
||||||
|
import os
|
||||||
import pdb
|
import pdb
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
import types
|
import types
|
||||||
import unittest
|
import unittest
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -34,7 +36,7 @@ def test_pdb_displayhook():
|
||||||
"""This tests the custom displayhook for pdb.
|
"""This tests the custom displayhook for pdb.
|
||||||
|
|
||||||
>>> def test_function(foo, bar):
|
>>> def test_function(foo, bar):
|
||||||
... import pdb; pdb.Pdb(nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
... pass
|
... pass
|
||||||
|
|
||||||
>>> with PdbTestInput([
|
>>> with PdbTestInput([
|
||||||
|
@ -74,7 +76,7 @@ def test_pdb_basic_commands():
|
||||||
... return foo.upper()
|
... return foo.upper()
|
||||||
|
|
||||||
>>> def test_function():
|
>>> def test_function():
|
||||||
... import pdb; pdb.Pdb(nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
... ret = test_function_2('baz')
|
... ret = test_function_2('baz')
|
||||||
... print(ret)
|
... print(ret)
|
||||||
|
|
||||||
|
@ -173,7 +175,7 @@ def test_pdb_breakpoint_commands():
|
||||||
"""Test basic commands related to breakpoints.
|
"""Test basic commands related to breakpoints.
|
||||||
|
|
||||||
>>> def test_function():
|
>>> def test_function():
|
||||||
... import pdb; pdb.Pdb(nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
... print(1)
|
... print(1)
|
||||||
... print(2)
|
... print(2)
|
||||||
... print(3)
|
... print(3)
|
||||||
|
@ -305,7 +307,7 @@ def test_list_commands():
|
||||||
... return foo
|
... return foo
|
||||||
|
|
||||||
>>> def test_function():
|
>>> def test_function():
|
||||||
... import pdb; pdb.Pdb(nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
... ret = test_function_2('baz')
|
... ret = test_function_2('baz')
|
||||||
|
|
||||||
>>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
|
>>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
|
||||||
|
@ -328,7 +330,7 @@ def test_list_commands():
|
||||||
-> ret = test_function_2('baz')
|
-> ret = test_function_2('baz')
|
||||||
(Pdb) list
|
(Pdb) list
|
||||||
1 def test_function():
|
1 def test_function():
|
||||||
2 import pdb; pdb.Pdb(nosigint=True).set_trace()
|
2 import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
3 -> ret = test_function_2('baz')
|
3 -> ret = test_function_2('baz')
|
||||||
[EOF]
|
[EOF]
|
||||||
(Pdb) step
|
(Pdb) step
|
||||||
|
@ -391,7 +393,7 @@ def test_post_mortem():
|
||||||
... print('Exception!')
|
... print('Exception!')
|
||||||
|
|
||||||
>>> def test_function():
|
>>> def test_function():
|
||||||
... import pdb; pdb.Pdb(nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
... test_function_2()
|
... test_function_2()
|
||||||
... print('Not reached.')
|
... print('Not reached.')
|
||||||
|
|
||||||
|
@ -424,7 +426,7 @@ def test_post_mortem():
|
||||||
-> 1/0
|
-> 1/0
|
||||||
(Pdb) list
|
(Pdb) list
|
||||||
1 def test_function():
|
1 def test_function():
|
||||||
2 import pdb; pdb.Pdb(nosigint=True).set_trace()
|
2 import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
3 -> test_function_2()
|
3 -> test_function_2()
|
||||||
4 print('Not reached.')
|
4 print('Not reached.')
|
||||||
[EOF]
|
[EOF]
|
||||||
|
@ -448,7 +450,7 @@ def test_pdb_skip_modules():
|
||||||
|
|
||||||
>>> def skip_module():
|
>>> def skip_module():
|
||||||
... import string
|
... import string
|
||||||
... import pdb; pdb.Pdb(skip=['stri*'], nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(skip=['stri*'], nosigint=True, readrc=False).set_trace()
|
||||||
... string.capwords('FOO')
|
... string.capwords('FOO')
|
||||||
|
|
||||||
>>> with PdbTestInput([
|
>>> with PdbTestInput([
|
||||||
|
@ -477,7 +479,7 @@ def test_pdb_skip_modules_with_callback():
|
||||||
>>> def skip_module():
|
>>> def skip_module():
|
||||||
... def callback():
|
... def callback():
|
||||||
... return None
|
... return None
|
||||||
... import pdb; pdb.Pdb(skip=['module_to_skip*'], nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(skip=['module_to_skip*'], nosigint=True, readrc=False).set_trace()
|
||||||
... mod.foo_pony(callback)
|
... mod.foo_pony(callback)
|
||||||
|
|
||||||
>>> with PdbTestInput([
|
>>> with PdbTestInput([
|
||||||
|
@ -518,7 +520,7 @@ def test_pdb_continue_in_bottomframe():
|
||||||
"""Test that "continue" and "next" work properly in bottom frame (issue #5294).
|
"""Test that "continue" and "next" work properly in bottom frame (issue #5294).
|
||||||
|
|
||||||
>>> def test_function():
|
>>> def test_function():
|
||||||
... import pdb, sys; inst = pdb.Pdb(nosigint=True)
|
... import pdb, sys; inst = pdb.Pdb(nosigint=True, readrc=False)
|
||||||
... inst.set_trace()
|
... inst.set_trace()
|
||||||
... inst.botframe = sys._getframe() # hackery to get the right botframe
|
... inst.botframe = sys._getframe() # hackery to get the right botframe
|
||||||
... print(1)
|
... print(1)
|
||||||
|
@ -558,7 +560,7 @@ def test_pdb_continue_in_bottomframe():
|
||||||
|
|
||||||
def pdb_invoke(method, arg):
|
def pdb_invoke(method, arg):
|
||||||
"""Run pdb.method(arg)."""
|
"""Run pdb.method(arg)."""
|
||||||
getattr(pdb.Pdb(nosigint=True), method)(arg)
|
getattr(pdb.Pdb(nosigint=True, readrc=False), method)(arg)
|
||||||
|
|
||||||
|
|
||||||
def test_pdb_run_with_incorrect_argument():
|
def test_pdb_run_with_incorrect_argument():
|
||||||
|
@ -607,7 +609,7 @@ def test_next_until_return_at_return_event():
|
||||||
... x = 2
|
... x = 2
|
||||||
|
|
||||||
>>> def test_function():
|
>>> def test_function():
|
||||||
... import pdb; pdb.Pdb(nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
... test_function_2()
|
... test_function_2()
|
||||||
... test_function_2()
|
... test_function_2()
|
||||||
... test_function_2()
|
... test_function_2()
|
||||||
|
@ -673,7 +675,7 @@ def test_pdb_next_command_for_generator():
|
||||||
... yield 2
|
... yield 2
|
||||||
|
|
||||||
>>> def test_function():
|
>>> def test_function():
|
||||||
... import pdb; pdb.Pdb(nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
... it = test_gen()
|
... it = test_gen()
|
||||||
... try:
|
... try:
|
||||||
... if next(it) != 0:
|
... if next(it) != 0:
|
||||||
|
@ -733,7 +735,7 @@ def test_pdb_return_command_for_generator():
|
||||||
... yield 2
|
... yield 2
|
||||||
|
|
||||||
>>> def test_function():
|
>>> def test_function():
|
||||||
... import pdb; pdb.Pdb(nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
... it = test_gen()
|
... it = test_gen()
|
||||||
... try:
|
... try:
|
||||||
... if next(it) != 0:
|
... if next(it) != 0:
|
||||||
|
@ -788,7 +790,7 @@ def test_pdb_until_command_for_generator():
|
||||||
... yield 2
|
... yield 2
|
||||||
|
|
||||||
>>> def test_function():
|
>>> def test_function():
|
||||||
... import pdb; pdb.Pdb(nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
... for i in test_gen():
|
... for i in test_gen():
|
||||||
... print(i)
|
... print(i)
|
||||||
... print("finished")
|
... print("finished")
|
||||||
|
@ -830,7 +832,7 @@ def test_pdb_next_command_in_generator_for_loop():
|
||||||
... return 1
|
... return 1
|
||||||
|
|
||||||
>>> def test_function():
|
>>> def test_function():
|
||||||
... import pdb; pdb.Pdb(nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
... for i in test_gen():
|
... for i in test_gen():
|
||||||
... print('value', i)
|
... print('value', i)
|
||||||
... x = 123
|
... x = 123
|
||||||
|
@ -875,7 +877,7 @@ def test_pdb_next_command_subiterator():
|
||||||
... return x
|
... return x
|
||||||
|
|
||||||
>>> def test_function():
|
>>> def test_function():
|
||||||
... import pdb; pdb.Pdb(nosigint=True).set_trace()
|
... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
|
||||||
... for i in test_gen():
|
... for i in test_gen():
|
||||||
... print('value', i)
|
... print('value', i)
|
||||||
... x = 123
|
... x = 123
|
||||||
|
@ -1025,7 +1027,7 @@ class PdbTestCase(unittest.TestCase):
|
||||||
import pdb
|
import pdb
|
||||||
|
|
||||||
def start_pdb():
|
def start_pdb():
|
||||||
pdb.Pdb().set_trace()
|
pdb.Pdb(readrc=False).set_trace()
|
||||||
x = 1
|
x = 1
|
||||||
y = 1
|
y = 1
|
||||||
|
|
||||||
|
@ -1054,13 +1056,47 @@ class PdbTestCase(unittest.TestCase):
|
||||||
.format(expected, stdout))
|
.format(expected, stdout))
|
||||||
|
|
||||||
|
|
||||||
|
def test_readrc_kwarg(self):
|
||||||
|
save_home = os.environ['HOME']
|
||||||
|
save_dir = os.getcwd()
|
||||||
|
script = """import pdb; pdb.Pdb(readrc=False).set_trace()
|
||||||
|
|
||||||
|
print('hello')
|
||||||
|
"""
|
||||||
|
del os.environ['HOME']
|
||||||
|
try:
|
||||||
|
with tempfile.TemporaryDirectory() as dirname:
|
||||||
|
os.chdir(dirname)
|
||||||
|
with open('.pdbrc', 'w') as f:
|
||||||
|
f.write("invalid\n")
|
||||||
|
|
||||||
|
with open('main.py', 'w') as f:
|
||||||
|
f.write(script)
|
||||||
|
|
||||||
|
cmd = [sys.executable, 'main.py']
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
cmd,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
)
|
||||||
|
self.addCleanup(proc.stdout.close)
|
||||||
|
self.addCleanup(proc.stderr.close)
|
||||||
|
stdout, stderr = proc.communicate(b'q\n')
|
||||||
|
self.assertNotIn("NameError: name 'invalid' is not defined",
|
||||||
|
stdout.decode())
|
||||||
|
|
||||||
|
finally:
|
||||||
|
os.environ['HOME'] = save_home
|
||||||
|
os.chdir(save_dir)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
support.unlink(support.TESTFN)
|
support.unlink(support.TESTFN)
|
||||||
|
|
||||||
|
|
||||||
def load_tests(*args):
|
def load_tests(*args):
|
||||||
from test import test_pdb
|
from test import test_pdb
|
||||||
suites = [unittest.makeSuite(PdbTestCase), doctest.DocTestSuite(test_pdb)]
|
suites = [unittest.makeSuite(PdbTestCase)]
|
||||||
return unittest.TestSuite(suites)
|
return unittest.TestSuite(suites)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,10 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #18401: Pdb now supports the 'readrc' keyword argument to control
|
||||||
|
whether .pdbrc files should be read. Patch by Martin Matusiak and
|
||||||
|
Sam Kimbrel.
|
||||||
|
|
||||||
- Issue #25969: Update the lib2to3 grammar to handle the unpacking
|
- Issue #25969: Update the lib2to3 grammar to handle the unpacking
|
||||||
generalizations added in 3.5.
|
generalizations added in 3.5.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue