Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
NCRonB opened this issue Apr 29, 2024 · 2 comments

Comments

@NCRonB
Copy link

NCRonB commented Apr 29, 2024

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))')
@jankotuc-photoneo
Copy link

@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.

@NCRonB
Copy link
Author

NCRonB commented Jun 14, 2024

@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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants