66from codegen .utils import CAVEAT , PlotlyNode , TraceNode , write_source_py
77
88
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 ):
8510 """
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.
8713
8814 Parameters
8915 ----------
90- outdir : str
91- Root outdir in which the validators package should reside
9216 node : PlotlyNode
9317 The datatype node (node.is_datatype must evaluate to true) for which
9418 to build a validator class
19+ store : dict
20+ Dictionary to store the JSON data for the validator
9521 Returns
9622 -------
9723 None
9824 """
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
10427
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 ]
10831
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 }
11534
116- write_source_py (validator_source , filepath , leading_newlines = 2 )
11735
118- def get_validator_params ( node : PlotlyNode , store : dict ):
36+ def get_data_validator_params ( base_trace_node : TraceNode , store : dict ):
11937 """
120- Write out the JSON schema for the validator
38+ Add a dict of constructor params for the DataValidator to the store.
12139
12240 Parameters
12341 ----------
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
12744 store : dict
12845 Dictionary to store the JSON data for the validator
12946 Returns
13047 -------
131- None
132- """
133- assert isinstance (store , dict )
134- assert node .is_datatype
48+ None"""
49+ assert isinstance (store , dict )
13550
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+ }
13956
140- key = "." .join (node .parent_path_parts + (node .name_property ,))
141- store [key ] = {"params" : params , "superclass" : superclass_name }
14257
14358def write_validator_json (outdir , params : dict ):
14459 """
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
14665
14766 Parameters
14867 ----------
@@ -184,78 +103,15 @@ def build_data_validator_params(base_trace_node: TraceNode):
184103 # Get list of trace nodes
185104 # -----------------------
186105 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 ])
187108
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" : "" ,
216113 }
217114
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-
259115
260116def get_data_validator_instance (base_trace_node : TraceNode ):
261117 """
@@ -276,42 +132,7 @@ def get_data_validator_instance(base_trace_node: TraceNode):
276132 # We need to eval the values to convert out of the repr-form of the
277133 # params. e.g. '3' -> 3
278134 params = build_data_validator_params (base_trace_node )
279- eval_params = {k : eval (repr_val ) for k , repr_val in params .items ()}
280135
281136 # Build and return BaseDataValidator instance
282137 # -------------------------------------------
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