Using argparse does not retain the Namespace variable across sub-parsers. This prohibits customization of Actions due to "upper" level arguments not being stored in the namespace passed to the sub-parsers. Hence, one may not create different sub-parsers which depend on an upper level flag. The reason is the subparser command: subnamespace, arg_strings = parser.parse_known_args(arg_strings, None) Which by default passes `None` as the namespace argument. A simple patch would be to copy the original namespace, which may then be altered. And subsequently restored, based on changes to that namespace.
This call used to be namespace, arg_strings = parser.parse_known_args(arg_strings, namespace) But in 2014 (2.7.9) http://bugs.python.org/issue9351 was implemented As noted in the title and comment in the code, the idea was to give more power to the defaults set in the subparser. But as noted in the subsequent posts, the patch has raised some backward compatibility issues. Generally having the action for one argument depend on the value of another argument is tricky, because arguments may be parsed in any order. (but there is a 'test_argparse.py' case that does that kind of testing). It is safer to test for any interactions after parsing is all done. Now in the subparser case, there is an order. Main parser arguments have to come first. I suggested in 9351 a way of allowing both behaviors - use of new namespace or use of the existing one. But as you can see there hasn't been any further action in the past 2 years.
I've posted a file that runs your code as you expect. It uses a custom Action class (like your test case). It subclasses ._SubParsersAction, and replaces the 9351 namespace use with the original one. I use the registry to change the class that parser.add_subparsers() uses. The stock argparse.py file does not need to be changed. ps In your custom Action I access `namespace.foo` with `getattr(namespace, 'foo', None)` which is how argparse accesses the namespace, and does not throw attribute errors.