docopt icon indicating copy to clipboard operation
docopt copied to clipboard

Invalid options are not recorded in the DocoptExit exception

Open iwonbigbro opened this issue 5 years ago • 2 comments

If I pass an invalid option to my script, it throws a DocoptExit exception, but sets the message to the first line of the usage. This is useless, since it doesn't tell you anything about the options that failed to parse...

Adding a pprint to the exception handler produces this...

myscript.py --junkoption
DocoptExit('Usage: myscript.py [options]')

iwonbigbro avatar Nov 14 '19 21:11 iwonbigbro

Here is a patch that fixes this issue.

diff --git a/docopt.py b/docopt.py
index 7c6a52d..2a36b12 100644
--- a/docopt.py
+++ b/docopt.py
@@ -578,4 +578,8 @@ def docopt(doc, argv=None, help=True, version=None, options_first=False):
     matched, left, collected = pattern.fix().match(argv)
     if matched and left == []:  # better error message if left?
         return Dict((a.name, a.value) for a in (pattern.flat() + collected))
+
+    if left and type(left[0]) is Option:
+        raise DocoptExit('Invalid option -- {}'.format(left[0].name))
+
     raise DocoptExit()
diff --git a/test_docopt.py b/test_docopt.py
index f5bdc37..c95b9a7 100644
--- a/test_docopt.py
+++ b/test_docopt.py
@@ -575,6 +575,15 @@ def test_issue_71_double_dash_is_not_a_valid_option_argument():
                   options: -l LEVEL''', '-l -- 1 2')
 
 
+def test_issue_466_invalid_option_not_reported():
+    with raises(DocoptExit):
+        try:
+            docopt('usage: prog [--help]', ['--garbage'])
+        except DocoptExit as e:
+            assert 'Invalid option -- --garbage' in e.message
+            raise e
+
+
 usage = '''usage: this
 
 usage:hai

iwonbigbro avatar Nov 15 '19 09:11 iwonbigbro

similarly patched here for more informative error...

    extras(help, version, argv, doc)
    matched, left, collected = pattern.fix().match(argv)
    if matched and left == []:  # better error message if left?
        return Dict((a.name, a.value) for a in (pattern.flat() + collected))
    else:
        raise DocoptExit('Error: Following arguments not matched:%s'%(left))

shouldsee avatar Dec 07 '22 06:12 shouldsee