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

Issue:
Improve handling of None in from_object
Currently a `ValueError` is raised in `from_object` if the source object has a `None` value for an enum or nested object field.

Pull request description:
Improve handling of None in `from_object`
Fixes #87

Patch:
diff --git a/dataclasses_jsonschema/__init__.py b/dataclasses_jsonschema/__init__.py
index 46ea060..391302f 100644
--- a/dataclasses_jsonschema/__init__.py
+++ b/dataclasses_jsonschema/__init__.py
@@ -432,16 +432,20 @@ class JsonSchemaMixin:
             if is_optional(ft):
                 ft = unwrap_optional(ft)
             field_type_name = cls._get_field_type_name(ft)
-            if cls._is_json_schema_subclass(ft):
-                values[field.name] = ft.from_object(getattr(obj, field.name), exclude=sub_exclude)
+
+            from_value = getattr(obj, field.name)
+            if from_value is None:
+                values[field.name] = from_value
+            elif cls._is_json_schema_subclass(ft):
+                values[field.name] = ft.from_object(from_value, exclude=sub_exclude)
             elif is_enum(ft):
-                values[field.name] = ft(getattr(obj, field.name))
+                values[field.name] = ft(from_value)
             elif field_type_name == "List" and cls._is_json_schema_subclass(ft.__args__[0]):
                 values[field.name] = [
-                    ft.__args__[0].from_object(v, exclude=sub_exclude) for v in getattr(obj, field.name)
+                    ft.__args__[0].from_object(v, exclude=sub_exclude) for v in from_value
                 ]
             else:
-                values[field.name] = getattr(obj, field.name)
+                values[field.name] = from_value
 
         instance = cls(**init_values)  # type: ignore
         for field_name, value in non_init_values.items():


Test patch:
diff --git a/tests/test_core.py b/tests/test_core.py
index bad6b27..a6aeb3d 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -479,7 +479,7 @@ def test_from_object():
     class Book(JsonSchemaMixin):
         name: str
         publisher: str
-        genre: Genre
+        genre: Optional[Genre]
         first_print: Optional[datetime.datetime] = None
 
     @dataclass
@@ -494,6 +494,12 @@ def test_from_object():
     expected_author = Author("Joe Bloggs", books=[Book("Hello World!", "ACME Corp", Genre.BIOGRAPHY)])
     assert Author.from_object(sample_author, exclude=('age', ('books', ('first_print',)))) == expected_author
 
+    sample_author_2 = AuthorModel(
+        "Joe Bloggs", 32, [BookModel("Hello World!", datetime.datetime.utcnow(), "ACME Corp", None)]
+    )
+    expected_author_2 = Author("Joe Bloggs", books=[Book("Hello World!", "ACME Corp", None)])
+    assert Author.from_object(sample_author_2, exclude=('age', ('books', ('first_print',)))) == expected_author_2
+
     with pytest.raises(ValueError):
         Author.from_object(sample_author, exclude=('age', ('books', ('publisher',))))