Normally if a value to an argument is passed that is not in the choices list an error like "test.py: error: argument --test: invalid choice: 'c' (choose from 'a', 'b')" is shown. But if the default is set to an invalid choice no error is shown.
I was thinking about cases where the default is variable for example a call to platform.machine() while the choices list (and the script itself) might not support all exotic architectures for its use that might be returned now or in a future version of Python from this function. In this case the call to platform.machine() could be wrapped into a function that checks if the returned value is one of the values in the choices list but that would be the same that I would normally expect to be done by the argparse module.
I assume you are talking about the behavior of the argparse 'choices' feature? That is what my comment was addressed to. I didn't actually run a test to see if it behaves the way you describe :)
A related issue which Sworddragon found just before starting this issue is http://bugs.python.org/issue9625 The handling of defaults in argparse is a bit complicated. In general it errs on the side of giving the user/developer freedom to set them how ever they want. That's especially true in the case of non-string defaults. A default does not have to be something that the user could give. In particular the default 'default' is None, which can't be parsed from the command line. The same for boolean values (the default 'type' does not translate string 'False' to boolean 'False'.) Errors in the defaults are usually caught during program development. If the calling code generates the defaults dynamically, it seems reasonable that it should also check that they are valid. The validity test for choices is a simple 'in' (contains) one. 'choices' can be a list or dictionary (keys), and can even be dynamically generated. parser = .... choices = default = if default not in choices: parser.add_argument(..., choices=choices, default=default) etc.