From 2eb6eca3e5118009b6b74b444d73aa377fb44098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Fri, 9 Sep 2016 22:21:17 -0700 Subject: Issue #18401: pdb tests don't read ~/.pdbrc anymore Patch by Martin Matusiak and Sam Kimbrel. --- Doc/library/pdb.rst | 8 +++++- Lib/pdb.py | 22 +++++++++------- Lib/test/test_pdb.py | 74 ++++++++++++++++++++++++++++++++++++++-------------- Misc/NEWS | 4 +++ 4 files changed, 78 insertions(+), 30 deletions(-) diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index d77de2e..4b912f7 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -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: .. class:: Pdb(completekey='tab', stdin=None, stdout=None, skip=None, \ - nosigint=False) + nosigint=False, readrc=True) :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 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*:: 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 Pdb. + .. versionadded:: 3.5 + The *readrc* argument. + .. method:: run(statement, globals=None, locals=None) runeval(expression, globals=None, locals=None) runcall(function, *args, **kwds) diff --git a/Lib/pdb.py b/Lib/pdb.py index b11ac0a..7eb78b9 100755 --- a/Lib/pdb.py +++ b/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 debugger prompt. This is particularly useful for aliases. If both 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 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): def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, - nosigint=False): + nosigint=False, readrc=True): bdb.Bdb.__init__(self, skip=skip) cmd.Cmd.__init__(self, completekey, stdin, stdout) if stdout: @@ -158,18 +159,19 @@ class Pdb(bdb.Bdb, cmd.Cmd): # Read $HOME/.pdbrc and ./.pdbrc self.rcLines = [] - if 'HOME' in os.environ: - envHome = os.environ['HOME'] + if readrc: + 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: - with open(os.path.join(envHome, ".pdbrc")) as rcFile: + with open(".pdbrc") as rcFile: self.rcLines.extend(rcFile) except OSError: 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_doprompt = {} # for each bp num, tells if the prompt diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index a63ccd8..c39cc97 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1,8 +1,10 @@ # A test suite for pdb; not very comprehensive at the moment. import doctest +import os import pdb import sys +import tempfile import types import unittest import subprocess @@ -34,7 +36,7 @@ def test_pdb_displayhook(): """This tests the custom displayhook for pdb. >>> def test_function(foo, bar): - ... import pdb; pdb.Pdb(nosigint=True).set_trace() + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() ... pass >>> with PdbTestInput([ @@ -74,7 +76,7 @@ def test_pdb_basic_commands(): ... return foo.upper() >>> 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') ... print(ret) @@ -173,7 +175,7 @@ def test_pdb_breakpoint_commands(): """Test basic commands related to breakpoints. >>> def test_function(): - ... import pdb; pdb.Pdb(nosigint=True).set_trace() + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() ... print(1) ... print(2) ... print(3) @@ -305,7 +307,7 @@ def test_list_commands(): ... return foo >>> 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') >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE @@ -328,7 +330,7 @@ def test_list_commands(): -> ret = test_function_2('baz') (Pdb) list 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') [EOF] (Pdb) step @@ -391,7 +393,7 @@ def test_post_mortem(): ... print('Exception!') >>> def test_function(): - ... import pdb; pdb.Pdb(nosigint=True).set_trace() + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() ... test_function_2() ... print('Not reached.') @@ -424,7 +426,7 @@ def test_post_mortem(): -> 1/0 (Pdb) list 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() 4 print('Not reached.') [EOF] @@ -448,7 +450,7 @@ def test_pdb_skip_modules(): >>> def skip_module(): ... 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') >>> with PdbTestInput([ @@ -477,7 +479,7 @@ def test_pdb_skip_modules_with_callback(): >>> def skip_module(): ... def callback(): ... 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) >>> with PdbTestInput([ @@ -518,7 +520,7 @@ def test_pdb_continue_in_bottomframe(): """Test that "continue" and "next" work properly in bottom frame (issue #5294). >>> 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.botframe = sys._getframe() # hackery to get the right botframe ... print(1) @@ -558,7 +560,7 @@ def test_pdb_continue_in_bottomframe(): def pdb_invoke(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(): @@ -607,7 +609,7 @@ def test_next_until_return_at_return_event(): ... x = 2 >>> 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() @@ -673,7 +675,7 @@ def test_pdb_next_command_for_generator(): ... yield 2 >>> def test_function(): - ... import pdb; pdb.Pdb(nosigint=True).set_trace() + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() ... it = test_gen() ... try: ... if next(it) != 0: @@ -733,7 +735,7 @@ def test_pdb_return_command_for_generator(): ... yield 2 >>> def test_function(): - ... import pdb; pdb.Pdb(nosigint=True).set_trace() + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() ... it = test_gen() ... try: ... if next(it) != 0: @@ -788,7 +790,7 @@ def test_pdb_until_command_for_generator(): ... yield 2 >>> 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(): ... print(i) ... print("finished") @@ -830,7 +832,7 @@ def test_pdb_next_command_in_generator_for_loop(): ... return 1 >>> 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(): ... print('value', i) ... x = 123 @@ -875,7 +877,7 @@ def test_pdb_next_command_subiterator(): ... return x >>> 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(): ... print('value', i) ... x = 123 @@ -1025,7 +1027,7 @@ class PdbTestCase(unittest.TestCase): import pdb def start_pdb(): - pdb.Pdb().set_trace() + pdb.Pdb(readrc=False).set_trace() x = 1 y = 1 @@ -1054,13 +1056,47 @@ class PdbTestCase(unittest.TestCase): .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): support.unlink(support.TESTFN) def load_tests(*args): from test import test_pdb - suites = [unittest.makeSuite(PdbTestCase), doctest.DocTestSuite(test_pdb)] + suites = [unittest.makeSuite(PdbTestCase)] return unittest.TestSuite(suites) diff --git a/Misc/NEWS b/Misc/NEWS index 5628dc9..defb4f9 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -135,6 +135,10 @@ Core and Builtins 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 generalizations added in 3.5. -- cgit v0.12