Skip to content

Commit cc0b883

Browse files
adamchainznicoddemuswebknjaz
committed
Copy docstrings to wrapped pdb methods
Co-authored-by: Bruno Oliveira <[email protected]> Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) <[email protected]>
1 parent 24e84f0 commit cc0b883

File tree

3 files changed

+83
-6
lines changed

3 files changed

+83
-6
lines changed

changelog/12946.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed missing help for :mod:`pdb` commands wrapped by pytest -- by :user:`adamchainz`.

src/_pytest/debugging.py

+14-6
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ def do_debug(self, arg):
159159
cls._recursive_debug -= 1
160160
return ret
161161

162+
if hasattr(pdb_cls, "do_debug"):
163+
do_debug.__doc__ = pdb_cls.do_debug.__doc__
164+
162165
def do_continue(self, arg):
163166
ret = super().do_continue(arg)
164167
if cls._recursive_debug == 0:
@@ -185,22 +188,27 @@ def do_continue(self, arg):
185188
self._continued = True
186189
return ret
187190

191+
if hasattr(pdb_cls, "do_continue"):
192+
do_continue.__doc__ = pdb_cls.do_continue.__doc__
193+
188194
do_c = do_cont = do_continue
189195

190196
def do_quit(self, arg):
191-
"""Raise Exit outcome when quit command is used in pdb.
192-
193-
This is a bit of a hack - it would be better if BdbQuit
194-
could be handled, but this would require to wrap the
195-
whole pytest run, and adjust the report etc.
196-
"""
197+
# Raise Exit outcome when quit command is used in pdb.
198+
#
199+
# This is a bit of a hack - it would be better if BdbQuit
200+
# could be handled, but this would require to wrap the
201+
# whole pytest run, and adjust the report etc.
197202
ret = super().do_quit(arg)
198203

199204
if cls._recursive_debug == 0:
200205
outcomes.exit("Quitting debugger")
201206

202207
return ret
203208

209+
if hasattr(pdb_cls, "do_quit"):
210+
do_quit.__doc__ = pdb_cls.do_quit.__doc__
211+
204212
do_q = do_quit
205213
do_exit = do_quit
206214

testing/test_debugging.py

+68
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ def reset(self):
5252
def interaction(self, *args):
5353
called.append("interaction")
5454

55+
# Methods which we copy docstrings to.
56+
def do_debug(self, *args): # pragma: no cover
57+
pass
58+
59+
def do_continue(self, *args): # pragma: no cover
60+
pass
61+
62+
def do_quit(self, *args): # pragma: no cover
63+
pass
64+
5565
_pytest._CustomPdb = _CustomPdb # type: ignore
5666
return called
5767

@@ -75,6 +85,16 @@ def set_trace(self, frame):
7585
print("**CustomDebugger**")
7686
called.append("set_trace")
7787

88+
# Methods which we copy docstrings to.
89+
def do_debug(self, *args): # pragma: no cover
90+
pass
91+
92+
def do_continue(self, *args): # pragma: no cover
93+
pass
94+
95+
def do_quit(self, *args): # pragma: no cover
96+
pass
97+
7898
_pytest._CustomDebugger = _CustomDebugger # type: ignore
7999
yield called
80100
del _pytest._CustomDebugger # type: ignore
@@ -965,6 +985,34 @@ def test_1():
965985
child.sendeof()
966986
self.flush(child)
967987

988+
def test_pdb_wrapped_commands_docstrings(self, pytester: Pytester) -> None:
989+
p1 = pytester.makepyfile(
990+
"""
991+
def test_1():
992+
assert False
993+
"""
994+
)
995+
996+
child = pytester.spawn_pytest(f"--pdb {p1}")
997+
child.expect("Pdb")
998+
999+
# Verify no undocumented commands
1000+
child.sendline("help")
1001+
child.expect("Documented commands")
1002+
assert "Undocumented commands" not in child.before.decode()
1003+
1004+
child.sendline("help continue")
1005+
child.expect("Continue execution")
1006+
child.expect("Pdb")
1007+
1008+
child.sendline("help debug")
1009+
child.expect("Enter a recursive debugger")
1010+
child.expect("Pdb")
1011+
1012+
child.sendline("c")
1013+
child.sendeof()
1014+
self.flush(child)
1015+
9681016

9691017
class TestDebuggingBreakpoints:
9701018
@pytest.mark.parametrize("arg", ["--pdb", ""])
@@ -1288,6 +1336,16 @@ def set_trace(self, *args):
12881336
12891337
def runcall(self, *args, **kwds):
12901338
print("runcall_called", args, kwds)
1339+
1340+
# Methods which we copy the docstring over.
1341+
def do_debug(self, *args):
1342+
pass
1343+
1344+
def do_continue(self, *args):
1345+
pass
1346+
1347+
def do_quit(self, *args):
1348+
pass
12911349
""",
12921350
)
12931351
result = pytester.runpytest(
@@ -1354,6 +1412,16 @@ def __init__(self, *args, **kwargs):
13541412
13551413
def set_trace(self, *args):
13561414
print("set_trace_called", args)
1415+
1416+
# Methods which we copy the docstring over.
1417+
def do_debug(self, *args):
1418+
pass
1419+
1420+
def do_continue(self, *args):
1421+
pass
1422+
1423+
def do_quit(self, *args):
1424+
pass
13571425
""",
13581426
)
13591427
result = pytester.runpytest(str(p1), "--pdbcls=mypdb:MyPdb", syspathinsert=True)

0 commit comments

Comments
 (0)