1
1
import dataclasses as dc
2
2
import typing as ta
3
3
4
+ from omlish import cached
4
5
from omlish import check
6
+ from omlish import collections as col
5
7
from omlish import lang
6
8
7
9
@@ -48,9 +50,58 @@ def shape_metadata(
48
50
return md
49
51
50
52
53
+ class ShapeInfo :
54
+ def __init__ (
55
+ self ,
56
+ cls : type ['Shape' ],
57
+ metadata : ta .Mapping [ta .Any , ta .Any ],
58
+ ) -> None :
59
+ super ().__init__ ()
60
+
61
+ self ._cls = check .issubclass (cls , Shape )
62
+ self ._metadata = metadata
63
+
64
+ @property
65
+ def cls (self ) -> type ['Shape' ]:
66
+ return self ._cls
67
+
68
+ @property
69
+ def metadata (self ) -> ta .Mapping [ta .Any , ta .Any ]:
70
+ return self ._metadata
71
+
72
+ #
73
+
74
+ @cached .function
75
+ def fields (self ) -> ta .Sequence [dc .Field ]:
76
+ check .in_ ('__dataclass_fields__' , self ._cls .__dict__ )
77
+ fls = dc .fields (self ._cls )
78
+ return fls # noqa
79
+
80
+ @cached .function
81
+ def fields_by_name (self ) -> ta .Mapping [str , dc .Field ]:
82
+ return col .make_map_by (lambda fl : fl .name , self .fields (), strict = True )
83
+
84
+ @cached .function
85
+ def fields_by_member_name (self ) -> ta .Mapping [str , dc .Field ]:
86
+ return col .make_map (
87
+ [(n , f ) for f in self .fields () if (n := f .metadata .get (MEMBER_NAME )) is not None ],
88
+ strict = True ,
89
+ )
90
+
91
+ @cached .function
92
+ def fields_by_serialization_name (self ) -> ta .Mapping [str , dc .Field ]:
93
+ l = []
94
+ for f in self .fields ():
95
+ if sn := f .metadata .get (SERIALIZATION_NAME ):
96
+ l .append ((sn , f ))
97
+ elif mn := f .metadata .get (MEMBER_NAME ):
98
+ l .append ((mn , f ))
99
+ return col .make_map (l , strict = True )
100
+
101
+
51
102
@dc .dataclass (frozen = True )
52
103
class Shape :
53
- __shape_metadata__ : ta . ClassVar [ ta . Mapping [ ta . Any , ta . Any ]]
104
+ __shape__ : ShapeInfo
54
105
55
106
def __init_subclass__ (
56
107
cls ,
@@ -60,9 +111,14 @@ def __init_subclass__(
60
111
) -> None :
61
112
super ().__init_subclass__ (** kwargs )
62
113
63
- check .state (not hasattr (cls , '__shape_metadata__' ))
114
+ check .state (not hasattr (cls , '__shape__' ))
115
+
116
+ info = ShapeInfo (
117
+ cls ,
118
+ shape_metadata (** kwargs ),
119
+ )
64
120
65
- cls .__shape_metadata__ = shape_metadata ( ** kwargs )
121
+ cls .__shape__ = info
66
122
67
123
68
124
##
0 commit comments