@@ -185,13 +185,37 @@ def _prop_descriptions(self):
185
185
buffer .write (f"""
186
186
def __init__(self""" )
187
187
188
- add_constructor_params (buffer , subtype_nodes )
189
- header = f"Construct a new { datatype_class } object"
190
- add_docstring (buffer , node , header = header )
188
+ add_constructor_params (buffer ,
189
+ subtype_nodes ,
190
+ prepend_extras = ['arg' ])
191
+
192
+ # ### Constructor Docstring ###
193
+ header = f'Construct a new { datatype_class } object'
194
+ class_name = (f'plotly.graph_objs'
195
+ f'{ node .parent_dotpath_str } .'
196
+ f'{ node .name_datatype_class } ' )
197
+
198
+ extras = [(f'arg' ,
199
+ f'dict of properties compatible with this constructor '
200
+ f'or an instance of { class_name } ' )]
201
+
202
+ add_docstring (buffer , node , header = header , prepend_extras = extras )
191
203
192
204
buffer .write (f"""
193
205
super({ datatype_class } , self).__init__('{ node .name_property } ')
194
206
207
+ # Validate arg
208
+ # ------------
209
+ if arg is None:
210
+ arg = {{}}
211
+ elif isinstance(arg, self.__class__):
212
+ arg = arg.to_plotly_json()
213
+ elif not isinstance(arg, dict):
214
+ raise ValueError(\" \" \" \\
215
+ The first argument to the { class_name }
216
+ constructor must be a dict or
217
+ an instance of { class_name } \" \" \" )
218
+
195
219
# Import validators
196
220
# -----------------
197
221
from plotly.validators{ node .parent_dotpath_str } import (
@@ -210,8 +234,10 @@ def __init__(self""")
210
234
# Populate data dict with properties
211
235
# ----------------------------------""" )
212
236
for subtype_node in subtype_nodes :
237
+ name_prop = subtype_node .name_property
213
238
buffer .write (f"""
214
- self.{ subtype_node .name_property } = { subtype_node .name_property } """ )
239
+ v = arg.pop('{ name_prop } ', None)
240
+ self.{ name_prop } = { name_prop } or v""" )
215
241
216
242
# ### Literals ###
217
243
if literal_nodes :
@@ -233,7 +259,7 @@ def __init__(self""")
233
259
234
260
# Process unknown kwargs
235
261
# ----------------------
236
- self._process_kwargs(**kwargs)
262
+ self._process_kwargs(**dict(arg, ** kwargs))
237
263
""" )
238
264
239
265
# Return source string
@@ -266,7 +292,10 @@ def reindent_validator_description(validator, extra_indent):
266
292
validator .description ().strip ().split ('\n ' ))
267
293
268
294
269
- def add_constructor_params (buffer , subtype_nodes , extras = ()):
295
+ def add_constructor_params (buffer ,
296
+ subtype_nodes ,
297
+ prepend_extras = (),
298
+ append_extras = ()):
270
299
"""
271
300
Write datatype constructor params to a buffer
272
301
@@ -276,17 +305,23 @@ def add_constructor_params(buffer, subtype_nodes, extras=()):
276
305
Buffer to write to
277
306
subtype_nodes : list of PlotlyNode
278
307
List of datatype nodes to be written as constructor params
279
- extras : list[str]
308
+ prepend_extras : list[str]
309
+ List of extra parameters to include at the beginning of the params
310
+ append_extras : list[str]
280
311
List of extra parameters to include at the end of the params
281
312
Returns
282
313
-------
283
314
None
284
315
"""
316
+ for extra in prepend_extras :
317
+ buffer .write (f""",
318
+ { extra } =None""" )
319
+
285
320
for i , subtype_node in enumerate (subtype_nodes ):
286
321
buffer .write (f""",
287
322
{ subtype_node .name_property } =None""" )
288
323
289
- for extra in extras :
324
+ for extra in append_extras :
290
325
buffer .write (f""",
291
326
{ extra } =None""" )
292
327
@@ -296,7 +331,7 @@ def add_constructor_params(buffer, subtype_nodes, extras=()):
296
331
):""" )
297
332
298
333
299
- def add_docstring (buffer , node , header , extras = ()):
334
+ def add_docstring (buffer , node , header , prepend_extras = (), append_extras = ()):
300
335
"""
301
336
Write docstring for a compound datatype node
302
337
@@ -309,6 +344,12 @@ def add_docstring(buffer, node, header, extras=()):
309
344
header :
310
345
Top-level header for docstring that will preceded the input node's
311
346
own description. Header should be < 71 characters long
347
+ prepend_extras :
348
+ List or tuple of propery name / description pairs that should be
349
+ included at the beginning of the docstring
350
+ append_extras :
351
+ List or tuple of propery name / description pairs that should be
352
+ included at the end of the docstring
312
353
Returns
313
354
-------
314
355
@@ -340,11 +381,23 @@ def add_docstring(buffer, node, header, extras=()):
340
381
341
382
# Write parameter descriptions
342
383
# ----------------------------
384
+ # Write any prepend extras
385
+ for p , v in prepend_extras :
386
+ v_wrapped = '\n ' .join (textwrap .wrap (
387
+ v ,
388
+ width = 79 - 12 ,
389
+ initial_indent = ' ' * 12 ,
390
+ subsequent_indent = ' ' * 12 ))
391
+ buffer .write (f"""
392
+ { p }
393
+ { v_wrapped } """ )
394
+
395
+ # Write core docstring
343
396
buffer .write (node .get_constructor_params_docstring (
344
397
indent = 8 ))
345
398
346
- # Write any extras
347
- for p , v in extras :
399
+ # Write any append extras
400
+ for p , v in append_extras :
348
401
v_wrapped = '\n ' .join (textwrap .wrap (
349
402
v ,
350
403
width = 79 - 12 ,
0 commit comments