@@ -584,7 +584,8 @@ def numbers_allowed(self):
584584
585585 def description (self ):
586586
587- named_clrs_str = '\n ' .join (textwrap .wrap (', ' .join (self .named_colors ), width = 80 , subsequent_indent = ' ' * 12 ))
587+ named_clrs_str = '\n ' .join (textwrap .wrap (', ' .join (
588+ self .named_colors ), width = 79 , subsequent_indent = ' ' * 12 ))
588589
589590 valid_color_description = """\
590591 The '{plotly_name}' property is a color and may be specified as:
@@ -1090,38 +1091,60 @@ def validate_coerce(self, v):
10901091class CompoundValidator (BaseValidator ):
10911092 def __init__ (self , plotly_name , parent_name , data_class , data_docs ):
10921093 super ().__init__ (plotly_name = plotly_name , parent_name = parent_name )
1093- self .data_class = data_class
1094+
1095+ # Save element class string
1096+ self .data_class_str = data_class
1097+ self ._data_class = None
10941098 self .data_docs = data_docs
1099+ self .module_str = CompoundValidator .compute_graph_obj_module_str (
1100+ self .data_class_str , parent_name )
10951101
10961102 @staticmethod
1097- def get_constructor_params_str (data_class ):
1098- params_match = re .search ("Parameters\n \W*-+\n \W*(.*?)(Returns|$)" ,
1099- str (data_class .__init__ .__doc__ ),
1100- flags = re .DOTALL )
1101-
1102- if params_match is not None :
1103- param_descs = params_match .groups ()[0 ]
1103+ def import_graph_objs_class (data_class_str , module_str ):
1104+ # Import class module
1105+ module = import_module (module_str )
11041106
1105- # Increase indent by 4 spaces
1106- param_descs_indented = ( ' \n ' + ' ' * 4 ). join ( param_descs . split ( ' \n ' ) )
1107+ # Get class reference
1108+ return getattr ( module , data_class_str )
11071109
1108- return param_descs_indented
1110+ @staticmethod
1111+ def compute_graph_obj_module_str (data_class_str , parent_name ):
1112+ if parent_name == 'frame' and data_class_str in ['Data' , 'Layout' ]:
1113+ # Special case. There are no graph_objs.frame.Data or
1114+ # graph_objs.frame.Layout classes. These are remapped to
1115+ # graph_objs.Data and graph_objs.Layout
1116+
1117+ parent_parts = parent_name .split ('.' )
1118+ module_str = '.' .join (['plotly.graph_objs' ] + parent_parts [1 :])
1119+ elif parent_name :
1120+ module_str = 'plotly.graph_objs.' + parent_name
11091121 else :
1110- return ''
1122+ module_str = 'plotly.graph_objs'
1123+
1124+ return module_str
1125+
1126+ @property
1127+ def data_class (self ):
1128+ if self ._data_class is None :
1129+ self ._data_class = CompoundValidator .import_graph_objs_class (
1130+ self .data_class_str , self .module_str )
1131+
1132+ return self ._data_class
11111133
11121134 def description (self ):
11131135
11141136 desc = ("""\
1115- The '{plotly_name}' property is an instance of {data_class }
1137+ The '{plotly_name}' property is an instance of {class_str }
11161138 that may be specified as:
1117- - An instance of {data_class }
1139+ - An instance of {module_str}.{class_str }
11181140 - A dict of string/value properties that will be passed to the
1119- {data_class } constructor
1141+ {class_str } constructor
11201142
11211143 Supported dict properties:
11221144 {constructor_params_str}"""
11231145 ).format (plotly_name = self .plotly_name ,
1124- data_class = type_str (self .data_class ),
1146+ class_str = self .data_class_str ,
1147+ module_str = self .module_str ,
11251148 constructor_params_str = self .data_docs )
11261149
11271150 return desc
@@ -1150,29 +1173,44 @@ def validate_coerce(self, v):
11501173class CompoundArrayValidator (BaseValidator ):
11511174 def __init__ (self , plotly_name , parent_name , element_class , element_docs ):
11521175 super ().__init__ (plotly_name = plotly_name , parent_name = parent_name )
1153- self .data_class = element_class
1176+
1177+ # Save element class string
1178+ self .data_class_str = element_class
1179+ self ._data_class = None
1180+
11541181 self .data_docs = element_docs
1182+ self .module_str = CompoundValidator .compute_graph_obj_module_str (
1183+ self .data_class_str , parent_name )
11551184
11561185 def description (self ):
11571186
11581187 desc = ("""\
1159- The '{plotly_name}' property is a tuple of instances of {data_class } that may be specified as:
1160- - A list or tuple of instances of {data_class }
1161- - A list or tuple of dicts of string/value properties that will be passed to the {data_class } constructor
1188+ The '{plotly_name}' property is a tuple of instances of {class_str } that may be specified as:
1189+ - A list or tuple of instances of {module_str}.{class_str }
1190+ - A list or tuple of dicts of string/value properties that will be passed to the {class_str } constructor
11621191
11631192 Supported dict properties:
11641193 {constructor_params_str}"""
11651194 ).format (plotly_name = self .plotly_name ,
1166- data_class = type_str (self .data_class ),
1195+ class_str = self .data_class_str ,
1196+ module_str = self .module_str ,
11671197 constructor_params_str = self .data_docs )
11681198
11691199 return desc
11701200
1201+ @property
1202+ def data_class (self ):
1203+ if self ._data_class is None :
1204+ self ._data_class = CompoundValidator .import_graph_objs_class (
1205+ self .data_class_str , self .module_str )
1206+
1207+ return self ._data_class
1208+
11711209 def validate_coerce (self , v ):
11721210
11731211 if isinstance (self .data_class , str ):
11741212 raise ValueError ("Invalid data_class of type 'string': {data_class}"
1175- .format (data_class = self .data_class ))
1213+ .format (data_class = self .data_class ))
11761214
11771215 if v is None :
11781216 v = ()
@@ -1203,15 +1241,16 @@ def validate_coerce(self, v):
12031241class BaseDataValidator (BaseValidator ):
12041242 def __init__ (self , class_map , plotly_name , parent_name ):
12051243 super ().__init__ (plotly_name = plotly_name , parent_name = parent_name )
1206- self .class_map = class_map
1244+ self .class_strs_map = class_map
1245+ self ._class_map = None
12071246
12081247 def description (self ):
12091248
1210- trace_types = str (list (self .class_map .keys ()))
1249+ trace_types = str (list (self .class_strs_map .keys ()))
12111250
12121251 trace_types_wrapped = '\n ' .join (textwrap .wrap (trace_types ,
12131252 subsequent_indent = ' ' * 21 ,
1214- width = 80 - 8 ))
1253+ width = 79 - 8 ))
12151254
12161255 desc = ("""\
12171256 The '{plotly_name}' property is a tuple of trace instances that may be specified as:
@@ -1228,6 +1267,20 @@ def description(self):
12281267
12291268 return desc
12301269
1270+ @property
1271+ def class_map (self ):
1272+ if self ._class_map is None :
1273+
1274+ # Initialize class map
1275+ self ._class_map = {}
1276+
1277+ # Import trace classes
1278+ trace_module = import_module ('plotly.graph_objs' )
1279+ for k , class_str in self .class_strs_map .items ():
1280+ self ._class_map [k ] = getattr (trace_module , class_str )
1281+
1282+ return self ._class_map
1283+
12311284 def validate_coerce (self , v ):
12321285
12331286 if v is None :
0 commit comments