@@ -185,13 +185,37 @@ def _prop_descriptions(self):
185185 buffer .write (f"""
186186 def __init__(self""" )
187187
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 )
191203
192204 buffer .write (f"""
193205 super({ datatype_class } , self).__init__('{ node .name_property } ')
194206
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+
195219 # Import validators
196220 # -----------------
197221 from plotly.validators{ node .parent_dotpath_str } import (
@@ -210,8 +234,10 @@ def __init__(self""")
210234 # Populate data dict with properties
211235 # ----------------------------------""" )
212236 for subtype_node in subtype_nodes :
237+ name_prop = subtype_node .name_property
213238 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""" )
215241
216242 # ### Literals ###
217243 if literal_nodes :
@@ -233,7 +259,7 @@ def __init__(self""")
233259
234260 # Process unknown kwargs
235261 # ----------------------
236- self._process_kwargs(**kwargs)
262+ self._process_kwargs(**dict(arg, ** kwargs))
237263 """ )
238264
239265 # Return source string
@@ -266,7 +292,10 @@ def reindent_validator_description(validator, extra_indent):
266292 validator .description ().strip ().split ('\n ' ))
267293
268294
269- def add_constructor_params (buffer , subtype_nodes , extras = ()):
295+ def add_constructor_params (buffer ,
296+ subtype_nodes ,
297+ prepend_extras = (),
298+ append_extras = ()):
270299 """
271300 Write datatype constructor params to a buffer
272301
@@ -276,17 +305,23 @@ def add_constructor_params(buffer, subtype_nodes, extras=()):
276305 Buffer to write to
277306 subtype_nodes : list of PlotlyNode
278307 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]
280311 List of extra parameters to include at the end of the params
281312 Returns
282313 -------
283314 None
284315 """
316+ for extra in prepend_extras :
317+ buffer .write (f""",
318+ { extra } =None""" )
319+
285320 for i , subtype_node in enumerate (subtype_nodes ):
286321 buffer .write (f""",
287322 { subtype_node .name_property } =None""" )
288323
289- for extra in extras :
324+ for extra in append_extras :
290325 buffer .write (f""",
291326 { extra } =None""" )
292327
@@ -296,7 +331,7 @@ def add_constructor_params(buffer, subtype_nodes, extras=()):
296331 ):""" )
297332
298333
299- def add_docstring (buffer , node , header , extras = ()):
334+ def add_docstring (buffer , node , header , prepend_extras = (), append_extras = ()):
300335 """
301336 Write docstring for a compound datatype node
302337
@@ -309,6 +344,12 @@ def add_docstring(buffer, node, header, extras=()):
309344 header :
310345 Top-level header for docstring that will preceded the input node's
311346 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
312353 Returns
313354 -------
314355
@@ -340,11 +381,23 @@ def add_docstring(buffer, node, header, extras=()):
340381
341382 # Write parameter descriptions
342383 # ----------------------------
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
343396 buffer .write (node .get_constructor_params_docstring (
344397 indent = 8 ))
345398
346- # Write any extras
347- for p , v in extras :
399+ # Write any append extras
400+ for p , v in append_extras :
348401 v_wrapped = '\n ' .join (textwrap .wrap (
349402 v ,
350403 width = 79 - 12 ,
0 commit comments