From 2ac99bab099557d206c491c157134588181d21b2 Mon Sep 17 00:00:00 2001 From: Chris P Date: Tue, 16 Apr 2019 22:29:07 -0400 Subject: [PATCH 1/8] support `exact` just like `shape` --- dash/development/_py_components_generation.py | 34 ++++++++++------- tests/development/metadata_test.json | 37 +++++++++++++++++++ tests/development/metadata_test.py | 8 ++++ tests/development/test_base_component.py | 13 +++++++ 4 files changed, 78 insertions(+), 14 deletions(-) diff --git a/dash/development/_py_components_generation.py b/dash/development/_py_components_generation.py index 61a183e787..6a1c663011 100644 --- a/dash/development/_py_components_generation.py +++ b/dash/development/_py_components_generation.py @@ -445,6 +445,22 @@ def create_prop_docstring(prop_name, type_object, required, description, def map_js_to_py_types_prop_types(type_object): """Mapping from the PropTypes js type object to the Python type""" + + shape_or_exact = lambda: 'dict containing keys {}.\n{}'.format( + ', '.join( + "'{}'".format(t) + for t in list(type_object['value'].keys())), + 'Those keys have the following types:\n{}'.format( + '\n'.join( + create_prop_docstring( + prop_name=prop_name, + type_object=prop, + required=prop['required'], + description=prop.get('description', ''), + indent_num=1 + ) for prop_name, prop in + list(type_object['value'].items())))) + return dict( array=lambda: 'list', bool=lambda: 'boolean', @@ -483,25 +499,15 @@ def map_js_to_py_types_prop_types(type_object): js_to_py_type(type_object['value'])), # React's PropTypes.shape - shape=lambda: 'dict containing keys {}.\n{}'.format( - ', '.join( - "'{}'".format(t) - for t in list(type_object['value'].keys())), - 'Those keys have the following types:\n{}'.format( - '\n'.join( - create_prop_docstring( - prop_name=prop_name, - type_object=prop, - required=prop['required'], - description=prop.get('description', ''), - indent_num=1 - ) for prop_name, prop in - list(type_object['value'].items())))), + shape=shape_or_exact, + # React's PropTypes.exact + exact=shape_or_exact, ) def map_js_to_py_types_flow_types(type_object): """Mapping from the Flow js types to the Python type""" + return dict( array=lambda: 'list', boolean=lambda: 'boolean', diff --git a/tests/development/metadata_test.json b/tests/development/metadata_test.json index faa4bc734e..80a381f062 100644 --- a/tests/development/metadata_test.json +++ b/tests/development/metadata_test.json @@ -174,6 +174,43 @@ "required": false, "description": "" }, + "optionalObjectWithExactAndNestedDescription": { + "type": { + "name": "shape", + "value": { + "color": { + "name": "string", + "required": false + }, + "fontSize": { + "name": "number", + "required": false + }, + "figure": { + "name": "shape", + "value": { + "data": { + "name": "arrayOf", + "value": { + "name": "object" + }, + "description": "data is a collection of traces", + "required": false + }, + "layout": { + "name": "object", + "description": "layout describes the rest of the figure", + "required": false + } + }, + "description": "Figure is a plotly graph object", + "required": false + } + } + }, + "required": false, + "description": "" + }, "optionalAny": { "type": { "name": "any" diff --git a/tests/development/metadata_test.py b/tests/development/metadata_test.py index c1a580fa6b..2357485923 100644 --- a/tests/development/metadata_test.py +++ b/tests/development/metadata_test.py @@ -22,6 +22,14 @@ class Table(Component): - optionalArrayOf (list; optional) - optionalObjectOf (dict with strings as keys and values of type number; optional) - optionalObjectWithShapeAndNestedDescription (optional): . optionalObjectWithShapeAndNestedDescription has the following type: dict containing keys 'color', 'fontSize', 'figure'. +Those keys have the following types: + - color (string; optional) + - fontSize (number; optional) + - figure (optional): Figure is a plotly graph object. figure has the following type: dict containing keys 'data', 'layout'. +Those keys have the following types: + - data (list; optional): data is a collection of traces + - layout (dict; optional): layout describes the rest of the figure +- optionalObjectWithExactAndNestedDescription (optional): . optionalObjectWithShapeAndNestedDescription has the following type: dict containing keys 'color', 'fontSize', 'figure'. Those keys have the following types: - color (string; optional) - fontSize (number; optional) diff --git a/tests/development/test_base_component.py b/tests/development/test_base_component.py index a19768a3dc..0456bfd462 100644 --- a/tests/development/test_base_component.py +++ b/tests/development/test_base_component.py @@ -807,6 +807,19 @@ def setUp(self): ])], + ['optionalObjectWithExactAndNestedDescription', '\n'.join([ + + "dict containing keys 'color', 'fontSize', 'figure'.", + "Those keys have the following types:", + " - color (string; optional)", + " - fontSize (number; optional)", + " - figure (optional): Figure is a plotly graph object. figure has the following type: dict containing keys 'data', 'layout'.", # noqa: E501 + "Those keys have the following types:", + " - data (list; optional): data is a collection of traces", + " - layout (dict; optional): layout describes the rest of the figure" # noqa: E501 + + ])], + ['optionalAny', 'boolean | number | string | dict | list'], ['customProp', ''], From 46bb0e56d694d1817f39d9b343ec4103a95f516f Mon Sep 17 00:00:00 2001 From: Chris P Date: Tue, 16 Apr 2019 23:27:44 -0400 Subject: [PATCH 2/8] appease the pylint gods (_i'm not worthyyyy_) --- dash/development/_py_components_generation.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dash/development/_py_components_generation.py b/dash/development/_py_components_generation.py index 6a1c663011..760c73b2cf 100644 --- a/dash/development/_py_components_generation.py +++ b/dash/development/_py_components_generation.py @@ -446,7 +446,8 @@ def create_prop_docstring(prop_name, type_object, required, description, def map_js_to_py_types_prop_types(type_object): """Mapping from the PropTypes js type object to the Python type""" - shape_or_exact = lambda: 'dict containing keys {}.\n{}'.format( + def shape_or_exact(): + return 'dict containing keys {}.\n{}'.format( ', '.join( "'{}'".format(t) for t in list(type_object['value'].keys())), From 9844e1f4689ff3f31891d1e7a411ab55248aa9e4 Mon Sep 17 00:00:00 2001 From: Chris P Date: Tue, 16 Apr 2019 23:45:31 -0400 Subject: [PATCH 3/8] pylint & flake8 --- dash/development/_py_components_generation.py | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/dash/development/_py_components_generation.py b/dash/development/_py_components_generation.py index 760c73b2cf..66db6a12d6 100644 --- a/dash/development/_py_components_generation.py +++ b/dash/development/_py_components_generation.py @@ -448,19 +448,20 @@ def map_js_to_py_types_prop_types(type_object): def shape_or_exact(): return 'dict containing keys {}.\n{}'.format( - ', '.join( - "'{}'".format(t) - for t in list(type_object['value'].keys())), - 'Those keys have the following types:\n{}'.format( - '\n'.join( - create_prop_docstring( - prop_name=prop_name, - type_object=prop, - required=prop['required'], - description=prop.get('description', ''), - indent_num=1 - ) for prop_name, prop in - list(type_object['value'].items())))) + ', '.join( + "'{}'".format(t) for t in list(type_object['value'].keys()) + ), + 'Those keys have the following types:\n{}'.format( + '\n'.join( + create_prop_docstring( + prop_name=prop_name, + type_object=prop, + required=prop['required'], + description=prop.get('description', ''), + indent_num=1 + ) for prop_name, prop in + list(type_object['value'].items()))) + ) return dict( array=lambda: 'list', From dad656cb15e22469d7ac2d3861fff2c337265b7a Mon Sep 17 00:00:00 2001 From: Chris P Date: Tue, 16 Apr 2019 23:45:54 -0400 Subject: [PATCH 4/8] another test fix --- tests/development/test_base_component.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/development/test_base_component.py b/tests/development/test_base_component.py index 0456bfd462..a67be5ba44 100644 --- a/tests/development/test_base_component.py +++ b/tests/development/test_base_component.py @@ -900,6 +900,25 @@ def assert_docstring(assertEqual, docstring): " - layout (dict; optional): layout describes " "the rest of the figure", + "- optionalObjectWithExactAndNestedDescription (optional): . " + "optionalObjectWithExactAndNestedDescription has the " + "following type: dict containing keys " + "'color', 'fontSize', 'figure'.", + + "Those keys have the following types:", + " - color (string; optional)", + " - fontSize (number; optional)", + + " - figure (optional): Figure is a plotly graph object. " + "figure has the following type: dict containing " + "keys 'data', 'layout'.", + + "Those keys have the following types:", + " - data (list; optional): data is a collection of traces", + + " - layout (dict; optional): layout describes " + "the rest of the figure", + "- optionalAny (boolean | number | string | dict | " "list; optional)", From 171960cb476e99c2e490d69b9e3f73b6d8468277 Mon Sep 17 00:00:00 2001 From: Chris P Date: Wed, 17 Apr 2019 00:01:09 -0400 Subject: [PATCH 5/8] :see_no_evil: typo --- tests/development/metadata_test.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/development/metadata_test.json b/tests/development/metadata_test.json index 80a381f062..a15c266748 100644 --- a/tests/development/metadata_test.json +++ b/tests/development/metadata_test.json @@ -176,7 +176,7 @@ }, "optionalObjectWithExactAndNestedDescription": { "type": { - "name": "shape", + "name": "exact", "value": { "color": { "name": "string", From 8c8b403ea4c82b203a2b1a30a0539befa524244d Mon Sep 17 00:00:00 2001 From: Chris P Date: Wed, 17 Apr 2019 00:01:23 -0400 Subject: [PATCH 6/8] another test miss --- tests/development/test_base_component.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/development/test_base_component.py b/tests/development/test_base_component.py index a67be5ba44..5a498a9fa7 100644 --- a/tests/development/test_base_component.py +++ b/tests/development/test_base_component.py @@ -719,6 +719,7 @@ def test_call_signature(self): 'optionalArrayOf', 'optionalObjectOf', 'optionalObjectWithShapeAndNestedDescription', + 'optionalObjectWithExactAndNestedDescription', 'optionalAny', 'customProp', 'customArrayProp', From c8fd9b619f2064144372cdac4db5a54e1031d958 Mon Sep 17 00:00:00 2001 From: Chris P Date: Wed, 17 Apr 2019 00:56:22 -0400 Subject: [PATCH 7/8] alphabetical --- tests/development/metadata_test.json | 8 ++++---- tests/development/metadata_test.py | 4 ++-- tests/development/test_base_component.py | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/development/metadata_test.json b/tests/development/metadata_test.json index a15c266748..a65cad547a 100644 --- a/tests/development/metadata_test.json +++ b/tests/development/metadata_test.json @@ -137,9 +137,9 @@ "required": false, "description": "" }, - "optionalObjectWithShapeAndNestedDescription": { + "optionalObjectWithExactAndNestedDescription": { "type": { - "name": "shape", + "name": "exact", "value": { "color": { "name": "string", @@ -174,9 +174,9 @@ "required": false, "description": "" }, - "optionalObjectWithExactAndNestedDescription": { + "optionalObjectWithShapeAndNestedDescription": { "type": { - "name": "exact", + "name": "shape", "value": { "color": { "name": "string", diff --git a/tests/development/metadata_test.py b/tests/development/metadata_test.py index 2357485923..8b2b52970f 100644 --- a/tests/development/metadata_test.py +++ b/tests/development/metadata_test.py @@ -21,7 +21,7 @@ class Table(Component): - optionalUnion (string | number; optional) - optionalArrayOf (list; optional) - optionalObjectOf (dict with strings as keys and values of type number; optional) -- optionalObjectWithShapeAndNestedDescription (optional): . optionalObjectWithShapeAndNestedDescription has the following type: dict containing keys 'color', 'fontSize', 'figure'. +- optionalObjectWithExactAndNestedDescription (optional): . optionalObjectWithExactAndNestedDescription has the following type: dict containing keys 'color', 'fontSize', 'figure'. Those keys have the following types: - color (string; optional) - fontSize (number; optional) @@ -29,7 +29,7 @@ class Table(Component): Those keys have the following types: - data (list; optional): data is a collection of traces - layout (dict; optional): layout describes the rest of the figure -- optionalObjectWithExactAndNestedDescription (optional): . optionalObjectWithShapeAndNestedDescription has the following type: dict containing keys 'color', 'fontSize', 'figure'. +- optionalObjectWithShapeAndNestedDescription (optional): . optionalObjectWithShapeAndNestedDescription has the following type: dict containing keys 'color', 'fontSize', 'figure'. Those keys have the following types: - color (string; optional) - fontSize (number; optional) diff --git a/tests/development/test_base_component.py b/tests/development/test_base_component.py index 5a498a9fa7..254ead5006 100644 --- a/tests/development/test_base_component.py +++ b/tests/development/test_base_component.py @@ -718,8 +718,8 @@ def test_call_signature(self): 'optionalUnion', 'optionalArrayOf', 'optionalObjectOf', - 'optionalObjectWithShapeAndNestedDescription', 'optionalObjectWithExactAndNestedDescription', + 'optionalObjectWithShapeAndNestedDescription', 'optionalAny', 'customProp', 'customArrayProp', @@ -795,7 +795,7 @@ def setUp(self): ['optionalObjectOf', 'dict with strings as keys and values of type number'], - ['optionalObjectWithShapeAndNestedDescription', '\n'.join([ + ['optionalObjectWithExactAndNestedDescription', '\n'.join([ "dict containing keys 'color', 'fontSize', 'figure'.", "Those keys have the following types:", @@ -808,7 +808,7 @@ def setUp(self): ])], - ['optionalObjectWithExactAndNestedDescription', '\n'.join([ + ['optionalObjectWithShapeAndNestedDescription', '\n'.join([ "dict containing keys 'color', 'fontSize', 'figure'.", "Those keys have the following types:", @@ -882,8 +882,8 @@ def assert_docstring(assertEqual, docstring): "- optionalObjectOf (dict with strings as keys and values " "of type number; optional)", - "- optionalObjectWithShapeAndNestedDescription (optional): . " - "optionalObjectWithShapeAndNestedDescription has the " + "- optionalObjectWithExactAndNestedDescription (optional): . " + "optionalObjectWithExactAndNestedDescription has the " "following type: dict containing keys " "'color', 'fontSize', 'figure'.", @@ -901,8 +901,8 @@ def assert_docstring(assertEqual, docstring): " - layout (dict; optional): layout describes " "the rest of the figure", - "- optionalObjectWithExactAndNestedDescription (optional): . " - "optionalObjectWithExactAndNestedDescription has the " + "- optionalObjectWithShapeAndNestedDescription (optional): . " + "optionalObjectWithShapeAndNestedDescription has the " "following type: dict containing keys " "'color', 'fontSize', 'figure'.", From dcc9b4aa985abca2465b98d9ad0b44811702ca23 Mon Sep 17 00:00:00 2001 From: Chris P Date: Wed, 17 Apr 2019 01:12:06 -0400 Subject: [PATCH 8/8] final 2 test fixes --- tests/development/metadata_test.py | 6 +++--- tests/development/test_base_component.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/development/metadata_test.py b/tests/development/metadata_test.py index 8b2b52970f..785feae6bf 100644 --- a/tests/development/metadata_test.py +++ b/tests/development/metadata_test.py @@ -45,12 +45,12 @@ class Table(Component): - in (string; optional) - id (string; optional)""" @_explicitize_args - def __init__(self, children=None, optionalArray=Component.UNDEFINED, optionalBool=Component.UNDEFINED, optionalFunc=Component.UNDEFINED, optionalNumber=Component.UNDEFINED, optionalObject=Component.UNDEFINED, optionalString=Component.UNDEFINED, optionalSymbol=Component.UNDEFINED, optionalNode=Component.UNDEFINED, optionalElement=Component.UNDEFINED, optionalMessage=Component.UNDEFINED, optionalEnum=Component.UNDEFINED, optionalUnion=Component.UNDEFINED, optionalArrayOf=Component.UNDEFINED, optionalObjectOf=Component.UNDEFINED, optionalObjectWithShapeAndNestedDescription=Component.UNDEFINED, optionalAny=Component.UNDEFINED, customProp=Component.UNDEFINED, customArrayProp=Component.UNDEFINED, id=Component.UNDEFINED, **kwargs): - self._prop_names = ['children', 'optionalArray', 'optionalBool', 'optionalNumber', 'optionalObject', 'optionalString', 'optionalNode', 'optionalElement', 'optionalEnum', 'optionalUnion', 'optionalArrayOf', 'optionalObjectOf', 'optionalObjectWithShapeAndNestedDescription', 'optionalAny', 'customProp', 'customArrayProp', 'data-*', 'aria-*', 'in', 'id'] + def __init__(self, children=None, optionalArray=Component.UNDEFINED, optionalBool=Component.UNDEFINED, optionalFunc=Component.UNDEFINED, optionalNumber=Component.UNDEFINED, optionalObject=Component.UNDEFINED, optionalString=Component.UNDEFINED, optionalSymbol=Component.UNDEFINED, optionalNode=Component.UNDEFINED, optionalElement=Component.UNDEFINED, optionalMessage=Component.UNDEFINED, optionalEnum=Component.UNDEFINED, optionalUnion=Component.UNDEFINED, optionalArrayOf=Component.UNDEFINED, optionalObjectOf=Component.UNDEFINED, optionalObjectWithExactAndNestedDescription=Component.UNDEFINED, optionalObjectWithShapeAndNestedDescription=Component.UNDEFINED, optionalAny=Component.UNDEFINED, customProp=Component.UNDEFINED, customArrayProp=Component.UNDEFINED, id=Component.UNDEFINED, **kwargs): + self._prop_names = ['children', 'optionalArray', 'optionalBool', 'optionalNumber', 'optionalObject', 'optionalString', 'optionalNode', 'optionalElement', 'optionalEnum', 'optionalUnion', 'optionalArrayOf', 'optionalObjectOf', 'optionalObjectWithExactAndNestedDescription', 'optionalObjectWithShapeAndNestedDescription', 'optionalAny', 'customProp', 'customArrayProp', 'data-*', 'aria-*', 'in', 'id'] self._type = 'Table' self._namespace = 'TableComponents' self._valid_wildcard_attributes = ['data-', 'aria-'] - self.available_properties = ['children', 'optionalArray', 'optionalBool', 'optionalNumber', 'optionalObject', 'optionalString', 'optionalNode', 'optionalElement', 'optionalEnum', 'optionalUnion', 'optionalArrayOf', 'optionalObjectOf', 'optionalObjectWithShapeAndNestedDescription', 'optionalAny', 'customProp', 'customArrayProp', 'data-*', 'aria-*', 'in', 'id'] + self.available_properties = ['children', 'optionalArray', 'optionalBool', 'optionalNumber', 'optionalObject', 'optionalString', 'optionalNode', 'optionalElement', 'optionalEnum', 'optionalUnion', 'optionalArrayOf', 'optionalObjectOf', 'optionalObjectWithExactAndNestedDescription', 'optionalObjectWithShapeAndNestedDescription', 'optionalAny', 'customProp', 'customArrayProp', 'data-*', 'aria-*', 'in', 'id'] self.available_wildcard_properties = ['data-', 'aria-'] _explicit_args = kwargs.pop('_explicit_args') diff --git a/tests/development/test_base_component.py b/tests/development/test_base_component.py index 254ead5006..690e721d14 100644 --- a/tests/development/test_base_component.py +++ b/tests/development/test_base_component.py @@ -738,7 +738,7 @@ def test_call_signature(self): if hasattr(inspect, 'signature'): self.assertEqual( [str(x) for x in inspect.getargspec(__init__func).defaults], - ['None'] + ['undefined'] * 19 + ['None'] + ['undefined'] * 20 ) def test_required_props(self):