-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
try_from_str and try_from_os_str functions are called twice #3589
Comments
I think that fixing this should be as simple as just never adding the validators, if there is an error in the get phase it is beautifully printed in exactly the same way as the validator would. |
Huh, we had a previous PR for this but no issue. #2683 is the tracking issue for resolving this
There are subtle differences, like color support. |
Bah, you are of course right it is not as simple as I thought,
without validator (only
Since the nice error message relies on the Would you be interested in a PR dropping the validate calls or should I just wait for 4.0? |
I would consider that a blocker for a solution
Even if the final message ends up looking exactly the same, this would be borderline for breaking compatibility due to changes in expectations of behavior. Let's just wait for that 4.0 work to go through. |
4.0 it is then! Thank you for all your hard work and speedy responses. |
Clap parses the arguments twice and that causes issues with systemd activation file descriptors if the parsing logic is not pure. The solution is to allow parsing Bindings and make the conversion to Listeners an explicit action that happens only once. See: clap-rs/clap#3589 Signed-off-by: Wiktor Kwapisiewicz <wiktor@metacode.biz>
For clap 3, its opt-in as a precaution against breaking compatibility in some weird cases. This does require the types to implement `Clone`. Fixes clap-rs#3734 Fixes clap-rs#3496 Fixes clap-rs#3589
I've taken a look at the new way of parsing with One question though: now the structs to be parsed need to I wanted to parse the object and create it only once and intentionally make it non-clone'able since it owns some resources that should not be shared (ie. file descriptors). So it would be really nice if the must-impl-Clone restriction was lifted... An example: use std::convert::TryFrom;
#[derive(Debug)]
struct Xing;
impl Clone for Xing { // this is needed by value_parser
fn clone(&self) -> Self {
todo!() // this is not called
}
}
impl std::str::FromStr for Xing { // FromStr needs to be implemented
type Err = std::io::Error;
fn from_str(_s: &str) -> Result<Self, Self::Err> {
eprintln!("Calling..."); // this is printed only once -> nice!
Ok(Xing)
}
}
use clap::Parser;
#[derive(Parser, Debug)]
struct Args {
#[clap(short, long, value_parser)] // this is new
x: Xing,
}
fn main() {
let args = Args::parse();
println!("Hello, world: {:?}", args);
} |
The derive API is built on top of the builder API. The parser generates data into an Feel free to create an issue for this if you want. An idea I'm playing with for the future is to have At one point, However, I suspect most exclusive resources are not safe to acquire at process start regardless of what happens for the rest of the program and that not needing |
Thanks for the detailed explanation and your work on clap in general! What I'm trying to achieve here is constructing my own objects from command line parameters only once. Previously this was not the case (the objects were constructed twice: once during validation). With So, while technically the issue here is solved (
I'm not sure if that's only me and I don't want to put more work on your plate if this is a rare edge-case but I still wanted to explain my rationale. Thank you for your time! |
@wiktor-k what are your thoughts on adding a Right now we have a |
Please complete the following tasks
Rust Version
rustc 1.58.1 (db9d1b20b 2022-01-20)
Clap Version
3.1.6
Minimal reproducible code
Steps to reproduce the bug with the above code
cargo run
Actual Behaviour
When specifying a parser for an attribute using
try_from_str
and the#[derive(Parser)]
macro the function passed used for parising is called twice, once as part of the validate phase and then again to convert the argument to the expected type.This causes issues when the function is not idemponent, such as opening a file, or performing a network request.
Expected Behaviour
The
try_from_str
should only be called once.Additional Context
No response
Debug Output
The text was updated successfully, but these errors were encountered: