6
6
from codegen .utils import CAVEAT , PlotlyNode , TraceNode , write_source_py
7
7
8
8
9
- def build_validator_py (node : PlotlyNode ):
10
- """
11
- Build validator class source code string for a datatype PlotlyNode
12
-
13
- Parameters
14
- ----------
15
- node : PlotlyNode
16
- The datatype node (node.is_datatype must evaluate to true) for which
17
- to build the validator class
18
- Returns
19
- -------
20
- str
21
- String containing source code for the validator class definition
22
- """
23
-
24
- # Validate inputs
25
- # ---------------
26
- assert node .is_datatype
27
-
28
- # Initialize
29
- import_alias = "_bv"
30
- buffer = StringIO ()
31
- buffer .write (CAVEAT )
32
-
33
- # Imports
34
- # -------
35
- # ### Import package of the validator's superclass ###
36
- import_str = "." .join (node .name_base_validator .split ("." )[:- 1 ])
37
- buffer .write (f"import { import_str } as { import_alias } \n " )
38
-
39
- # Build Validator
40
- # ---------------
41
- # ### Get dict of validator's constructor params ###
42
- params = node .get_validator_params ()
43
-
44
- # ### Write class definition ###
45
- class_name = node .name_validator_class
46
- superclass_name = node .name_base_validator .split ("." )[- 1 ]
47
- buffer .write (
48
- f"""
49
-
50
- class { class_name } ({ import_alias } .{ superclass_name } ):
51
- def __init__(self, plotly_name={ params ['plotly_name' ]} ,
52
- parent_name={ params ['parent_name' ]} ,
53
- **kwargs):"""
54
- )
55
-
56
- # ### Write constructor ###
57
- buffer .write (
58
- f"""
59
- super().__init__(plotly_name, parent_name"""
60
- )
61
-
62
- # Write out remaining constructor parameters
63
- for attr_name , attr_val in params .items ():
64
- if attr_name in ["plotly_name" , "parent_name" ]:
65
- # plotly_name and parent_name are already handled
66
- continue
67
-
68
- buffer .write (
69
- f""",
70
- { attr_name } =kwargs.pop('{ attr_name } ', { attr_val } )"""
71
- )
72
-
73
- buffer .write (
74
- f""",
75
- **kwargs"""
76
- )
77
-
78
- buffer .write (")" )
79
-
80
- # ### Return buffer's string ###
81
- return buffer .getvalue ()
82
-
83
-
84
- def write_validator_py (outdir , node : PlotlyNode ):
9
+ def get_validator_params (node : PlotlyNode , store : dict ):
85
10
"""
86
- Build validator source code and write to a file
11
+ Get params for the validator instance for the supplied node
12
+ and add them to the store.
87
13
88
14
Parameters
89
15
----------
90
- outdir : str
91
- Root outdir in which the validators package should reside
92
16
node : PlotlyNode
93
17
The datatype node (node.is_datatype must evaluate to true) for which
94
18
to build a validator class
19
+ store : dict
20
+ Dictionary to store the JSON data for the validator
95
21
Returns
96
22
-------
97
23
None
98
24
"""
99
- if node .is_mapped :
100
- # No validator written for mapped nodes
101
- # e.g. no validator for layout.title_font since ths is mapped to
102
- # layout.title.font
103
- return
25
+ assert isinstance (store , dict )
26
+ assert node .is_datatype
104
27
105
- # Generate source code
106
- # --------------------
107
- validator_source = build_validator_py ( node )
28
+ raw_params = node . get_validator_params ()
29
+ params = dict ([( k , eval ( v )) for k , v in raw_params . items ()])
30
+ superclass_name = node . name_base_validator . split ( "." )[ - 1 ]
108
31
109
- # Write file
110
- # ----------
111
- # filepath = opath.join(outdir, "validators", *node.parent_path_parts, "__init__.py")
112
- filepath = opath .join (
113
- outdir , "validators" , * node .parent_path_parts , "_" + node .name_property + ".py"
114
- )
32
+ key = "." .join (node .parent_path_parts + (node .name_property ,))
33
+ store [key ] = {"params" : params , "superclass" : superclass_name }
115
34
116
- write_source_py (validator_source , filepath , leading_newlines = 2 )
117
35
118
- def get_validator_params ( node : PlotlyNode , store : dict ):
36
+ def get_data_validator_params ( base_trace_node : TraceNode , store : dict ):
119
37
"""
120
- Write out the JSON schema for the validator
38
+ Add a dict of constructor params for the DataValidator to the store.
121
39
122
40
Parameters
123
41
----------
124
- node : PlotlyNode
125
- The datatype node (node.is_datatype must evaluate to true) for which
126
- to build a validator class
42
+ base_trace_node : TraceNode
43
+ PlotlyNode that is the parent of all of the individual trace nodes
127
44
store : dict
128
45
Dictionary to store the JSON data for the validator
129
46
Returns
130
47
-------
131
- None
132
- """
133
- assert isinstance (store , dict )
134
- assert node .is_datatype
48
+ None"""
49
+ assert isinstance (store , dict )
135
50
136
- raw_params = node .get_validator_params ()
137
- params = dict ([(k , eval (v )) for k , v in raw_params .items ()])
138
- superclass_name = node .name_base_validator .split ("." )[- 1 ]
51
+ params = build_data_validator_params (base_trace_node )
52
+ store ["data" ] = {
53
+ "params" : params ,
54
+ "superclass" : "BaseDataValidator" ,
55
+ }
139
56
140
- key = "." .join (node .parent_path_parts + (node .name_property ,))
141
- store [key ] = {"params" : params , "superclass" : superclass_name }
142
57
143
58
def write_validator_json (outdir , params : dict ):
144
59
"""
145
- Write out the JSON schema for the validator
60
+ Write out a JSON serialization of the validator arguments
61
+ for all validators (keyed by f"{parent_name}.{plotly_name})
62
+
63
+ Each validator has a "params": {kwargs} entry and
64
+ a "superclass": str to indicate the class to be instantiated
146
65
147
66
Parameters
148
67
----------
@@ -184,78 +103,15 @@ def build_data_validator_params(base_trace_node: TraceNode):
184
103
# Get list of trace nodes
185
104
# -----------------------
186
105
tracetype_nodes = base_trace_node .child_compound_datatypes
106
+ class_strs_map = dict ([
107
+ (node .name_property , node .name_datatype_class ) for node in tracetype_nodes ])
187
108
188
- # Build class_map_repr string
189
- # ---------------------------
190
- # This is the repr-form of a dict from trace propert name string
191
- # to the name of the trace datatype class in the graph_objs package.
192
- buffer = StringIO ()
193
- buffer .write ("{\n " )
194
- for i , tracetype_node in enumerate (tracetype_nodes ):
195
- sfx = "," if i < len (tracetype_nodes ) else ""
196
- trace_name = tracetype_node .name_property
197
- trace_datatype_class = tracetype_node .name_datatype_class
198
- buffer .write (
199
- f"""
200
- '{ trace_name } ': '{ trace_datatype_class } '{ sfx } """
201
- )
202
-
203
- buffer .write (
204
- """
205
- }"""
206
- )
207
-
208
- class_map_repr = buffer .getvalue ()
209
-
210
- # Build params dict
211
- # -----------------
212
- params = {
213
- "class_strs_map" : class_map_repr ,
214
- "plotly_name" : repr ("data" ),
215
- "parent_name" : repr ("" ),
109
+ return {
110
+ "class_strs_map" : class_strs_map ,
111
+ "plotly_name" : "data" ,
112
+ "parent_name" : "" ,
216
113
}
217
114
218
- return params
219
-
220
-
221
- def build_data_validator_py (base_trace_node : TraceNode ):
222
- """
223
- Build source code for the DataValidator
224
- (this is the validator that inputs a list of traces)
225
-
226
- Parameters
227
- ----------
228
- base_trace_node : PlotlyNode
229
- PlotlyNode that is the parent of all of the individual trace nodes
230
- Returns
231
- -------
232
- str
233
- Source code string for DataValidator class
234
- """
235
-
236
- # Get constructor params
237
- # ----------------------
238
- params = build_data_validator_params (base_trace_node )
239
-
240
- # Build source code
241
- # -----------------
242
- buffer = StringIO ()
243
-
244
- buffer .write (
245
- f"""
246
- import _plotly_utils.basevalidators
247
-
248
- class DataValidator(_plotly_utils.basevalidators.BaseDataValidator):
249
-
250
- def __init__(self, plotly_name={ params ['plotly_name' ]} ,
251
- parent_name={ params ['parent_name' ]} ,
252
- **kwargs):
253
-
254
- super().__init__({ params ['class_strs_map' ]} , plotly_name, parent_name, **kwargs)"""
255
- )
256
-
257
- return buffer .getvalue ()
258
-
259
115
260
116
def get_data_validator_instance (base_trace_node : TraceNode ):
261
117
"""
@@ -276,42 +132,7 @@ def get_data_validator_instance(base_trace_node: TraceNode):
276
132
# We need to eval the values to convert out of the repr-form of the
277
133
# params. e.g. '3' -> 3
278
134
params = build_data_validator_params (base_trace_node )
279
- eval_params = {k : eval (repr_val ) for k , repr_val in params .items ()}
280
135
281
136
# Build and return BaseDataValidator instance
282
137
# -------------------------------------------
283
- return _plotly_utils .basevalidators .BaseDataValidator (** eval_params )
284
-
285
-
286
- def write_data_validator_py (outdir , base_trace_node : TraceNode ):
287
- """
288
- Construct and write out the DataValidator
289
- (this is the validator that inputs a list of traces)
290
-
291
- Parameters
292
- ----------
293
- outdir : str
294
- Root outdir in which the top-level validators package should reside
295
- base_trace_node : PlotlyNode
296
- PlotlyNode that is the parent of all of the individual trace nodes
297
- Returns
298
- -------
299
- None
300
- """
301
- # Validate inputs
302
- # ---------------
303
- if base_trace_node .node_path :
304
- raise ValueError (
305
- "Expected root trace node.\n "
306
- 'Received node with path "%s"' % base_trace_node .path_str
307
- )
308
-
309
- # Build Source
310
- # ------------
311
- source = build_data_validator_py (base_trace_node )
312
-
313
- # Write file
314
- # ----------
315
- # filepath = opath.join(outdir, "validators", "__init__.py")
316
- filepath = opath .join (outdir , "validators" , "_data.py" )
317
- write_source_py (source , filepath , leading_newlines = 2 )
138
+ return _plotly_utils .basevalidators .BaseDataValidator (** params )
0 commit comments