Skip to content
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

store_into is incompatible with required #385

Open
noajshu opened this issue Nov 12, 2024 · 1 comment
Open

store_into is incompatible with required #385

noajshu opened this issue Nov 12, 2024 · 1 comment

Comments

@noajshu
Copy link

noajshu commented Nov 12, 2024

Previously in #33 a helpful feature required() was added with these rules:

  • doesn't have a default value and is not set. => exception
  • doesn't have a default value and is set without any value. => exception
  • doesn't have a default value and is set with some value. => use the value provided.
  • has a default value and is not set. => use the default value.
  • has a default value and is set without any value. => exception
  • has a default value and is set with some value. => use the value provided.
    (see also A way to require "optional" arguments to present #27)

But if we use the store_into feature, it is incompatible with required. Namely, it cannot recognize that an argument was passed and stored into the specified variable.

MWE:

#include <argparse/argparse.hpp>
int main(int argc, char* argv[]) {
  argparse::ArgumentParser program("cool binary");
  size_t num_threads;
  program.add_argument("--threads")
      .help("Number of threads to use")
      .metavar("N")
      .required()
      .scan<'u', size_t>()
      .default_value(size_t(1))
      .store_into(num_threads);
  program.add_argument("--boxes")
      .help("Number of boxes to use")
      .metavar("B")
      .required()
      .scan<'u', size_t>()
      .default_value(size_t(1));

  try {
    program.parse_args(argc, argv);
  } catch (const std::exception& err) {
    std::cerr << err.what() << std::endl;
    std::cerr << program;
    return EXIT_FAILURE;
  }

  size_t num_boxes = program.get<size_t>("--boxes");

  std::cout << "got num_threads = " << num_threads
            << " num_boxes = " << num_boxes << std::endl;
}

Test script:

clang++ -I argparse/include/ example.cc -o example
for a1 in " " "--threads " "--threads 2 "; do
  for a2 in " " "--boxes " "--boxes 3 "; do
    echo ./example $a1 $a2
    ./example $a1 $a2
  done
done

Output (edited for clarity):

# This works (falls back to default values):
./example
got num_threads = 1 num_boxes = 1

# This raises an exception, as it should
./example --boxes
--boxes: no value provided.

# This also works:
./example --boxes 3
got num_threads = 1 num_boxes = 3

# This raises an exception, as it should
./example --threads
--threads: no value provided.

# This raises an exception, as it should
./example --threads --boxes
--boxes: no value provided.

# This raises an exception, as it should
./example --threads --boxes 3
--threads: no value provided.

# This fails, raising an exception even though `--threads` has a value.
./example --threads 2
--threads: no value provided.

# This raises an exception, as it should
./example --threads 2 --boxes
--boxes: no value provided.

# This fails, raising an exception even though `--threads` has a value.
./example --threads 2 --boxes 3
--threads: no value provided.
@geon6
Copy link

geon6 commented Nov 27, 2024

It may make sense
https://geon6.github.io/posts/argparse-issue-385/

@geon6 geon6 mentioned this issue Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants