Skip to content

Commit

Permalink
Fixing bug in decoder eval for optional fields (#354)
Browse files Browse the repository at this point in the history
  • Loading branch information
rpmcginty committed Jun 13, 2023
1 parent 5ef3fec commit b2dd567
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 11 deletions.
28 changes: 17 additions & 11 deletions dataclasses_json/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,17 +167,23 @@ def _decode_dataclass(cls, kvs, infer_missing):

field_value = kvs[field.name]
field_type = types[field.name]
if field_value is None and not _is_optional(field_type):
warning = (f"value of non-optional type {field.name} detected "
f"when decoding {cls.__name__}")
if infer_missing:
warnings.warn(
f"Missing {warning} and was defaulted to None by "
f"infer_missing=True. "
f"Set infer_missing=False (the default) to prevent this "
f"behavior.", RuntimeWarning)
else:
warnings.warn(f"`NoneType` object {warning}.", RuntimeWarning)
if field_value is None:
if not _is_optional(field_type):
warning = (
f"value of non-optional type {field.name} detected "
f"when decoding {cls.__name__}"
)
if infer_missing:
warnings.warn(
f"Missing {warning} and was defaulted to None by "
f"infer_missing=True. "
f"Set infer_missing=False (the default) to prevent "
f"this behavior.", RuntimeWarning
)
else:
warnings.warn(
f"`NoneType` object {warning}.", RuntimeWarning
)
init_kwargs[field.name] = field_value
continue

Expand Down
21 changes: 21 additions & 0 deletions tests/test_metadata.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import datetime
from dataclasses import dataclass, field
from typing import Optional

import pytest
from marshmallow import fields, ValidationError
Expand All @@ -23,10 +24,21 @@ class StringDate(DataClassJsonMixin):
'decoder': str,
'mm_field': fields.String(required=False)}
})

@dataclass
class OptionalStringDate(DataClassJsonMixin):
string_date: Optional[datetime.datetime] = field(
default=None,
metadata={'dataclasses_json': {
'encoder': str,
'decoder': str,
'mm_field': fields.String(required=False)}
})


car_schema = Car.schema()
string_date_schema = StringDate.schema()
opt_string_date_schema = OptionalStringDate.schema()


class TestMetadata:
Expand All @@ -39,3 +51,12 @@ def test_mm_field_takes_precedence_over_types(self):
obj = string_date_schema.load({'string_date': 'yesterday'})
assert isinstance(obj, StringDate)
assert obj.string_date == 'yesterday'

def test_optional_field_only_decoded_when_present(self):
obj = opt_string_date_schema.load({})
assert isinstance(obj, OptionalStringDate)
assert obj.string_date == None

another_obj = opt_string_date_schema.load({'string_date': 'today'})
assert isinstance(another_obj, OptionalStringDate)
assert another_obj.string_date == 'today'

0 comments on commit b2dd567

Please sign in to comment.