@@ -644,7 +644,7 @@ def do_commands(self, arg):
644
644
try :
645
645
bnum = int (arg )
646
646
except :
647
- self .error ( "Usage: commands [bnum] \n ... \n end" )
647
+ self ._print_invalid_arg ( arg )
648
648
return
649
649
try :
650
650
self .get_bpbynumber (bnum )
@@ -941,14 +941,22 @@ def do_ignore(self, arg):
941
941
condition evaluates to true.
942
942
"""
943
943
args = arg .split ()
944
- try :
945
- count = int (args [1 ].strip ())
946
- except :
944
+ if not args :
945
+ self .error ('Breakpoint number expected' )
946
+ return
947
+ if len (args ) == 1 :
947
948
count = 0
949
+ elif len (args ) == 2 :
950
+ try :
951
+ count = int (args [1 ])
952
+ except ValueError :
953
+ self ._print_invalid_arg (arg )
954
+ return
955
+ else :
956
+ self ._print_invalid_arg (arg )
957
+ return
948
958
try :
949
959
bp = self .get_bpbynumber (args [0 ].strip ())
950
- except IndexError :
951
- self .error ('Breakpoint number expected' )
952
960
except ValueError as err :
953
961
self .error (err )
954
962
else :
@@ -1025,6 +1033,9 @@ def do_where(self, arg):
1025
1033
An arrow indicates the "current frame", which determines the
1026
1034
context of most commands. 'bt' is an alias for this command.
1027
1035
"""
1036
+ if arg :
1037
+ self ._print_invalid_arg (arg )
1038
+ return
1028
1039
self .print_stack_trace ()
1029
1040
do_w = do_where
1030
1041
do_bt = do_where
@@ -1112,6 +1123,9 @@ def do_step(self, arg):
1112
1123
(either in a function that is called or in the current
1113
1124
function).
1114
1125
"""
1126
+ if arg :
1127
+ self ._print_invalid_arg (arg )
1128
+ return
1115
1129
self .set_step ()
1116
1130
return 1
1117
1131
do_s = do_step
@@ -1122,6 +1136,9 @@ def do_next(self, arg):
1122
1136
Continue execution until the next line in the current function
1123
1137
is reached or it returns.
1124
1138
"""
1139
+ if arg :
1140
+ self ._print_invalid_arg (arg )
1141
+ return
1125
1142
self .set_next (self .curframe )
1126
1143
return 1
1127
1144
do_n = do_next
@@ -1153,6 +1170,9 @@ def do_return(self, arg):
1153
1170
1154
1171
Continue execution until the current function returns.
1155
1172
"""
1173
+ if arg :
1174
+ self ._print_invalid_arg (arg )
1175
+ return
1156
1176
self .set_return (self .curframe )
1157
1177
return 1
1158
1178
do_r = do_return
@@ -1162,6 +1182,9 @@ def do_continue(self, arg):
1162
1182
1163
1183
Continue execution, only stop when a breakpoint is encountered.
1164
1184
"""
1185
+ if arg :
1186
+ self ._print_invalid_arg (arg )
1187
+ return
1165
1188
if not self .nosigint :
1166
1189
try :
1167
1190
Pdb ._previous_sigint_handler = \
@@ -1256,6 +1279,9 @@ def do_args(self, arg):
1256
1279
1257
1280
Print the argument list of the current function.
1258
1281
"""
1282
+ if arg :
1283
+ self ._print_invalid_arg (arg )
1284
+ return
1259
1285
co = self .curframe .f_code
1260
1286
dict = self .curframe_locals
1261
1287
n = co .co_argcount + co .co_kwonlyargcount
@@ -1274,6 +1300,9 @@ def do_retval(self, arg):
1274
1300
1275
1301
Print the return value for the last return of a function.
1276
1302
"""
1303
+ if arg :
1304
+ self ._print_invalid_arg (arg )
1305
+ return
1277
1306
if '__return__' in self .curframe_locals :
1278
1307
self .message (repr (self .curframe_locals ['__return__' ]))
1279
1308
else :
@@ -1390,6 +1419,9 @@ def do_longlist(self, arg):
1390
1419
1391
1420
List the whole source code for the current function or frame.
1392
1421
"""
1422
+ if arg :
1423
+ self ._print_invalid_arg (arg )
1424
+ return
1393
1425
filename = self .curframe .f_code .co_filename
1394
1426
breaklist = self .get_file_breaks (filename )
1395
1427
try :
@@ -1570,7 +1602,9 @@ def do_unalias(self, arg):
1570
1602
Delete the specified alias.
1571
1603
"""
1572
1604
args = arg .split ()
1573
- if len (args ) == 0 : return
1605
+ if len (args ) == 0 :
1606
+ self ._print_invalid_arg (arg )
1607
+ return
1574
1608
if args [0 ] in self .aliases :
1575
1609
del self .aliases [args [0 ]]
1576
1610
@@ -1723,7 +1757,7 @@ def _getsourcelines(self, obj):
1723
1757
lineno = max (1 , lineno )
1724
1758
return lines , lineno
1725
1759
1726
- def _help_message_from_doc (self , doc ):
1760
+ def _help_message_from_doc (self , doc , usage_only = False ):
1727
1761
lines = [line .strip () for line in doc .rstrip ().splitlines ()]
1728
1762
if not lines :
1729
1763
return "No help message found."
@@ -1739,10 +1773,24 @@ def _help_message_from_doc(self, doc):
1739
1773
elif i < usage_end :
1740
1774
prefix = " "
1741
1775
else :
1776
+ if usage_only :
1777
+ break
1742
1778
prefix = ""
1743
1779
formatted .append (indent + prefix + line )
1744
1780
return "\n " .join (formatted )
1745
1781
1782
+ def _print_invalid_arg (self , arg ):
1783
+ """Return the usage string for a function."""
1784
+
1785
+ self .error (f"Invalid argument: { arg } " )
1786
+
1787
+ # Yes it's a bit hacky. Get the caller name, get the method based on
1788
+ # that name, and get the docstring from that method.
1789
+ # This should NOT fail if the caller is a method of this class.
1790
+ doc = inspect .getdoc (getattr (self , sys ._getframe (1 ).f_code .co_name ))
1791
+ if doc is not None :
1792
+ self .message (self ._help_message_from_doc (doc , usage_only = True ))
1793
+
1746
1794
# Collect all command help into docstring, if not run with -OO
1747
1795
1748
1796
if __doc__ is not None :
0 commit comments