diff --git a/gooey/python_bindings/argparse_to_json.py b/gooey/python_bindings/argparse_to_json.py index 10d381b..77ecbce 100644 --- a/gooey/python_bindings/argparse_to_json.py +++ b/gooey/python_bindings/argparse_to_json.py @@ -14,11 +14,20 @@ from argparse import ( _SubParsersAction) from collections import OrderedDict from functools import partial +from pathlib import Path +import pathlib from uuid import uuid4 from gooey.python_bindings.gooey_parser import GooeyParser from gooey.util.functional import merge, getin, identity, assoc +pathlib_constructors = { + pathlib.Path, + pathlib.PurePath, + pathlib.PurePosixPath, + pathlib.PureWindowsPath +} + VALID_WIDGETS = ( 'FileChooser', @@ -255,12 +264,12 @@ def categorize(actions, widget_dict, options): if is_mutex(action): yield build_radio_group(action, widget_dict, options) - elif is_standard(action): - yield action_to_json(action, _get_widget(action, 'TextField'), options) - elif is_file(action): yield action_to_json(action, _get_widget(action, 'FileSaver'), options) + elif is_standard(action): + yield action_to_json(action, _get_widget(action, 'TextField'), options) + elif is_choice(action): yield action_to_json(action, _get_widget(action, 'Dropdown'), options) @@ -322,10 +331,6 @@ def is_choice(action): ''' action with choices supplied ''' return action.choices -def is_file(action): - ''' action with FileType ''' - return isinstance(action.type, argparse.FileType) - def is_standard(action): """ actions which are general "store" instructions. e.g. anything which has an argument style like: @@ -341,6 +346,11 @@ def is_standard(action): and not isinstance(action, _HelpAction) and type(action) not in boolean_actions) +def is_file(action): + ''' action with FileType ''' + return isinstance(action.type, argparse.FileType) \ + or action.type in pathlib_constructors + def is_flag(action): """ _actions which are either storeconst, store_bool, etc.. """ diff --git a/gooey/tests/test_argparse_to_json.py b/gooey/tests/test_argparse_to_json.py index e64dac6..8e4fc48 100644 --- a/gooey/tests/test_argparse_to_json.py +++ b/gooey/tests/test_argparse_to_json.py @@ -1,6 +1,8 @@ import sys import unittest -from argparse import ArgumentParser +from argparse import ArgumentParser, FileType + +import pathlib from gooey import GooeyParser from gooey.python_bindings import argparse_to_json @@ -138,3 +140,23 @@ class TestArgparse(unittest.TestCase): self.assertEqual(result, None) + def test_file_and_path_types_are_helpfully_mapped(self): + """ + Arguments with type=Filetype or type={various Path classes} + should be helpfully turned into FileChoosers. + """ + types = {FileType('r')} | argparse_to_json.pathlib_constructors + for filetype in types: + with self.subTest(filetype): + parser = ArgumentParser() + parser.add_argument('foo', type=filetype) + action = parser._actions[-1] + self.assertTrue(argparse_to_json.is_file(action)) + + randomTypes = {str, object, int} + for filetype in randomTypes: + with self.subTest(filetype): + parser = ArgumentParser() + parser.add_argument('foo', type=filetype) + action = parser._actions[-1] + self.assertFalse(argparse_to_json.is_file(action)) \ No newline at end of file