mirror of https://github.com/chriskiehl/Gooey.git
committed by
Chris
4 changed files with 146 additions and 0 deletions
Unified View
Diff Options
-
1README.md
-
79gooey/python_bindings/cmd_args.py
-
5gooey/python_bindings/gooey_decorator.py
-
61gooey/tests/test_cmd_args.py
@ -0,0 +1,79 @@ |
|||||
|
''' |
||||
|
Created on Jan 15 2019 |
||||
|
|
||||
|
@author: Jonathan Schultz |
||||
|
|
||||
|
This file contains code that allows the default argument values to be specified |
||||
|
on the command line. |
||||
|
''' |
||||
|
|
||||
|
from argparse import _SubParsersAction |
||||
|
|
||||
|
def parse_cmd_args(self, args=None): |
||||
|
|
||||
|
def prepare_to_read_cmd_args(item): |
||||
|
''' |
||||
|
Before reading the command-line arguments, we need to fudge a few things: |
||||
|
1. If there are subparsers, we need a dest in order to know in which |
||||
|
subparser the command-line values should be stored. |
||||
|
2. Any required argument or mutex group needs to be made not required, |
||||
|
otherwise it will be compulsory to enter those values on the command |
||||
|
line. |
||||
|
We save the everything as it was before the fudge, so we can restore later. |
||||
|
''' |
||||
|
for action in item._actions: |
||||
|
if isinstance(action, _SubParsersAction): |
||||
|
action.save_dest = action.dest |
||||
|
if not action.dest: |
||||
|
action.dest = '_subparser' |
||||
|
else: |
||||
|
action.save_required = action.required |
||||
|
action.required = False |
||||
|
action.save_nargs = action.nargs |
||||
|
if action.nargs == '+': |
||||
|
action.nargs = '*' |
||||
|
elif action.nargs is None: |
||||
|
action.nargs = '?' |
||||
|
|
||||
|
for mutex_group in item._mutually_exclusive_groups: |
||||
|
mutex_group.save_required = mutex_group.required |
||||
|
mutex_group.required = False |
||||
|
|
||||
|
def overwrite_default_values(item, cmd_args): |
||||
|
''' |
||||
|
Subsistute arguments provided on the command line in the place of the |
||||
|
default values provided to argparse. |
||||
|
''' |
||||
|
for action in item._actions: |
||||
|
if isinstance(action, _SubParsersAction): |
||||
|
subparser_arg = getattr(cmd_args, action.dest, None) |
||||
|
if subparser_arg: |
||||
|
overwrite_default_values(action.choices[subparser_arg], cmd_args) |
||||
|
else: |
||||
|
dest = getattr(action, 'dest', None) |
||||
|
if dest: |
||||
|
cmd_arg = getattr(cmd_args, dest, None) |
||||
|
if cmd_arg: |
||||
|
action.default = cmd_arg |
||||
|
|
||||
|
def restore_original_configuration(item): |
||||
|
''' |
||||
|
Restore the old values as they were to start with. |
||||
|
''' |
||||
|
for action in item._actions: |
||||
|
if isinstance(action, _SubParsersAction): |
||||
|
action.dest = action.save_dest |
||||
|
del action.save_dest |
||||
|
else: |
||||
|
action.required = action.save_required |
||||
|
del action.save_required |
||||
|
action.nargs = action.save_nargs |
||||
|
del action.save_nargs |
||||
|
|
||||
|
for mutex_group in item._mutually_exclusive_groups: |
||||
|
mutex_group.required = mutex_group.save_required |
||||
|
del mutex_group.save_required |
||||
|
|
||||
|
prepare_to_read_cmd_args(self) |
||||
|
overwrite_default_values(self, self.original_parse_args(args)) |
||||
|
restore_original_configuration(self) |
@ -0,0 +1,61 @@ |
|||||
|
import unittest |
||||
|
|
||||
|
from gooey import GooeyParser |
||||
|
from gooey.python_bindings import cmd_args |
||||
|
from argparse import ArgumentParser |
||||
|
|
||||
|
class TextCommandLine(unittest.TestCase): |
||||
|
|
||||
|
def test_default_overwritten(self): |
||||
|
parser = GooeyParser() |
||||
|
ArgumentParser.original_parse_args = ArgumentParser.parse_args |
||||
|
|
||||
|
parser.add_argument('arg', type=int, default=0) |
||||
|
|
||||
|
# Supply 1 as command line argument, check that it overwrites argparse default |
||||
|
cmd_args.parse_cmd_args(parser, ['1']) |
||||
|
argdefault = next(action for action in parser._actions if action.dest == 'arg').default |
||||
|
self.assertEqual(argdefault, 1) |
||||
|
|
||||
|
def test_required_not_enforced(self): |
||||
|
parser = GooeyParser() |
||||
|
ArgumentParser.original_parse_args = ArgumentParser.parse_args |
||||
|
|
||||
|
parser.add_argument('--arg', type=int, required=True) |
||||
|
parser.add_argument('--argn', type=int, nargs='+') |
||||
|
parser.add_argument('argp', type=int) |
||||
|
mutex=parser.add_mutually_exclusive_group(required=True) |
||||
|
mutex.add_argument('--one', action='store_true') |
||||
|
mutex.add_argument('--two', action='store_true') |
||||
|
|
||||
|
# No error when we don't provide required arguments |
||||
|
cmd_args.parse_cmd_args(parser) |
||||
|
|
||||
|
# Test that required/argn have been restored in parser |
||||
|
argrequired = next(action for action in parser._actions if action.dest == 'arg').required |
||||
|
self.assertEqual(argrequired, True) |
||||
|
argnnargs = next(action for action in parser._actions if action.dest == 'argn').nargs |
||||
|
self.assertEqual(argnnargs, '+') |
||||
|
argpnargs = next(action for action in parser._actions if action.dest == 'argp').nargs |
||||
|
self.assertEqual(argpnargs, None) |
||||
|
mutexrequired = next(mutex for mutex in parser._mutually_exclusive_groups).required |
||||
|
self.assertEqual(mutexrequired, True) |
||||
|
|
||||
|
def test_cmd_args_subparser(self): |
||||
|
parser = GooeyParser() |
||||
|
subparsers = parser.add_subparsers(dest='subparser') |
||||
|
subparserA = subparsers.add_parser('A') |
||||
|
subparserB = subparsers.add_parser('B') |
||||
|
subparserA.add_argument('argA', type=int, default=0) |
||||
|
subparserB.add_argument('argB', type=int, default=0) |
||||
|
|
||||
|
ArgumentParser.original_parse_args = ArgumentParser.parse_args |
||||
|
|
||||
|
cmd_args.parse_cmd_args(parser, ['A', '1']) |
||||
|
|
||||
|
# Check that argA is overwritten but not argB |
||||
|
subparseraction = next(action for action in parser._actions if action.dest == 'subparser') |
||||
|
argAdefault = next(action for action in subparseraction.choices['A']._actions if action.dest == 'argA').default |
||||
|
self.assertEqual(argAdefault, 1) |
||||
|
argBdefault = next(action for action in subparseraction.choices['B']._actions if action.dest == 'argB').default |
||||
|
self.assertEqual(argBdefault, 0) |
Write
Preview
Loading…
Cancel
Save