python argparse check choices before type

  • Last Update :
  • Techknowledgy :

Yes, during parsing the type then choices order is clear and intentional (and not just incidental). When preparing to assign arg_strings to the namespace it calls _get_values, which does:

  def _get_values(self, action, arg_strings)
     ....(various nargs tests)
  value = self._get_value(action, arg_string)
  self._check_value(action, value)
  return value

where _get_value applies the action.type function, and _check_value tests

value not in action.choices

Apparently so, however you can work around this simply by using functions.keys() as your choices, e.g.

import argparse

def foo():
   return 'foo'

def bar():
   return 'bar'

parser = argparse.ArgumentParser()
functions = {
   f.__name__: f
   for f in [foo, bar]
}
parser.add_argument("function", type = lambda f: functions.get(f), help = "which function", choices = functions.values())
args = parser.parse_args()
print(args.function())

Suggestion : 2

Note that inclusion in the choices container is checked after any type conversions have been performed, so the type of the objects in the choices container should match the type specified:,By default, the parser reads command-line arguments in as simple strings. However, quite often the command-line string should instead be interpreted as another type, such as a float or int. The type keyword for add_argument() allows any necessary type-checking and type conversions to be performed.,The ArgumentParser object will hold all the information necessary to parse the command line into Python data types.,The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.

import argparse

parser = argparse.ArgumentParser(description = 'Process some integers.')
parser.add_argument('integers', metavar = 'N', type = int, nargs = '+',
   help = 'an integer for the accumulator')
parser.add_argument('--sum', dest = 'accumulate', action = 'store_const',
   const = sum,
   default = max,
   help = 'sum the integers (default: find the max)')

args = parser.parse_args()
print(args.accumulate(args.integers))
$ python prog.py - h
usage: prog.py[-h][--sum] N[N...]

Process some integers.

positional arguments:
   N an integer
for the accumulator

options:
   -h, --help show this help message and exit
   --sum sum the integers(
      default: find the max)
$ python prog.py 1 2 3 4
4

$ python prog.py 1 2 3 4--sum
10
$ python prog.py a b c
usage: prog.py[-h][--sum] N[N...]
prog.py: error: argument N: invalid int value: 'a'
>>> parser = argparse.ArgumentParser(description = 'Process some integers.')
>>> parser.add_argument('integers', metavar = 'N', type = int, nargs = '+',
      ...help = 'an integer for the accumulator') >>>
   parser.add_argument('--sum', dest = 'accumulate', action = 'store_const',
      ...
      const = sum,
      default = max,
      ...help = 'sum the integers (default: find the max)')

Suggestion : 3

I'm trying to enable a user to pass in a function name. For some reason it seems that argparse performs the type check/conversion BEFORE it checks the choices. Is this a bug? Best thing to do? , metavar is your most powerful tool for replacing an undesirable choices list. I'd have to run a test case to see whether it solves things for all 3 situations. , Yes, during parsing the type then choices order is clear and intentional (and not just incidental). When preparing to assign arg_strings to the namespace it calls _get_values , which does: , *edit : * check What is the most effective way for float and double comparison? for more information about comparing floats.

I'm trying to enable a user to pass in a function name. For some reason it seems that argparse performs the type check/conversion BEFORE it checks the choices. Is this a bug? Best thing to do?

import argparse

def foo():
   return 'foo'

def bar():
   return 'bar'

parser = argparse.ArgumentParser()
functions = {
   f.__name__: f
   for f in [foo, bar]
}
parser.add_argument("function", type = lambda f: functions.get(f), help = "which function", choices = functions)
args = parser.parse_args()
print(args.function())

This throws:

$ python blah.py foo
usage: blah.py [-h] {foo,bar}
blah.py: error: argument function: invalid choice: <function foo at 0x7f65746dd848> (choose from 'foo', 'bar')

