Browse Source

closes #377 - drop all non-serializable objects from default args

pull/473/head
Chris 6 years ago
parent
commit
be1343b6da
2 changed files with 39 additions and 14 deletions
  1. 20
      gooey/python_bindings/argparse_to_json.py
  2. 33
      gooey/tests/test_argparse_to_json.py

20
gooey/python_bindings/argparse_to_json.py

@ -2,6 +2,7 @@
Converts argparse parser actions into json "Build Specs"
"""
import argparse
import json
import os
import sys
from argparse import (
@ -457,15 +458,20 @@ def clean_list_defaults(default_values):
def clean_default(default):
'''
"""
Attemps to safely coalesce the default value down to
a valid JSON type.
See: Issue #147.
function references supplied as arguments to the
`default` parameter in Argparse cause errors in Gooey.
'''
return default.__name__ if callable(default) else default
"""
try:
json.dumps(default)
return default
except TypeError as e:
# see: Issue #377
# if is ins't json serializable (i.e. primitive data) there's nothing
# useful for Gooey to do with it (since Gooey deals in primitive data
# types). So the correct behavior is dropping them. This affects ONLY
# gooey, not the client code.
return None
def safe_string(value):

33
gooey/tests/test_argparse_to_json.py

@ -1,5 +1,7 @@
import sys
import unittest
from argparse import ArgumentParser
from gooey import GooeyParser
from gooey.python_bindings import argparse_to_json
from gooey.util.functional import getin
@ -84,12 +86,29 @@ class TestArgparse(unittest.TestCase):
result = argparse_to_json.action_to_json(choice_action, 'Listbox', {})
self.assertEqual(getin(result, ['data', 'default']), ['sup'])
def test_callables_as_default_args_are_cast_to_their_name(self):
""" Issue 147 """
parser = ArgumentParser()
parser.add_argument('--foo', default=max)
def test_non_data_defaults_are_dropped_entirely(self):
"""
This is a refinement in understanding of Issue #147
Caused by Issue 377 - passing arbitrary objects as defaults
causes failures.
"""
# passing plain data to cleaning function results in plain data
# being returned
data = ['abc',
123,
['a', 'b'],
[1, 2, 3]]
for datum in data:
result = argparse_to_json.clean_default(datum)
self.assertEqual(result, datum)
# passing in complex objects results in None
objects = [sys.stdout, sys.stdin, object(), max, min]
for obj in objects:
result = argparse_to_json.clean_default(obj)
self.assertEqual(result, None)
choice_action = parser._actions[-1]
result = argparse_to_json.action_to_json(choice_action, 'Textfield', {})
self.assertEqual(getin(result, ['data', 'default']), 'max')
Loading…
Cancel
Save