Skip to content

Commit 12bc5dd

Browse files
committed
Do not render field with init=False
``` @DataClass @serde class Init: a: int b: int = field(init=False) def __post_init__(self) -> None: self.b = self.a * 10 ``` Field "b" is not rendreed, otherwise class constructor raises this error ``` Foo.__init__() takes 2 positional arguments but 3 were given ```
1 parent a442e7e commit 12bc5dd

File tree

4 files changed

+21
-4
lines changed

4 files changed

+21
-4
lines changed

serde/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ class Foo:
436436
name: Optional[str]
437437
default: Any = field(default_factory=dataclasses._MISSING_TYPE)
438438
default_factory: Any = field(default_factory=dataclasses._MISSING_TYPE)
439-
init: Any = field(default_factory=dataclasses._MISSING_TYPE)
439+
init: bool = field(default_factory=dataclasses._MISSING_TYPE)
440440
repr: Any = field(default_factory=dataclasses._MISSING_TYPE)
441441
hash: Any = field(default_factory=dataclasses._MISSING_TYPE)
442442
compare: Any = field(default_factory=dataclasses._MISSING_TYPE)

serde/de.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,10 @@ def to_iter_arg(f: DeField, *args, **kwargs) -> DeField:
899899
return f
900900

901901

902+
def renderable(f: DeField) -> bool:
903+
return f.init
904+
905+
902906
def render_from_iter(cls: Type[Any], custom: Optional[DeserializeFunc] = None, type_check: TypeCheck = NoCheck) -> str:
903907
template = """
904908
def {{func}}(cls=cls, maybe_generic=None, data=None, reuse_instances = {{serde_scope.reuse_instances_default}}):
@@ -926,7 +930,8 @@ def {{func}}(cls=cls, maybe_generic=None, data=None, reuse_instances = {{serde_s
926930
env = jinja2.Environment(loader=jinja2.DictLoader({'iter': template}))
927931
env.filters.update({'rvalue': renderer.render})
928932
env.filters.update({'arg': to_iter_arg})
929-
res = env.get_template('iter').render(func=FROM_ITER, serde_scope=getattr(cls, SERDE_SCOPE), fields=defields(cls))
933+
fields = list(filter(renderable, defields(cls)))
934+
res = env.get_template('iter').render(func=FROM_ITER, serde_scope=getattr(cls, SERDE_SCOPE), fields=fields)
930935

931936
if renderer.import_numpy:
932937
res = "import numpy\n" + res
@@ -973,8 +978,9 @@ def {{func}}(cls=cls, maybe_generic=None, data=None,
973978
env = jinja2.Environment(loader=jinja2.DictLoader({'dict': template}))
974979
env.filters.update({'rvalue': renderer.render})
975980
env.filters.update({'arg': functools.partial(to_arg, rename_all=rename_all)})
981+
fields = list(filter(renderable, defields(cls)))
976982
res = env.get_template('dict').render(
977-
func=FROM_DICT, serde_scope=getattr(cls, SERDE_SCOPE), fields=defields(cls), type_check=type_check
983+
func=FROM_DICT, serde_scope=getattr(cls, SERDE_SCOPE), fields=fields, type_check=type_check
978984
)
979985

980986
if renderer.import_numpy:

tests/common.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ def toml_not_supported(se, de, opt) -> bool:
9292
param(data.Pri(10, 'foo', 100.0, True), Optional[data.Pri]),
9393
param(None, Optional[data.Pri], toml_not_supported),
9494
param(data.Recur(data.Recur(None, None, None), None, None), data.Recur, toml_not_supported),
95+
param(data.Init(1), data.Init),
9596
param(10, NewType('Int', int)), # NewType
9697
param({'a': 1}, Any), # Any
9798
param(GenericClass[str, int]('foo', 10), GenericClass[str, int]), # Generic

tests/data.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from dataclasses import dataclass
33
from typing import Dict, List, Optional, Tuple
44

5-
from serde import serde
5+
from serde import field, serde
66

77
from . import imported
88

@@ -257,3 +257,13 @@ class Recur:
257257
NESTED_PRILIST = ([INT], [STR], [FLOAT], [BOOL])
258258

259259
NESTED_PRILIST_TUPLE = ([(10,)], [('foo',)], [(100.0,)], [(True,)])
260+
261+
262+
@dataclass
263+
@serde
264+
class Init:
265+
a: int
266+
b: int = field(init=False)
267+
268+
def __post_init__(self) -> None:
269+
self.b = self.a * 10

0 commit comments

Comments
 (0)