Repository: s-knibbs/dataclasses-jsonschema (python)

Issue:
TypeError thrown from valid Union type
We've been using dataclasses-jsonschema for awhile.  After updating from 2.15.1 to 2.15.2. the following errors started to occur:

```
  File "/Users/XXX/.virtualenvs/customer-implementations/lib/python3.7/site-packages/dataclasses_jsonschema/__init__.py", line 420, in to_dict
    value = self._encode_field(f.field.type, value, omit_none)
  File "/Users/XXX/.virtualenvs/customer-implementations/lib/python3.7/site-packages/dataclasses_jsonschema/__init__.py", line 360, in _encode_field
    return encoder(field_type, value, omit_none)
  File "/Users/XXX/.virtualenvs/customer-implementations/lib/python3.7/site-packages/dataclasses_jsonschema/__init__.py", line 304, in encoder
    def encoder(ft, val, o): return cls._encode_field(unwrap_optional(ft), val, o)
  File "/Users/XXX/.virtualenvs/customer-implementations/lib/python3.7/site-packages/dataclasses_jsonschema/__init__.py", line 323, in _encode_field
    for variant in field_args:
  File "/Users/XXX/.virtualenvs/customer-implementations/lib/python3.7/site-packages/dataclasses_jsonschema/__init__.py", line 322, in <lambda>
    field_args = filter(lambda x: not issubclass(x, primitives), field_type.__args__)
TypeError: issubclass() arg 1 must be a class
```

reverting back to 2.15.1 resolved the error.

Confirmed that the order of variables on line 322 is wrong. 

Pull request:
Use `issubclass_safe` in type union handling
Fixes #190

Patch:
diff --git a/dataclasses_jsonschema/__init__.py b/dataclasses_jsonschema/__init__.py
index ea2a2e7..929987f 100644
--- a/dataclasses_jsonschema/__init__.py
+++ b/dataclasses_jsonschema/__init__.py
@@ -75,7 +75,7 @@ def is_enum(field_type: Any):
     return issubclass_safe(field_type, Enum)
 
 
-def issubclass_safe(klass: Any, base: Type):
+def issubclass_safe(klass: Any, base: Union[Type, Tuple[Type, ...]]):
     try:
         return issubclass(klass, base)
     except TypeError:
@@ -319,7 +319,7 @@ class JsonSchemaMixin:
                 encoded = None
                 # Remove primitive types from unions, these are handled later
                 primitives = (int, str, float, bool, type(None))
-                field_args = filter(lambda x: not issubclass(x, primitives), field_type.__args__)
+                field_args = filter(lambda x: not issubclass_safe(x, primitives), field_type.__args__)
                 for variant in field_args:
                     try:
                         encoded = cls._encode_field(variant, value, omit_none)
@@ -463,7 +463,7 @@ class JsonSchemaMixin:
                 decoded = None
                 # Remove primitive types from unions, these are handled later
                 primitives = (int, str, float, bool, type(None))
-                field_args = filter(lambda x: not issubclass(x, primitives), field_type.__args__)
+                field_args = filter(lambda x: not issubclass_safe(x, primitives), field_type.__args__)
                 for variant in field_args:
                     try:
                         decoded = cls._decode_field(field, variant, value)


Test patch:
diff --git a/tests/test_core.py b/tests/test_core.py
index 07aab5a..38ef334 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -1063,3 +1063,12 @@ def test_tuple_item_schema():
 
     expected_tuple_schema = {"type": "array", "minItems": 2, "maxItems": 2, "items": {"type": "number"}}
     assert MapNote.json_schema()['properties']['point'] == expected_tuple_schema
+
+
+def test_union_issue_190():
+    @dataclass
+    class Config(JsonSchemaMixin):
+        option: Union[str, Dict[str, str]]
+
+    conf = Config.from_dict({"option": "test"})
+    assert conf.to_dict() == {"option": "test"}