@@ -584,7 +584,8 @@ def numbers_allowed(self):
584
584
585
585
def description (self ):
586
586
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 ))
588
589
589
590
valid_color_description = """\
590
591
The '{plotly_name}' property is a color and may be specified as:
@@ -1090,38 +1091,60 @@ def validate_coerce(self, v):
1090
1091
class CompoundValidator (BaseValidator ):
1091
1092
def __init__ (self , plotly_name , parent_name , data_class , data_docs ):
1092
1093
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
1094
1098
self .data_docs = data_docs
1099
+ self .module_str = CompoundValidator .compute_graph_obj_module_str (
1100
+ self .data_class_str , parent_name )
1095
1101
1096
1102
@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 )
1104
1106
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 )
1107
1109
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
1109
1121
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
1111
1133
1112
1134
def description (self ):
1113
1135
1114
1136
desc = ("""\
1115
- The '{plotly_name}' property is an instance of {data_class }
1137
+ The '{plotly_name}' property is an instance of {class_str }
1116
1138
that may be specified as:
1117
- - An instance of {data_class }
1139
+ - An instance of {module_str}.{class_str }
1118
1140
- A dict of string/value properties that will be passed to the
1119
- {data_class } constructor
1141
+ {class_str } constructor
1120
1142
1121
1143
Supported dict properties:
1122
1144
{constructor_params_str}"""
1123
1145
).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 ,
1125
1148
constructor_params_str = self .data_docs )
1126
1149
1127
1150
return desc
@@ -1150,29 +1173,44 @@ def validate_coerce(self, v):
1150
1173
class CompoundArrayValidator (BaseValidator ):
1151
1174
def __init__ (self , plotly_name , parent_name , element_class , element_docs ):
1152
1175
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
+
1154
1181
self .data_docs = element_docs
1182
+ self .module_str = CompoundValidator .compute_graph_obj_module_str (
1183
+ self .data_class_str , parent_name )
1155
1184
1156
1185
def description (self ):
1157
1186
1158
1187
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
1162
1191
1163
1192
Supported dict properties:
1164
1193
{constructor_params_str}"""
1165
1194
).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 ,
1167
1197
constructor_params_str = self .data_docs )
1168
1198
1169
1199
return desc
1170
1200
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
+
1171
1209
def validate_coerce (self , v ):
1172
1210
1173
1211
if isinstance (self .data_class , str ):
1174
1212
raise ValueError ("Invalid data_class of type 'string': {data_class}"
1175
- .format (data_class = self .data_class ))
1213
+ .format (data_class = self .data_class ))
1176
1214
1177
1215
if v is None :
1178
1216
v = ()
@@ -1203,15 +1241,16 @@ def validate_coerce(self, v):
1203
1241
class BaseDataValidator (BaseValidator ):
1204
1242
def __init__ (self , class_map , plotly_name , parent_name ):
1205
1243
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
1207
1246
1208
1247
def description (self ):
1209
1248
1210
- trace_types = str (list (self .class_map .keys ()))
1249
+ trace_types = str (list (self .class_strs_map .keys ()))
1211
1250
1212
1251
trace_types_wrapped = '\n ' .join (textwrap .wrap (trace_types ,
1213
1252
subsequent_indent = ' ' * 21 ,
1214
- width = 80 - 8 ))
1253
+ width = 79 - 8 ))
1215
1254
1216
1255
desc = ("""\
1217
1256
The '{plotly_name}' property is a tuple of trace instances that may be specified as:
@@ -1228,6 +1267,20 @@ def description(self):
1228
1267
1229
1268
return desc
1230
1269
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
+
1231
1284
def validate_coerce (self , v ):
1232
1285
1233
1286
if v is None :
0 commit comments