def perform_codegen(): outdir = 'ipyplotly/' # outdir = 'codegen/output' # Load plotly schema # ------------------ with open('codegen/resources/plot-schema.json', 'r') as f: plotly_schema = json.load(f) # Compute property paths # ---------------------- compound_trace_nodes = PlotlyNode.get_all_compound_datatype_nodes( plotly_schema, TraceNode) compound_layout_nodes = PlotlyNode.get_all_compound_datatype_nodes( plotly_schema, LayoutNode) extra_layout_nodes = PlotlyNode.get_all_trace_layout_nodes(plotly_schema) # Write out validators # -------------------- validators_pkgdir = opath.join(outdir, 'validators') if opath.exists(validators_pkgdir): shutil.rmtree(validators_pkgdir) for node in compound_layout_nodes: write_validator_py(outdir, node, extra_layout_nodes) for node in compound_trace_nodes: write_validator_py(outdir, node) # Write out datatypes # ------------------- datatypes_pkgdir = opath.join(outdir, 'datatypes') if opath.exists(datatypes_pkgdir): shutil.rmtree(datatypes_pkgdir) for node in compound_layout_nodes: write_datatypes_py(outdir, node, extra_layout_nodes) for node in compound_trace_nodes: write_datatypes_py(outdir, node) # Append figure class to datatypes # -------------------------------- base_node = TraceNode(plotly_schema) append_figure_class(datatypes_pkgdir, base_node) # Append traces validator class # ----------------------------- append_traces_validator_py(validators_pkgdir, base_node)
def perform_codegen(): # Set root codegen output directory # --------------------------------- # (relative to project root) abs_file_path = opath.realpath(__file__) packages_py = opath.dirname(opath.dirname(opath.dirname(abs_file_path))) outdir = opath.join(packages_py, "plotly", "plotly") # Delete prior codegen output # --------------------------- validators_pkgdir = opath.join(outdir, "validators") if opath.exists(validators_pkgdir): shutil.rmtree(validators_pkgdir) graph_objs_pkgdir = opath.join(outdir, "graph_objs") if opath.exists(graph_objs_pkgdir): shutil.rmtree(graph_objs_pkgdir) # plotly/datatypes is not used anymore, but was at one point so we'll # still delete it if we find it in case a developer is upgrading from an # older version datatypes_pkgdir = opath.join(outdir, "datatypes") if opath.exists(datatypes_pkgdir): shutil.rmtree(datatypes_pkgdir) # Load plotly schema # ------------------ plot_schema_path = opath.join(packages_py, "plotly", "codegen", "resources", "plot-schema.json") with open(plot_schema_path, "r") as f: plotly_schema = json.load(f) # Preprocess Schema # ----------------- preprocess_schema(plotly_schema) # Build node lists # ---------------- # ### TraceNode ### base_traces_node = TraceNode(plotly_schema) compound_trace_nodes = PlotlyNode.get_all_compound_datatype_nodes( plotly_schema, TraceNode) all_trace_nodes = PlotlyNode.get_all_datatype_nodes( plotly_schema, TraceNode) # ### LayoutNode ### compound_layout_nodes = PlotlyNode.get_all_compound_datatype_nodes( plotly_schema, LayoutNode) layout_node = compound_layout_nodes[0] all_layout_nodes = PlotlyNode.get_all_datatype_nodes( plotly_schema, LayoutNode) subplot_nodes = [ node for node in layout_node.child_compound_datatypes if node.node_data.get("_isSubplotObj", False) ] layout_array_nodes = [ node for node in layout_node.child_compound_datatypes if node.is_array_element and node.has_child("xref") and node.has_child("yref") ] # ### FrameNode ### compound_frame_nodes = PlotlyNode.get_all_compound_datatype_nodes( plotly_schema, FrameNode) frame_node = compound_frame_nodes[0] all_frame_nodes = PlotlyNode.get_all_datatype_nodes( plotly_schema, FrameNode) # ### All nodes ### all_datatype_nodes = all_trace_nodes + all_layout_nodes + all_frame_nodes all_compound_nodes = [ node for node in all_datatype_nodes if node.is_compound and not isinstance(node, ElementDefaultsNode) ] # Write out validators # -------------------- # # ### Layout ### for node in all_layout_nodes: write_validator_py(outdir, node) # ### Trace ### for node in all_trace_nodes: write_validator_py(outdir, node) # ### Frames ### for node in all_frame_nodes: write_validator_py(outdir, node) # ### Data (traces) validator ### write_data_validator_py(outdir, base_traces_node) # Alls # ---- alls = {} # Write out datatypes # ------------------- for node in all_compound_nodes: write_datatype_py(outdir, node) # ### Deprecated ### # These are deprecated legacy datatypes like graph_objs.Marker write_deprecated_datatypes(outdir) # Write figure class to graph_objs # -------------------------------- data_validator = get_data_validator_instance(base_traces_node) layout_validator = layout_node.get_validator_instance() frame_validator = frame_node.get_validator_instance() write_figure_classes( outdir, base_traces_node, data_validator, layout_validator, frame_validator, subplot_nodes, layout_array_nodes, ) # Write validator __init__.py files # --------------------------------- # ### Write __init__.py files for each validator package ### validator_rel_class_imports = {} for node in all_datatype_nodes: if node.is_mapped: continue key = node.parent_path_parts validator_rel_class_imports.setdefault( key, []).append(f"._{node.name_property}.{node.name_validator_class}") # Add Data validator root_validator_pairs = validator_rel_class_imports[()] root_validator_pairs.append("._data.DataValidator") # Output validator __init__.py files validators_pkg = opath.join(outdir, "validators") for path_parts, rel_classes in validator_rel_class_imports.items(): write_init_py(validators_pkg, path_parts, [], rel_classes) # Write datatype __init__.py files # -------------------------------- datatype_rel_class_imports = {} datatype_rel_module_imports = {} for node in all_compound_nodes: key = node.parent_path_parts # class import datatype_rel_class_imports.setdefault( key, []).append(f"._{node.name_undercase}.{node.name_datatype_class}") # submodule import if node.child_compound_datatypes: datatype_rel_module_imports.setdefault( key, []).append(f".{node.name_undercase}") # ### Write plotly/graph_objs/graph_objs.py ### # This if for backward compatibility. It just imports everything from # graph_objs/__init__.py write_graph_objs_graph_objs(outdir) # ### Add Figure and FigureWidget ### root_datatype_imports = datatype_rel_class_imports[()] root_datatype_imports.append("._figure.Figure") # ### Add deprecations ### for dep_clas in DEPRECATED_DATATYPES: root_datatype_imports.append(f"._deprecations.{dep_clas}") optional_figure_widget_import = f""" if sys.version_info < (3, 7) or TYPE_CHECKING: try: import ipywidgets as _ipywidgets from distutils.version import LooseVersion as _LooseVersion if _LooseVersion(_ipywidgets.__version__) >= _LooseVersion("7.0.0"): from ..graph_objs._figurewidget import FigureWidget else: raise ImportError() except Exception: from ..missing_ipywidgets import FigureWidget else: __all__.append("FigureWidget") orig_getattr = __getattr__ def __getattr__(import_name): if import_name == "FigureWidget": try: import ipywidgets from distutils.version import LooseVersion if LooseVersion(ipywidgets.__version__) >= LooseVersion("7.0.0"): from ..graph_objs._figurewidget import FigureWidget return FigureWidget else: raise ImportError() except Exception: from ..missing_ipywidgets import FigureWidget return FigureWidget return orig_getattr(import_name) """ # ### __all__ ### for path_parts, class_names in alls.items(): if path_parts and class_names: filepath = opath.join(outdir, "graph_objs", *path_parts, "__init__.py") with open(filepath, "at") as f: f.write(f"\n__all__ = {class_names}") # ### Output datatype __init__.py files ### graph_objs_pkg = opath.join(outdir, "graph_objs") for path_parts in datatype_rel_class_imports: rel_classes = sorted(datatype_rel_class_imports[path_parts]) rel_modules = sorted(datatype_rel_module_imports.get(path_parts, [])) if path_parts == (): init_extra = optional_figure_widget_import else: init_extra = "" write_init_py(graph_objs_pkg, path_parts, rel_modules, rel_classes, init_extra) # ### Output graph_objects.py alias graph_objects_rel_classes = [ "..graph_objs." + rel_path.split(".")[-1] for rel_path in datatype_rel_class_imports[()] ] graph_objects_rel_modules = [ "..graph_objs." + rel_module.split(".")[-1] for rel_module in datatype_rel_module_imports[()] ] graph_objects_init_source = build_from_imports_py( graph_objects_rel_modules, graph_objects_rel_classes, init_extra=optional_figure_widget_import, ) graph_objects_path = opath.join(outdir, "graph_objects", "__init__.py") os.makedirs(opath.join(outdir, "graph_objects"), exist_ok=True) with open(graph_objects_path, "wt") as f: f.write(graph_objects_init_source) # ### Run black code formatter on output directories ### subprocess.call(["black", "--target-version=py36", validators_pkgdir]) subprocess.call(["black", "--target-version=py36", graph_objs_pkgdir]) subprocess.call(["black", "--target-version=py36", graph_objects_path])
def perform_codegen(): # Set root codegen output directory # --------------------------------- # (relative to project root) abs_file_path = opath.realpath(__file__) packages_py = opath.dirname(opath.dirname(opath.dirname(abs_file_path))) outdir = opath.join(packages_py, "plotly", "plotly") # Delete prior codegen output # --------------------------- validators_pkgdir = opath.join(outdir, "validators") if opath.exists(validators_pkgdir): shutil.rmtree(validators_pkgdir) graph_objs_pkgdir = opath.join(outdir, "graph_objs") if opath.exists(graph_objs_pkgdir): shutil.rmtree(graph_objs_pkgdir) # plotly/datatypes is not used anymore, but was at one point so we'll # still delete it if we find it in case a developer is upgrading from an # older version datatypes_pkgdir = opath.join(outdir, "datatypes") if opath.exists(datatypes_pkgdir): shutil.rmtree(datatypes_pkgdir) # Load plotly schema # ------------------ plot_schema_path = opath.join( packages_py, "plotly", "codegen", "resources", "plot-schema.json" ) with open(plot_schema_path, "r") as f: plotly_schema = json.load(f) # Preprocess Schema # ----------------- preprocess_schema(plotly_schema) # Build node lists # ---------------- # ### TraceNode ### base_traces_node = TraceNode(plotly_schema) compound_trace_nodes = PlotlyNode.get_all_compound_datatype_nodes( plotly_schema, TraceNode ) all_trace_nodes = PlotlyNode.get_all_datatype_nodes(plotly_schema, TraceNode) # ### LayoutNode ### compound_layout_nodes = PlotlyNode.get_all_compound_datatype_nodes( plotly_schema, LayoutNode ) layout_node = compound_layout_nodes[0] all_layout_nodes = PlotlyNode.get_all_datatype_nodes(plotly_schema, LayoutNode) subplot_nodes = [ node for node in layout_node.child_compound_datatypes if node.node_data.get("_isSubplotObj", False) ] # ### FrameNode ### compound_frame_nodes = PlotlyNode.get_all_compound_datatype_nodes( plotly_schema, FrameNode ) frame_node = compound_frame_nodes[0] all_frame_nodes = PlotlyNode.get_all_datatype_nodes(plotly_schema, FrameNode) # ### All nodes ### all_datatype_nodes = all_trace_nodes + all_layout_nodes + all_frame_nodes all_compound_nodes = [ node for node in all_datatype_nodes if node.is_compound and not isinstance(node, ElementDefaultsNode) ] # Write out validators # -------------------- # # ### Layout ### for node in all_layout_nodes: write_validator_py(outdir, node) # ### Trace ### for node in all_trace_nodes: write_validator_py(outdir, node) # ### Frames ### for node in all_frame_nodes: write_validator_py(outdir, node) # ### Data (traces) validator ### write_data_validator_py(outdir, base_traces_node) # Alls # ---- alls = {} # Write out datatypes # ------------------- for node in all_compound_nodes: write_datatype_py(outdir, node) alls.setdefault(node.path_parts, []) alls[node.path_parts].extend( c.name_datatype_class for c in node.child_compound_datatypes ) if node.parent_path_parts == (): # Add top-level classes to alls alls.setdefault((), []) alls[node.parent_path_parts].append(node.name_datatype_class) # ### Deprecated ### # These are deprecated legacy datatypes like graph_objs.Marker write_deprecated_datatypes(outdir) # Write figure class to graph_objs # -------------------------------- data_validator = get_data_validator_instance(base_traces_node) layout_validator = layout_node.get_validator_instance() frame_validator = frame_node.get_validator_instance() write_figure_classes( outdir, base_traces_node, data_validator, layout_validator, frame_validator, subplot_nodes, ) # Write datatype __init__.py files # -------------------------------- # ### Build mapping from parent package to datatype class ### path_to_datatype_import_info = {} for node in all_compound_nodes: key = node.parent_path_parts # submodule import if node.child_compound_datatypes: path_to_datatype_import_info.setdefault(key, []).append( (f"plotly.graph_objs{node.parent_dotpath_str}", node.name_undercase) ) alls[node.parent_path_parts].append(node.name_undercase) # ### Write plotly/graph_objs/graph_objs.py ### # This if for backward compatibility. It just imports everything from # graph_objs/__init__.py write_graph_objs_graph_objs(outdir) # ### Add Figure and FigureWidget ### root_datatype_imports = path_to_datatype_import_info[()] root_datatype_imports.append(("._figure", "Figure")) alls[()].append("Figure") # ### Add deprecations ### root_datatype_imports.append(("._deprecations", DEPRECATED_DATATYPES.keys())) alls[()].extend(DEPRECATED_DATATYPES.keys()) # Sort alls for k, v in alls.items(): alls[k] = list(sorted(v)) optional_figure_widget_import = f""" __all__ = {alls[()]} try: import ipywidgets from distutils.version import LooseVersion if LooseVersion(ipywidgets.__version__) >= LooseVersion('7.0.0'): from ._figurewidget import FigureWidget del LooseVersion del ipywidgets __all__.append("FigureWidget") except ImportError: pass """ root_datatype_imports.append(optional_figure_widget_import) # ### __all__ ### for path_parts, class_names in alls.items(): if path_parts and class_names: filepath = opath.join(outdir, "graph_objs", *path_parts, "__init__.py") with open(filepath, "at") as f: f.write(f"\n__all__ = {class_names}") # ### Output datatype __init__.py files ### graph_objs_pkg = opath.join(outdir, "graph_objs") for path_parts, import_pairs in path_to_datatype_import_info.items(): write_init_py(graph_objs_pkg, path_parts, import_pairs) # ### Output graph_objects.py alias graph_objects_path = opath.join(outdir, "graph_objects.py") with open(graph_objects_path, "wt") as f: f.write( f"""\ from __future__ import absolute_import from plotly.graph_objs import * __all__ = {alls[()]}""" ) # ### Run black code formatter on output directories ### subprocess.call(["black", "--target-version=py27", validators_pkgdir]) subprocess.call(["black", "--target-version=py27", graph_objs_pkgdir]) subprocess.call(["black", "--target-version=py27", graph_objects_path])
def perform_codegen(): # Set root codegen output directory # --------------------------------- # (relative to project root) outdir = 'plotly' # Delete prior codegen output # --------------------------- validators_pkgdir = opath.join(outdir, 'validators') if opath.exists(validators_pkgdir): shutil.rmtree(validators_pkgdir) graph_objs_pkgdir = opath.join(outdir, 'graph_objs') if opath.exists(graph_objs_pkgdir): shutil.rmtree(graph_objs_pkgdir) # plotly/datatypes is not used anymore, but was at one point so we'll # still delete it if we find it in case a developer is upgrading from an # older version datatypes_pkgdir = opath.join(outdir, 'datatypes') if opath.exists(datatypes_pkgdir): shutil.rmtree(datatypes_pkgdir) # Load plotly schema # ------------------ with open('plotly/package_data/plot-schema.json', 'r') as f: plotly_schema = json.load(f) # Preprocess Schema # ----------------- preprocess_schema(plotly_schema) # Build node lists # ---------------- # ### TraceNode ### base_traces_node = TraceNode(plotly_schema) compound_trace_nodes = PlotlyNode.get_all_compound_datatype_nodes( plotly_schema, TraceNode) all_trace_nodes = PlotlyNode.get_all_datatype_nodes( plotly_schema, TraceNode) # ### LayoutNode ### compound_layout_nodes = PlotlyNode.get_all_compound_datatype_nodes( plotly_schema, LayoutNode) layout_node = compound_layout_nodes[0] all_layout_nodes = PlotlyNode.get_all_datatype_nodes( plotly_schema, LayoutNode) # ### FrameNode ### compound_frame_nodes = PlotlyNode.get_all_compound_datatype_nodes( plotly_schema, FrameNode) frame_node = compound_frame_nodes[0] all_frame_nodes = PlotlyNode.get_all_datatype_nodes( plotly_schema, FrameNode) # ### All nodes ### all_datatype_nodes = (all_trace_nodes + all_layout_nodes + all_frame_nodes) all_compound_nodes = [node for node in all_datatype_nodes if node.is_compound and not isinstance(node, ElementDefaultsNode)] # Write out validators # -------------------- # # ### Layout ### for node in all_layout_nodes: write_validator_py(outdir, node) # ### Trace ### for node in all_trace_nodes: write_validator_py(outdir, node) # ### Frames ### for node in all_frame_nodes: write_validator_py(outdir, node) # ### Data (traces) validator ### write_data_validator_py(outdir, base_traces_node) # Write out datatypes # ------------------- # ### Layout ### for node in compound_layout_nodes: write_datatype_py(outdir, node) # ### Trace ### for node in compound_trace_nodes: write_datatype_py(outdir, node) # ### Frames ### for node in compound_frame_nodes: write_datatype_py(outdir, node) # ### Deprecated ### # These are deprecated legacy datatypes like graph_objs.Marker write_deprecated_datatypes(outdir) # Write figure class to graph_objs # -------------------------------- data_validator = get_data_validator_instance(base_traces_node) layout_validator = layout_node.get_validator_instance() frame_validator = frame_node.get_validator_instance() write_figure_classes(outdir, base_traces_node, data_validator, layout_validator, frame_validator) # Write validator __init__.py files # --------------------------------- # ### Write __init__.py files for each validator package ### path_to_validator_import_info = {} for node in all_datatype_nodes: if node.is_mapped: continue key = node.parent_path_parts path_to_validator_import_info.setdefault(key, []).append( (f"._{node.name_property}", node.name_validator_class) ) # Add Data validator root_validator_pairs = path_to_validator_import_info[()] root_validator_pairs.append(('._data', 'DataValidator')) # Output validator __init__.py files validators_pkg = opath.join(outdir, 'validators') for path_parts, import_pairs in path_to_validator_import_info.items(): write_init_py(validators_pkg, path_parts, import_pairs) # Write datatype __init__.py files # -------------------------------- # ### Build mapping from parent package to datatype class ### path_to_datatype_import_info = {} for node in all_compound_nodes: key = node.parent_path_parts # class import path_to_datatype_import_info.setdefault(key, []).append( (f"._{node.name_undercase}", node.name_datatype_class) ) # submodule import if node.child_compound_datatypes: path_to_datatype_import_info.setdefault(key, []).append( (f"plotly.graph_objs{node.parent_dotpath_str}", node.name_undercase) ) # ### Write plotly/graph_objs/graph_objs.py ### # This if for backward compatibility. It just imports everything from # graph_objs/__init__.py write_graph_objs_graph_objs(outdir) # ### Add Figure and FigureWidget ### root_datatype_imports = path_to_datatype_import_info[()] root_datatype_imports.append(('._figure', 'Figure')) optional_figure_widget_import = """ try: import ipywidgets from distutils.version import LooseVersion if LooseVersion(ipywidgets.__version__) >= LooseVersion('7.0.0'): from ._figurewidget import FigureWidget del LooseVersion del ipywidgets except ImportError: pass """ root_datatype_imports.append(optional_figure_widget_import) # ### Add deprecations ### root_datatype_imports.append(('._deprecations', DEPRECATED_DATATYPES.keys())) # ### Output datatype __init__.py files ### graph_objs_pkg = opath.join(outdir, 'graph_objs') for path_parts, import_pairs in path_to_datatype_import_info.items(): write_init_py(graph_objs_pkg, path_parts, import_pairs)