Repository navigation
Confusing error message when options for python are erroneously quoted #132414
Description
Activity
- addedtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Apr 11, 2025 - addedinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
on Apr 11, 2025 What's the behavior of other CLIs like
ls,cp, etc in this case?- changed the title
[-]Confusing error message when options are erroneously quoted[/-][+]Confusing error message when options for `python` are erroneously quoted[/+]on Apr 11, 2025 Oh, sensible question.
$ ls "-l -a" ls: invalid option -- ' ' $ ls "-q" ls: invalid option -- 'q' $ ls -a-s-d ls: invalid option -- '-' $ ls --a-sdsd ls: unrecognized option '--a-sdsd' $ cp "-v -v" cp: invalid option -- ' ' $ which "-a -a" # note: zsh builtin which: bad option: - $ /bin/which "-a -a" /bin/which: invalid option -- ' ' /bin/which: invalid option -- '-' $ perl "-p -u" perl # unquotes the argument and executes normallyGNU coreutils programs like
cpandlsuse seem to unconditionally quote the argument.cpandlsprint the first failure,whichseems to print all of them.zsh's
whichbuiltin matches python behavior. Note that it doesn't support long-form options.perl is doing its own thing.
I think we should follow GNU coreutils as we would have less ambiguities, namely
"invalid option -- '<FAILURE>'".Let's hear the opinion of people who worked on some accessibility REPL issues @hugovk @pablogsal @serhiy-storchaka
Reacted by Serhiy Storchaka, Zachary Vance and Eric V. SmithI think GNU coreutils is an okay default, but can we do better?
invalid option --doesn't really tell me anything about what I need to do to get it working. Can we give an actionable message?Or is it safe to act like perl and unquote the arguments and execute normally?
btw I use https://github.com/lsd-rs/lsd as an alias for
lsand it tries to be more useful, but doesn't really help:❯ ls "-l -a" error: unexpected argument '- ' found tip: to pass '- ' as a value, use '-- - ' Usage: lsd [OPTIONS] [FILE]...An actionable message is just a guess. It can be correct, it can be wrong. This is not common issue, and we cannot be sure that special message will be helpful and not add more confusion.
Acting like perl is unsafe. If the guess is not correct, it will silently do wrong things instead of just printing (possibly unclear) message.
Reacted by Pablo Galindo Salgado and Hugo van KemenadeI agree with @serhiy-storchaka
Right, to summarize (there are a lot of thumbs-ups) everyone asked is in agreement to follow the coreutils example of
/bin/python: invalid option -- '<FAILURE>'Although both of the following have some of the same virtues for the same input
/bin/python: invalid option -- ' ' /bin/python: invalid option -- '-q -i'I'm pretty sure we prefer the exact option coreutils uses (the first), and which has therefore been (1) tested for a few decades and (2) will be familiar to users.
I've opened the PR implementing the coreutils style agreed above.
Short options print
Invalid option -- 'X'.
Long options printInvalid option '--name', without the separator, as coreutils does.$ python "-q -i" Invalid option -- ' ' $ python --foo Invalid option '--foo'
Reacted by Zachary Vance
Bug report
Bug description:
#!/bin/python -q -iI was writing an unrelated post about shebang lines tricks+tips, and happened to pick python as an example, only to discover some weird behavior. The above gets parsed as
/bin/python "-q -i" <path/to/script>But the message python prints is quite confusing:
What's happening is that the "unknown option" is a single space, being parsed as a short-form option, and printed. But the output is pretty opaque, since the space is not quoted, and it's just a trailing invisible space.
Aside: Several other invalid one-byte options like
\nget printed wrongly. This doesn't seem worth fixing.Proposed fix:
I think the shebang case happens to users often enough that it would be good to have some kind of better error message if a short-form options list contains either of
-(this would require scanning ahead!), which either indicates some quoting problem, or an incorrect long-form option (-check-hash-based-pycsrather than--check-hash-based-pycs).I think a good error message could be
unknown option: -q -iorunknown option: "-q -i". Quoting the argument when it contains a space seems clearer to me.The current long-form options have pretty clear error messages either way, mostly by happenstance.
Currently,
-help-*parses as-hwhich then prints help, stopping option parsing. I have no strong opinion about whether that behavior is better or worse than printing an error message.CPython versions tested on:
3.13
Operating systems tested on:
Linux
Linked PRs