Open jcrist opened 11 months ago
Upon further investigation, I'm now leaning more towards 3.
__dict__
per instance, reducing memory usage somewhat and slightly accelerating attribute accessRLock
per cached property, which can provide unnecessary lock contention in threaded applications.The main downsides are:
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, thecached_property
implementation itself won't ever actually run, it's just a decorator flag to tell theStruct
implementation to treat it as a cached property using our own implementation. Sinceattrs
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.