New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AsyncParsableCommand exits before running run() async
#538
Comments
Just to show what works and what doesn't. Running it from Xcode or command line: These three don't work: Note that number three is not async, but the @available is specified at the function level. |
I'm using Swift 5.6, so I need to create a standalone type as your asynchronous @main entry point. |
Reopening it as the documentation of AnycMainProtocol indicates to use @main directly as I was using it which causes the issue above. |
Today I also ran into this issue, my command line tool didn't specify a platform at all in its @main
struct MyCommand: AsyncParsableCommand
mutating func run() async throws {
print("Hello World" )
}
} Debugging shows that the Declaring It would be great if the library can be adjusted so it gives a clear compile error. Or at least the documentation of |
I ran into this or at least a very similar issue as well. I did not use the After looking a bit deeper, I noticed that the default implementation of Reproducible with the following snippet in a import ArgumentParser
struct Foo: AsyncParsableCommand {
mutating func run() async throws {
print("Foo")
}
}
// Like AsyncParsableCommand.main()
do {
var cmd: ParsableCommand = try Foo.parseAsRoot()
if var asyncCmd = cmd as? AsyncParsableCommand {
try await asyncCmd.run()
} else {
try cmd.run()
}
} catch {
Foo.exit(withError: error)
} The Note that the compiler warns that the The underlaying problem seems to be that struct Foo {
func run()
func run() async
} This overload behaviour was introduced in SE-0296, see specifically the section Overloading and overload resolution, and also discussed in the Swift forum. The overloads are called based on their context. If you are in another Seems like the main context in extension AsyncParsableCommand {
mutating func runAsync() async throws {
try await self.run()
}
}
do {
var cmd: ParsableCommand = try Foo.parseAsRoot()
if var asyncCmd = cmd as? AsyncParsableCommand {
//try await asyncCmd.run()
try await asyncCmd.runAsync()
} else {
try cmd.run()
}
} catch {
Foo.exit(withError: error)
} Warpping everything into an There is a similar effect for the func main() async {
await Foo.main()
}
await main() Or disambiguate the overload: extension AsyncParsableCommand {
static func mainAsync() async throws {
try await main()
}
}
await Foo.mainAsync() |
When using an AsyncParsableCommand with @main, the command-line-tool exits without running the
run() async
function and prints the help log.Note:
run()
withoutasync
runs the function.ArgumentParser version:
1.2.0
Swift version: swift-driver version: 1.45.2 Apple Swift version 5.6 (swiftlang-5.6.0.323.62 clang-1316.0.20.8)
MacOS 12.6
Checklist
main
branch of this packageSteps to Reproduce
Option A: Reproduce by running the Example in this repository
Option B:
Expected behavior
The
run() async
function should runActual behavior
The
run() async
function isn't run and the program exits with the help log.The text was updated successfully, but these errors were encountered: