Skip to content

Struct __post_init__ is not called when converting to Struct with from_attributes=True #673

Closed

Description

@NCRonB

Description

When using msgspec.convert() to convert to a Struct with from_attributes=True, the Struct's __post_init__ is not called. It works as expected with dataclasses.

from dataclasses import dataclass
import msgspec

@dataclass
class DataclassEgg:
	grade: str
	
	def __post_init__(self):
		self.grade = f"dataclass({self.grade})"

class StructEgg(msgspec.Struct):
	grade: str

	def __post_init__(self):
		self.grade = f"Struct({self.grade})"
>>> egg = {"grade": "A"}

>>> struct_egg = msgspec.convert(egg, StructEgg)
>>> struct_egg
StructEgg(grade='Struct(A)')

>>> dataclass_egg = msgspec.convert(egg, DataclassEgg)
>>> dataclass_egg
DataclassEgg(grade='dataclass(A)')

>>> msgspec.convert(struct_egg, DataclassEgg, from_attributes=True)  # DataclassEgg post init is called
DataclassEgg(grade='dataclass(Struct(A))')

>>> msgspec.convert(dataclass_egg, StructEgg, from_attributes=True)  # StructEgg post init is not called
StructEgg(grade='dataclass(A)')

The last one should be:

StructEgg(grade='Struct(dataclass(A))')

Activity

  1. jankotuc-brightpick commented on Jun 13, 2024

    @jankotuc-brightpick

    @NCRonB I thought the same, but I found out the __post_init__() is indeed being called. However, if there are any new fields defined in it (as in your example), these are silently ignored. To fix it, you have to create your StructEgg with the configuration option dict=True.

    If the __post_init__() only contains validations or similar, there's probably no need for the dict=True option.

  2. NCRonB commented on Jun 14, 2024

    @NCRonB
    Author

    @jankotuc-photoneo I'm not defining any new fields — only setting the one field grade to a different value. If you change the __post_init__() to simply print() something, you'll see that it doesn't print.

    I tried what you suggested, and it still doesn't work. If you have an example where it does, please share.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions