ukify: avoid treating invalid option as an argument

For some reason, argparse treats undefined options as positional args in
certain scenarios:

$ src/ukify/ukify.py --badopt='11'
ukify.py: error: unrecognized arguments: --badopt=11
$ src/ukify/ukify.py --badopt '11'
ukify.py: error: unrecognized arguments: --badopt
$ src/ukify/ukify.py --badopt '11 12'
Assuming obsolete command line syntax with no verb. Please use 'build'.
Traceback (most recent call last):
  File "/home/zbyszek/src/systemd/src/ukify/ukify.py", line 2497, in <module>
    main()
    ~~~~^^
  File "/home/zbyszek/src/systemd/src/ukify/ukify.py", line 2485, in main
    check_inputs(opts)
    ~~~~~~~~~~~~^^^^^^
  File "/home/zbyszek/src/systemd/src/ukify/ukify.py", line 671, in check_inputs
    value.open().close()
    ~~~~~~~~~~^^
  File "/usr/lib64/python3.13/pathlib/_local.py", line 537, in open
    return io.open(self, mode, buffering, encoding, errors, newline)
           ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '--badopt=11 12'

I suspect that this is some crap compat for Windows, where option parsing is
an even bigger mess than here.

Being told about positional args, when no positional args were specified is
confusing, so add a check for this.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2025-03-05 11:17:33 +01:00
parent bd208a5421
commit 6446c7d99b
+6
View File
@@ -2485,6 +2485,12 @@ def finalize_options(opts: argparse.Namespace) -> None:
def parse_args(args: Optional[list[str]] = None) -> argparse.Namespace:
opts = create_parser().parse_args(args)
# argparse puts some unknown options in opts.positional. Make sure we don't
# try to interpret something that is an option as a positional argument.
if any((bad_opt := o).startswith('-') for o in opts.positional):
raise ValueError(f'Unknown option: {bad_opt.partition("=")[0]}')
apply_config(opts)
finalize_options(opts)
return opts