Skip to content

Incorrect error message for .allRemainingInput options without values #750

@james-fletcher-01

Description

@james-fletcher-01

Issue #434 reported that when a label, but no values, are provided for an array @Option property, the error message incorrectly signifies a missing option instead of a missing value. PR #435 fixed this for .upToNextOption arrays, but the bug remained for .allRemainingInput arrays.

Example

@main
struct Example: ParsableCommand {
  @Option(parsing: .remaining)
  var test: [String]

  mutating func run() throws {
    print(test)
  }
}

Expected Behaviour

$ example --test
Error: Missing value for '--test <test>'

Actual Behaviour

$ example --test
Error: Missing expected argument '--test <test> ...'

Unexpected Side-Effect

I created a commit that fixes this issue for .allRemainingInput arrays at james-fletcher-01/swift-argument-parser@1bf93bf. However, this change breaks the following test:

func testParsing_repeatingStringRemaining_2() {
  AssertParse(Baz.self, ["--names"]) { baz in
    XCTAssertFalse(baz.verbose)
    XCTAssertTrue(baz.names.isEmpty)
  }
}

This implies that for options with a default value, the expected behavior is for an option label without a value to essentially be ignored and retain the default value. For example, while the above test uses an empty array as the default value, this works as well:

struct NonEmptyDefaultValue: ParsableArguments {
  @Option(parsing: .remaining)
  var names = ["default"]
}

func testNonEmptyDefaultValue() {
  AssertParse(NonEmptyDefaultValue.self, ["--names"]) { baz in
    XCTAssertEqual(baz.names, ["default"])
  }
}

It's surprising to me that this would be the expected behaviour.

  • No other parsing strategy accepts an option label without a value. This includes single values strategies, as well as .upToNextOption.
  • In the example where the default is an empty array, it kind of makes sense. But the example I provided above seems especially counter-intuitive, since you explicitly provided an "empty option" but ended up with a non-empty value.

So if this really is expected behaviour, I can modify my changes to detect the presence of a default value and supress the error message before I submit a PR. But I would just like to get others' thoughts on this?

ArgumentParser version: main
Swift version: swift-driver version: 1.115.1 Apple Swift version 6.0.3 (swiftlang-6.0.3.1.10 clang-1600.0.30.1)

Checklist

  • If possible, I've reproduced the issue using the main branch of this package
  • I've searched for existing GitHub issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions