Any command other than convert, new, dev, or upgrade that uses an option that takes a value (e.g., -C <config value>, -d <device ID>) breaks when using Python 3.12.7.
Steps to reproduce
Generate an empty Briefcase project using Toga
Try to run briefcase run -d "iPhone 15 Pro"
See error:
Invalid format 'iPhone 15 Pro'; (choose from: Xcode)
Expected behavior
Options specified after flags should be accepted.
Screenshots
No response
Environment
Operating System: All
Python version: 3.12.7
Software versions:
Briefcase: 0.3.19+
Logs
No response
Additional context
The problem appear to be function of the complex sequence of multiple partial parsings of the command line arguments performed by Briefcase.
In the first pass, Briefcase's command line parser only knows about the core arguments -V and <command> - the values that are valid to a bare briefcase invocation. These are partially parsed, allowing Briefcase to determine which subcommand will be invoked (or if -V or --help should be handled.
In the second pass, the parser adds handling for the optional<platform> and <output_format> placeholders, then reparses the arguments. This allows Briefcase to validate the platform and output format, choosing defaults if they aren't provided.
However, there's an inherent ambiguity at this point. In briefcase run -d 'iPhone' - is 'iPhone' a value for the -d argument, or the value of the platform to pass to the run command? At this point, the parser doesn't have enough information to determine, as -d hasn't been configured in the parser.
Prior to python/cpython#124345 (released in Python 3.12.7; will be in 3.13.1 and 3.13.0a1) the value was considered to be a value for -d. As of 3.12.7, it's considered a value for the platform (i.e., as if -d took no value).
It's difficult to argue this is a bug in Python, because -d hasn't been defined, so there's no reason to believe that "iPhone"will be a value for the -d flag.
This is currently breaking CI, both because of test cases that validate -C foo=bar handling for the run command, plus commands deploying iOS that pass in the device identifier for the test configuration.
The immediate workaround is to not fall back on any platform/output format defaults when using an argument that requires values - i.e., use briefcase run iOS Xcode -d "iPhone 15 Pro", rather than briefcase run iOS -d "iPhone 15 Pro". This ensures that the platform and output format are fully parsed before attempting to handle arguments with values.
Describe the bug
Any command other than
convert
,new
,dev
, orupgrade
that uses an option that takes a value (e.g.,-C <config value>
,-d <device ID>
) breaks when using Python 3.12.7.Steps to reproduce
briefcase run -d "iPhone 15 Pro"
Expected behavior
Options specified after flags should be accepted.
Screenshots
No response
Environment
Logs
No response
Additional context
The problem appear to be function of the complex sequence of multiple partial parsings of the command line arguments performed by Briefcase.
In the first pass, Briefcase's command line parser only knows about the core arguments
-V
and<command>
- the values that are valid to a barebriefcase
invocation. These are partially parsed, allowing Briefcase to determine which subcommand will be invoked (or if-V
or--help
should be handled.In the second pass, the parser adds handling for the optional
<platform>
and<output_format>
placeholders, then reparses the arguments. This allows Briefcase to validate the platform and output format, choosing defaults if they aren't provided.However, there's an inherent ambiguity at this point. In
briefcase run -d 'iPhone'
- is'iPhone'
a value for the-d
argument, or the value of the platform to pass to the run command? At this point, the parser doesn't have enough information to determine, as-d
hasn't been configured in the parser.Prior to python/cpython#124345 (released in Python 3.12.7; will be in 3.13.1 and 3.13.0a1) the value was considered to be a value for
-d
. As of 3.12.7, it's considered a value for the platform (i.e., as if-d
took no value).It's difficult to argue this is a bug in Python, because
-d
hasn't been defined, so there's no reason to believe that"iPhone"
will be a value for the-d
flag.This is currently breaking CI, both because of test cases that validate
-C foo=bar
handling for therun
command, plus commands deploying iOS that pass in the device identifier for the test configuration.The immediate workaround is to not fall back on any platform/output format defaults when using an argument that requires values - i.e., use
briefcase run iOS Xcode -d "iPhone 15 Pro"
, rather thanbriefcase run iOS -d "iPhone 15 Pro"
. This ensures that the platform and output format are fully parsed before attempting to handle arguments with values.