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" Converts argparse parser actions into json "Build Specs"
""" """
import argparse import argparse
import json
import os import os
import sys import sys
from argparse import ( from argparse import (
@ -457,15 +458,20 @@ def clean_list_defaults(default_values):
def clean_default(default): def clean_default(default):
'''
"""
Attemps to safely coalesce the default value down to Attemps to safely coalesce the default value down to
a valid JSON type. 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): def safe_string(value):

33
gooey/tests/test_argparse_to_json.py

@ -1,5 +1,7 @@
import sys
import unittest import unittest
from argparse import ArgumentParser from argparse import ArgumentParser
from gooey import GooeyParser from gooey import GooeyParser
from gooey.python_bindings import argparse_to_json from gooey.python_bindings import argparse_to_json
from gooey.util.functional import getin from gooey.util.functional import getin
@ -84,12 +86,29 @@ class TestArgparse(unittest.TestCase):
result = argparse_to_json.action_to_json(choice_action, 'Listbox', {}) result = argparse_to_json.action_to_json(choice_action, 'Listbox', {})
self.assertEqual(getin(result, ['data', 'default']), ['sup']) 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