diff --git a/dataclasses_json/core.py b/dataclasses_json/core.py index c7b696e7..91a0b5ff 100644 --- a/dataclasses_json/core.py +++ b/dataclasses_json/core.py @@ -135,7 +135,9 @@ def _decode_letter_case_overrides(field_names, overrides): if field_override is not None: letter_case = field_override.letter_case if letter_case is not None: - names[letter_case(field_name)] = field_name + names[field_name] = letter_case(field_name) + if field_name not in names: + names[field_name] = field_name return names @@ -146,7 +148,8 @@ def _decode_dataclass(cls, kvs, infer_missing): kvs = {} if kvs is None and infer_missing else kvs field_names = [field.name for field in fields(cls)] decode_names = _decode_letter_case_overrides(field_names, overrides) - kvs = {decode_names.get(k, k): v for k, v in kvs.items()} + undefined_fields = {k: v for k, v in kvs.items() if k not in decode_names.values()} + kvs = {**{k: kvs[v] for k, v in decode_names.items() if v in kvs}, **undefined_fields} missing_fields = {field for field in fields(cls) if field.name not in kvs} for field in missing_fields: diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 980e7903..b0428bf6 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -1,11 +1,12 @@ import datetime +import json from dataclasses import dataclass, field -from typing import Optional +from typing import Optional, Dict import pytest from marshmallow import fields, ValidationError -from dataclasses_json import DataClassJsonMixin +from dataclasses_json import DataClassJsonMixin, dataclass_json, config @dataclass @@ -24,7 +25,8 @@ class StringDate(DataClassJsonMixin): 'decoder': str, 'mm_field': fields.String(required=False)} }) - + + @dataclass class OptionalStringDate(DataClassJsonMixin): string_date: Optional[datetime.datetime] = field( @@ -36,6 +38,14 @@ class OptionalStringDate(DataClassJsonMixin): }) +@dataclass_json +@dataclass +class MyDataClass: + first: str = field(metadata=config(field_name="myJsonField", decoder=lambda x: x["first"])) + second: str = field(metadata=config(field_name="myJsonField", decoder=lambda x: x["second"])) + other_field: str = field(metadata=config(field_name="otherField")) + + car_schema = Car.schema() string_date_schema = StringDate.schema() opt_string_date_schema = OptionalStringDate.schema() @@ -60,3 +70,16 @@ def test_optional_field_only_decoded_when_present(self): another_obj = opt_string_date_schema.load({'string_date': 'today'}) assert isinstance(another_obj, OptionalStringDate) assert another_obj.string_date == 'today' + + def test_multiple_fields_same_name(self): + contents = json.dumps({ + "myJsonField": { + "first": "val1", + "second": "val2" + }, + "otherField": "valotherfield" + }) + obj = MyDataClass.from_json(contents) + assert obj.first == "val1" + assert obj.second == "val2" + assert obj.other_field == "valotherfield"