Relay parsing error information to argparse, don't except on command argument parse error (#2711)

* relay parsing error information to argparse

* fix gdb_mod typo in comment
pull/2719/head
k4lizen 11 months ago committed by GitHub
parent a538b6737f
commit e99d4e7f0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -123,6 +123,9 @@ class Command:
def split_args(self, argument: str) -> Tuple[List[str], Dict[Any, Any]]:
"""Split a command-line string from the user into arguments.
This is only used by pwndbg/commands/shell.py which is deprecated.
Usually _ArgparsedCommand.split_args is called.
Returns:
A ``(tuple, dict)``, in the form of ``*args, **kwargs``.
The contents of the tuple/dict are undefined.
@ -139,6 +142,7 @@ class Command:
args, kwargs = self.split_args(argument)
except SystemExit:
# Raised when the usage is printed by an ArgparsedCommand
# because of an error in argument parsing
return
except (TypeError, pwndbg.dbg_mod.Error):
pwndbg.exception.handle(self.function.__name__)
@ -264,6 +268,18 @@ def fix_reraise(*a, **kw) -> str | pwndbg.dbg_mod.Value | None:
return fix(*a, reraise=True, **kw) # type: ignore[misc]
def fix_reraise_arg(arg) -> pwndbg.dbg_mod.Value:
"""fix_reraise wrapper for evaluating command arguments"""
try:
# Will always return pwndbg.dbg_mod.Value because
# sloppy=False (not str) and reraise=True (not None)
fixed = fix(arg, sloppy=False, quiet=True, reraise=True)
assert isinstance(fixed, pwndbg.dbg_mod.Value)
return fixed
except pwndbg.dbg_mod.Error as dbge:
raise argparse.ArgumentTypeError(f"debugger couldn't resolve argument '{arg}': {dbge}")
def fix_int(*a, **kw) -> int:
return int(fix(*a, **kw))
@ -272,6 +288,17 @@ def fix_int_reraise(*a, **kw) -> int:
return fix_int(*a, reraise=True, **kw)
def fix_int_reraise_arg(arg) -> int:
"""fix_int_reraise wrapper for evaluating command arguments"""
try:
fixed = fix_reraise_arg(arg)
return int(fixed)
except pwndbg.dbg_mod.Error as e:
raise argparse.ArgumentTypeError(
f"couldn't convert '{arg}' ({fixed.type.name_to_human_readable}) to int: {e}"
)
def OnlyWhenLocal(function: Callable[P, T]) -> Callable[P, Optional[T]]:
@functools.wraps(function)
def _OnlyWhenLocal(*a: P.args, **kw: P.kwargs) -> Optional[T]:
@ -604,10 +631,10 @@ class ArgparsedCommand:
action.type = str
if action.dest == "help":
continue
if action.type == int:
action.type = fix_int_reraise
if action.type is int:
action.type = fix_int_reraise_arg
if action.type is None:
action.type = fix_reraise
action.type = fix_reraise_arg
if action.default is not None:
action.help += " (default: %(default)s)"

Loading…
Cancel
Save