You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is because the cpython implementation of cached_property requires a __dict__ exist on the instance. The error raised if you fail to set dict=True happens on property access, and since it's from functools not msgspec it doesn't indicate how to resolve the issue:
TypeError: No '__dict__' attribute on 'RightTriangle' instance to cache 'c' property.
As such, users have to read the docs (or ask) to know how to mix msgspec.Struct and functools.cached_property together. It would be nice to improve this situation. A few options:
Automatically set dict=True if the class includes any cached_property attributes. This lets things "just work" for most users.
Warn if a class includes cached_property attributes but doesn't set dict=True. This is like a less automagic form of 1.
Rewrite cached_property attributes on msgspec.Struct types if dict=False to use an alternative slots-based mechanism, similar to what attrs added here.
Of these options I'm leaning towards 1 or maybe 3.
The text was updated successfully, but these errors were encountered:
Upon further investigation, I'm now leaning more towards 3.
Some of the preprocessing we'll need to do to make this work will also be needed to support Question: computed fields #573.
Providing builtin support for this will avoid the need to allocate a __dict__ per instance, reducing memory usage somewhat and slightly accelerating attribute access
Likewise, handling this ourselves lets us backport the 3.12 fix to avoid usage of an RLock per cached property, which can provide unnecessary lock contention in threaded applications.
The main downsides are:
More code on our end
Some magic. When used on a Struct type, the cached_property implementation itself won't ever actually run, it's just a decorator flag to tell the Struct implementation to treat it as a cached property using our own implementation. Since attrs is already doing the same, I feel better following their lead.
Some magic. When used on a Struct type, the cached_property implementation itself won't ever actually run, it's just a decorator flag to tell the Struct implementation to treat it as a cached property using our own implementation. Since attrs is already doing the same, I feel better following their lead.
What about not using functools.cached_property, but instead provide e.g. msgspec.cached_property, which would work the same way you described, but would make it more explicit that this is not the same as the functools one? That would eliminate the magic aspect of it while providing the same functionality.
Description
Since
msgspec.Struct
types are effectively slotted classes, usingfunctools.cached_property
with structs requires the user to also setdict=True
:This is because the cpython implementation of
cached_property
requires a__dict__
exist on the instance. The error raised if you fail to setdict=True
happens on property access, and since it's fromfunctools
notmsgspec
it doesn't indicate how to resolve the issue:As such, users have to read the docs (or ask) to know how to mix
msgspec.Struct
andfunctools.cached_property
together. It would be nice to improve this situation. A few options:dict=True
if the class includes anycached_property
attributes. This lets things "just work" for most users.cached_property
attributes but doesn't setdict=True
. This is like a less automagic form of 1.cached_property
attributes onmsgspec.Struct
types ifdict=False
to use an alternative slots-based mechanism, similar to whatattrs
added here.Of these options I'm leaning towards 1 or maybe 3.
The text was updated successfully, but these errors were encountered: