Skip to content

Commit ba27feb

Browse files
author
Shammamah Hossain
authored
Merge pull request #782 from plotly/docstring-default-values
Docstring default values + minor corrections
2 parents cfa120e + bf78b45 commit ba27feb

File tree

3 files changed

+72
-43
lines changed

3 files changed

+72
-43
lines changed

dash/development/_py_components_generation.py

+52-23
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,12 @@ def create_docstring(component_name, props, description):
236236
props = reorder_props(props=props)
237237

238238
return (
239-
"""A {name} component.\n{description}
239+
"""A{n} {name} component.\n{description}
240240
241241
Keyword arguments:\n{args}"""
242242
).format(
243+
n='n' if component_name[0].lower() in ['a', 'e', 'i', 'o', 'u']
244+
else '',
243245
name=component_name,
244246
description=description,
245247
args='\n'.join(
@@ -249,6 +251,7 @@ def create_docstring(component_name, props, description):
249251
else prop['flowType'],
250252
required=prop['required'],
251253
description=prop['description'],
254+
default=prop.get('defaultValue'),
252255
indent_num=0,
253256
is_flow_type='flowType' in prop and 'type' not in prop)
254257
for p, prop in list(filter_props(props).items())))
@@ -289,7 +292,7 @@ def parse_wildcards(props):
289292
"""
290293
list_of_valid_wildcard_attr_prefixes = []
291294
for wildcard_attr in ["data-*", "aria-*"]:
292-
if wildcard_attr in props.keys():
295+
if wildcard_attr in props:
293296
list_of_valid_wildcard_attr_prefixes.append(wildcard_attr[:-1])
294297
return list_of_valid_wildcard_attr_prefixes
295298

@@ -393,7 +396,7 @@ def filter_props(props):
393396

394397
# pylint: disable=too-many-arguments
395398
def create_prop_docstring(prop_name, type_object, required, description,
396-
indent_num, is_flow_type=False):
399+
default, indent_num, is_flow_type=False):
397400
"""
398401
Create the Dash component prop docstring
399402
@@ -407,6 +410,10 @@ def create_prop_docstring(prop_name, type_object, required, description,
407410
Component is required?
408411
description: str
409412
Dash component description
413+
default: dict
414+
Either None if a default value is not defined, or
415+
dict containing the key 'value' that defines a
416+
default value for the prop
410417
indent_num: int
411418
Number of indents to use for the context block
412419
(creates 2 spaces for every indent)
@@ -422,25 +429,40 @@ def create_prop_docstring(prop_name, type_object, required, description,
422429
type_object=type_object,
423430
is_flow_type=is_flow_type,
424431
indent_num=indent_num + 1)
425-
426432
indent_spacing = ' ' * indent_num
433+
434+
if default is None:
435+
default = ''
436+
else:
437+
default = default['value']
438+
439+
is_required = 'optional'
440+
if required:
441+
is_required = 'required'
442+
elif default and default not in ['null', '{}', '[]']:
443+
is_required = 'default {}'.format(
444+
default.replace('\n', '\n' + indent_spacing)
445+
)
446+
427447
if '\n' in py_type_name:
428-
return '{indent_spacing}- {name} ({is_required}): {description}. ' \
429-
'{name} has the following type: {type}'.format(
430-
indent_spacing=indent_spacing,
431-
name=prop_name,
432-
type=py_type_name,
433-
description=description,
434-
is_required='required' if required else 'optional')
448+
return '{indent_spacing}- {name} (dict; {is_required}): ' \
449+
'{description}{period}' \
450+
'{name} has the following type: {type}'.format(
451+
indent_spacing=indent_spacing,
452+
name=prop_name,
453+
type=py_type_name,
454+
description=description.strip().strip('.'),
455+
period='. ' if description else '',
456+
is_required=is_required)
435457
return '{indent_spacing}- {name} ({type}' \
436-
'{is_required}){description}'.format(
437-
indent_spacing=indent_spacing,
438-
name=prop_name,
439-
type='{}; '.format(py_type_name) if py_type_name else '',
440-
description=(
441-
': {}'.format(description) if description != '' else ''
442-
),
443-
is_required='required' if required else 'optional')
458+
'{is_required}){description}'.format(
459+
indent_spacing=indent_spacing,
460+
name=prop_name,
461+
type='{}; '.format(py_type_name) if py_type_name else '',
462+
description=(
463+
': {}'.format(description) if description != '' else ''
464+
),
465+
is_required=is_required)
444466

445467

446468
def map_js_to_py_types_prop_types(type_object):
@@ -458,6 +480,7 @@ def shape_or_exact():
458480
type_object=prop,
459481
required=prop['required'],
460482
description=prop.get('description', ''),
483+
default=prop.get('defaultValue'),
461484
indent_num=1
462485
) for prop_name, prop in
463486
list(type_object['value'].items())))
@@ -489,8 +512,13 @@ def shape_or_exact():
489512

490513
# React's PropTypes.arrayOf
491514
arrayOf=lambda: (
492-
"list" + ((" of {}s").format(
493-
js_to_py_type(type_object["value"]))
515+
"list" + ((" of {}").format(
516+
js_to_py_type(type_object["value"]) + 's'
517+
if js_to_py_type(type_object["value"]).split(' ')[0] != 'dict'
518+
else js_to_py_type(type_object["value"]).replace(
519+
'dict', 'dicts', 1
520+
)
521+
)
494522
if js_to_py_type(type_object["value"]) != ""
495523
else "")
496524
),
@@ -504,7 +532,7 @@ def shape_or_exact():
504532
# React's PropTypes.shape
505533
shape=shape_or_exact,
506534
# React's PropTypes.exact
507-
exact=shape_or_exact,
535+
exact=shape_or_exact
508536
)
509537

510538

@@ -548,6 +576,7 @@ def map_js_to_py_types_flow_types(type_object):
548576
type_object=prop['value'],
549577
required=prop['value']['required'],
550578
description=prop['value'].get('description', ''),
579+
default=prop.get('defaultValue'),
551580
indent_num=indent_num,
552581
is_flow_type=True)
553582
for prop in type_object['signature']['properties']))),
@@ -580,7 +609,7 @@ def js_to_py_type(type_object, is_flow_type=False, indent_num=0):
580609
if 'computed' in type_object and type_object['computed'] \
581610
or type_object.get('type', '') == 'function':
582611
return ''
583-
elif js_type_name in js_to_py_types:
612+
if js_type_name in js_to_py_types:
584613
if js_type_name == 'signature': # This is a Flow object w/ signature
585614
return js_to_py_types[js_type_name](indent_num)
586615
# All other types

tests/unit/development/metadata_test.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,28 @@ class Table(Component):
1212
- children (a list of or a singular dash component, string or number; optional)
1313
- optionalArray (list; optional): Description of optionalArray
1414
- optionalBool (boolean; optional)
15-
- optionalNumber (number; optional)
15+
- optionalNumber (number; default 42)
1616
- optionalObject (dict; optional)
17-
- optionalString (string; optional)
17+
- optionalString (string; default 'hello world')
1818
- optionalNode (a list of or a singular dash component, string or number; optional)
1919
- optionalElement (dash component; optional)
2020
- optionalEnum (a value equal to: 'News', 'Photos'; optional)
2121
- optionalUnion (string | number; optional)
2222
- optionalArrayOf (list of numbers; optional)
2323
- optionalObjectOf (dict with strings as keys and values of type number; optional)
24-
- optionalObjectWithExactAndNestedDescription (optional): . optionalObjectWithExactAndNestedDescription has the following type: dict containing keys 'color', 'fontSize', 'figure'.
24+
- optionalObjectWithExactAndNestedDescription (dict; optional): optionalObjectWithExactAndNestedDescription has the following type: dict containing keys 'color', 'fontSize', 'figure'.
2525
Those keys have the following types:
2626
- color (string; optional)
2727
- fontSize (number; optional)
28-
- figure (optional): Figure is a plotly graph object. figure has the following type: dict containing keys 'data', 'layout'.
28+
- figure (dict; optional): Figure is a plotly graph object. figure has the following type: dict containing keys 'data', 'layout'.
2929
Those keys have the following types:
3030
- data (list of dicts; optional): data is a collection of traces
3131
- layout (dict; optional): layout describes the rest of the figure
32-
- optionalObjectWithShapeAndNestedDescription (optional): . optionalObjectWithShapeAndNestedDescription has the following type: dict containing keys 'color', 'fontSize', 'figure'.
32+
- optionalObjectWithShapeAndNestedDescription (dict; optional): optionalObjectWithShapeAndNestedDescription has the following type: dict containing keys 'color', 'fontSize', 'figure'.
3333
Those keys have the following types:
3434
- color (string; optional)
3535
- fontSize (number; optional)
36-
- figure (optional): Figure is a plotly graph object. figure has the following type: dict containing keys 'data', 'layout'.
36+
- figure (dict; optional): Figure is a plotly graph object. figure has the following type: dict containing keys 'data', 'layout'.
3737
Those keys have the following types:
3838
- data (list of dicts; optional): data is a collection of traces
3939
- layout (dict; optional): layout describes the rest of the figure

tests/unit/development/test_base_component.py

+14-14
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ def setUp(self):
815815
"Those keys have the following types:",
816816
" - color (string; optional)",
817817
" - fontSize (number; optional)",
818-
" - figure (optional): Figure is a plotly graph object. figure has the following type: dict containing keys 'data', 'layout'.", # noqa: E501
818+
" - figure (dict; optional): Figure is a plotly graph object. figure has the following type: dict containing keys 'data', 'layout'.", # noqa: E501
819819
"Those keys have the following types:",
820820
" - data (list of dicts; optional): data is a collection of traces",
821821
" - layout (dict; optional): layout describes the rest of the figure" # noqa: E501
@@ -828,7 +828,7 @@ def setUp(self):
828828
"Those keys have the following types:",
829829
" - color (string; optional)",
830830
" - fontSize (number; optional)",
831-
" - figure (optional): Figure is a plotly graph object. figure has the following type: dict containing keys 'data', 'layout'.", # noqa: E501
831+
" - figure (dict; optional): Figure is a plotly graph object. figure has the following type: dict containing keys 'data', 'layout'.", # noqa: E501
832832
"Those keys have the following types:",
833833
" - data (list of dicts; optional): data is a collection of traces",
834834
" - layout (dict; optional): layout describes the rest of the figure" # noqa: E501
@@ -881,9 +881,9 @@ def assert_docstring(assertEqual, docstring):
881881
"- children (a list of or a singular dash component, string or number; optional)", # noqa: E501
882882
"- optionalArray (list; optional): Description of optionalArray",
883883
"- optionalBool (boolean; optional)",
884-
"- optionalNumber (number; optional)",
884+
"- optionalNumber (number; default 42)",
885885
"- optionalObject (dict; optional)",
886-
"- optionalString (string; optional)",
886+
"- optionalString (string; default 'hello world')",
887887

888888
"- optionalNode (a list of or a singular dash component, "
889889
"string or number; optional)",
@@ -896,7 +896,7 @@ def assert_docstring(assertEqual, docstring):
896896
"- optionalObjectOf (dict with strings as keys and values "
897897
"of type number; optional)",
898898

899-
"- optionalObjectWithExactAndNestedDescription (optional): . "
899+
"- optionalObjectWithExactAndNestedDescription (dict; optional): "
900900
"optionalObjectWithExactAndNestedDescription has the "
901901
"following type: dict containing keys "
902902
"'color', 'fontSize', 'figure'.",
@@ -905,7 +905,7 @@ def assert_docstring(assertEqual, docstring):
905905
" - color (string; optional)",
906906
" - fontSize (number; optional)",
907907

908-
" - figure (optional): Figure is a plotly graph object. "
908+
" - figure (dict; optional): Figure is a plotly graph object. "
909909
"figure has the following type: dict containing "
910910
"keys 'data', 'layout'.",
911911

@@ -915,7 +915,7 @@ def assert_docstring(assertEqual, docstring):
915915
" - layout (dict; optional): layout describes "
916916
"the rest of the figure",
917917

918-
"- optionalObjectWithShapeAndNestedDescription (optional): . "
918+
"- optionalObjectWithShapeAndNestedDescription (dict; optional): "
919919
"optionalObjectWithShapeAndNestedDescription has the "
920920
"following type: dict containing keys "
921921
"'color', 'fontSize', 'figure'.",
@@ -924,7 +924,7 @@ def assert_docstring(assertEqual, docstring):
924924
" - color (string; optional)",
925925
" - fontSize (number; optional)",
926926

927-
" - figure (optional): Figure is a plotly graph object. "
927+
" - figure (dict; optional): Figure is a plotly graph object. "
928928
"figure has the following type: dict containing "
929929
"keys 'data', 'layout'.",
930930

@@ -995,7 +995,7 @@ def setUp(self):
995995

996996
"dict containing keys 'customData', 'value'.",
997997
"Those keys have the following types:",
998-
"- customData (required): . customData has the following type: dict containing keys 'checked', 'children', 'customData', 'disabled', 'label', 'primaryText', 'secondaryText', 'style', 'value'.",
998+
"- customData (dict; required): customData has the following type: dict containing keys 'checked', 'children', 'customData', 'disabled', 'label', 'primaryText', 'secondaryText', 'style', 'value'.",
999999
" Those keys have the following types:",
10001000
" - checked (boolean; optional)",
10011001
" - children (a list of or a singular dash component, string or number; optional)",
@@ -1040,8 +1040,8 @@ def assert_flow_docstring(assertEqual, docstring):
10401040
"",
10411041
"Keyword arguments:",
10421042
"- requiredString (string; required): A required string",
1043-
"- optionalString (string; optional): A string that isn't required.",
1044-
"- optionalBoolean (boolean; optional): A boolean test",
1043+
"- optionalString (string; default ''): A string that isn't required.",
1044+
"- optionalBoolean (boolean; default false): A boolean test",
10451045

10461046
"- optionalNode (a list of or a singular dash component, string or number; optional): "
10471047
"A node test",
@@ -1052,7 +1052,7 @@ def assert_flow_docstring(assertEqual, docstring):
10521052

10531053
"- requiredUnion (string | number; required)",
10541054

1055-
"- optionalSignature(shape) (optional): This is a test of an object's shape. "
1055+
"- optionalSignature(shape) (dict; optional): This is a test of an object's shape. "
10561056
"optionalSignature(shape) has the following type: dict containing keys 'checked', "
10571057
"'children', 'customData', 'disabled', 'label', 'primaryText', 'secondaryText', "
10581058
"'style', 'value'.",
@@ -1068,12 +1068,12 @@ def assert_flow_docstring(assertEqual, docstring):
10681068
" - style (dict; optional)",
10691069
" - value (bool | number | str | dict | list; required)",
10701070

1071-
"- requiredNested (required): . requiredNested has the following type: dict containing "
1071+
"- requiredNested (dict; required): requiredNested has the following type: dict containing "
10721072
"keys 'customData', 'value'.",
10731073

10741074
" Those keys have the following types:",
10751075

1076-
" - customData (required): . customData has the following type: dict containing "
1076+
" - customData (dict; required): customData has the following type: dict containing "
10771077
"keys 'checked', 'children', 'customData', 'disabled', 'label', 'primaryText', "
10781078
"'secondaryText', 'style', 'value'.",
10791079

0 commit comments

Comments
 (0)