diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b283e4cb..9261c172 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,6 @@ name: Tests -on: [pull_request] +on: [pull_request, workflow_dispatch] jobs: diff --git a/serde/de.py b/serde/de.py index d822050f..eae2312e 100644 --- a/serde/de.py +++ b/serde/de.py @@ -1484,6 +1484,12 @@ def render_from_dict( ) serde_scope = getattr(cls, SERDE_SCOPE) all_fields = defields(cls) + force_kw = False + for field in all_fields: + if not renderable(field): + force_kw = True + if force_kw: + field.kw_only = True fields = list(filter(renderable, all_fields)) if serde_scope.transparent: field = dataclasses.replace(fields[0], alias=[], rename="__serde_transparent__", case=None) diff --git a/tests/test_basics.py b/tests/test_basics.py index f0957582..b75eff26 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -625,6 +625,24 @@ class Foo: assert ff.a == 2 +def test_skip() -> None: + # Note that skipped field is not the last one + @serde.serde + class Foo: + comments: list[str] = serde.field(default_factory=list, skip=True) + name: str = "" + + f = Foo(["foo"], "bar") + + # Serialization should work + assert serde.to_dict(f) == {"name": "bar"} + + # Deserialization should work, using default for skipped field + restored = serde.from_dict(Foo, {"name": "bar"}) + assert restored.name == "bar" + assert restored.comments == [] + + @pytest.mark.parametrize( "se,de", (format_dict + format_json + format_msgpack + format_yaml + format_toml + format_pickle),