Yes, during parsing the type then choices order is clear and intentional (and not just incidental). When preparing to assign arg_strings to the namespace it calls _get_values , which does:

  def _get_values(self, action, arg_strings)
     ....(various nargs tests)
  value = self._get_value(action, arg_string)
  self._check_value(action, value)
  return value

where _get_value applies the action.type function, and _check_value tests

value not in action.choices

Apparently so, however you can work around this simply by using functions.keys() as your choices, e.g.

import argparse

def foo():
   return 'foo'

def bar():
   return 'bar'

parser = argparse.ArgumentParser()
functions = {
   f.__name__: f
   for f in [foo, bar]
}
parser.add_argument("function", type = lambda f: functions.get(f), help = "which function", choices = functions.values())
args = parser.parse_args()
print(args.function())

Edit, again : I just saw your comment :

'use strict'

var numVertices = 100,
   temp = [];

var RAND_MAX = 32767;

for (var i = 0; i < 5; i++) {
   var place = parseInt(Math.random() * numVertices), // C++ : rand() % numVertices
      valid = true;
   //place = place * numVertices;
   for (var x = 0; x < temp.length; x++) {
      if (temp[x] == place) {
         i--;
         valid = false;
         break
      }
   }
   if (valid) temp[i] = place;
}
console.log(temp);

*edit : * check What is the most effective way for float and double comparison? for more information about comparing floats.

'use strict'

var numVertices = 5,
   temp = [];

var RAND_MAX = 32767,
   EPSILON = 1.00000001

for (var i = 0; i < 5 || i < numVertices; i++) {
   var place = Math.random(),
      valid = true;
   place = place / RAND_MAX * numVertices;
   for (var x = 0; x < temp.length; x++) {
      if (Math.abs(temp[x] - place) > EPSILON) { //Math.abs == fabs in C/C++
         i--;
         valid = false;
         break
      }
   }
   if (valid) temp[i] = place;
}
console.log(temp);

Change in main.js this line:

$(document).ready(function() {

to

jQuery(document).ready(function($) {

You should bracket the table names and "position" as well.

update[Regional Personnel$]
set[Regional Personnel$].name = 'Ada Lovelace',
   [Regional Personnel$].phone = '(303) 555-1337',
   [Regional Personnel$].[lan id] = 'ADL3',
   [Regional Personnel$].[position] = 'Engineer'
where[Regional Personnel$].id = 3

Suggestion : 4

The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.,Create a mutually exclusive group. argparse will make sure that only one of the arguments in the mutually exclusive group was present on the command line:,argparse.REMAINDER. All the remaining command-line arguments are gathered into a list. This is commonly useful for command line utilities that dispatch to other command line utilities:,The fromfile_prefix_chars= argument defaults to None, meaning that arguments will never be treated as file references.

import argparse

parser = argparse.ArgumentParser(description = 'Process some integers.')
parser.add_argument('integers', metavar = 'N', type = int, nargs = '+',
   help = 'an integer for the accumulator')
parser.add_argument('--sum', dest = 'accumulate', action = 'store_const',
   const = sum,
   default = max,
   help = 'sum the integers (default: find the max)')

args = parser.parse_args()
print(args.accumulate(args.integers))
$ python prog.py - h
usage: prog.py[-h][--sum] N[N...]

Process some integers.

positional arguments:
   N an integer
for the accumulator

optional arguments:
   -h, --help show this help message and exit
   --sum sum the integers(
      default: find the max)
$ python prog.py 1 2 3 4
4

$ python prog.py 1 2 3 4--sum
10
$ python prog.py a b c
usage: prog.py[-h][--sum] N[N...]
prog.py: error: argument N: invalid int value: 'a'
>>> parser = argparse.ArgumentParser(description = 'Process some integers.')
>>> parser.add_argument('integers', metavar = 'N', type = int, nargs = '+',
      ...help = 'an integer for the accumulator') >>>
   parser.add_argument('--sum', dest = 'accumulate', action = 'store_const',
      ...
      const = sum,
      default = max,
      ...help = 'sum the integers (default: find the max)')