Skip to content

Commit 5d1ccdb

Browse files
bmaranvillegvwilson
authored andcommitted
add DataValidator to autogenerated instances provided by ValidatorCache, and cleanup
1 parent 2507be9 commit 5d1ccdb

File tree

1 file changed

+35
-214
lines changed

1 file changed

+35
-214
lines changed

codegen/validators.py

Lines changed: 35 additions & 214 deletions
Original file line numberDiff line numberDiff line change
@@ -6,143 +6,62 @@
66
from 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

14358
def 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

260116
def 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

Comments
 (0)