1
1
from collections import OrderedDict
2
2
import copy
3
3
import os
4
+ import typing
4
5
from textwrap import fill , dedent
5
6
6
7
from dash .development .base_component import _explicitize_args
7
8
from dash .exceptions import NonExistentEventException
8
9
from ._all_keywords import python_keywords
9
10
from ._collect_nodes import collect_nodes , filter_base_nodes
11
+ from ._py_prop_typing import get_prop_typing
10
12
from .base_component import Component
11
13
12
14
13
- # pylint: disable=unused-argument,too-many-locals
15
+ # pylint: disable=unused-argument,too-many-locals,too-many-branches
14
16
def generate_class_string (
15
17
typename ,
16
18
props ,
@@ -55,7 +57,10 @@ def generate_class_string(
55
57
_namespace = '{namespace}'
56
58
_type = '{typename}'
57
59
@_explicitize_args
58
- def __init__(self, {default_argtext}):
60
+ def __init__(
61
+ self,
62
+ {default_argtext}
63
+ ):
59
64
self._prop_names = {list_of_valid_keys}
60
65
self._valid_wildcard_attributes =\
61
66
{list_of_valid_wildcard_attr_prefixes}
@@ -94,7 +99,7 @@ def __init__(self, {default_argtext}):
94
99
prop_keys = list (props .keys ())
95
100
if "children" in props and "children" in list_of_valid_keys :
96
101
prop_keys .remove ("children" )
97
- default_argtext = "children=None, "
102
+ default_argtext = "children=None,"
98
103
args = "{k: _locals[k] for k in _explicit_args if k != 'children'}"
99
104
argtext = "children=children, **args"
100
105
else :
@@ -118,15 +123,33 @@ def __init__(self, {default_argtext}):
118
123
raise TypeError('Required argument children was not specified.')
119
124
"""
120
125
121
- default_arglist = [
122
- (
123
- f"{ p :s} =Component.REQUIRED"
124
- if props [p ]["required" ]
125
- else f"{ p :s} =Component.UNDEFINED"
126
- )
127
- for p in prop_keys
128
- if not p .endswith ("-*" ) and p not in python_keywords and p != "setProps"
129
- ]
126
+ default_arglist = []
127
+
128
+ for prop_key in prop_keys :
129
+ prop = props [prop_key ]
130
+ if (
131
+ prop_key .endswith ("-*" )
132
+ or prop_key in python_keywords
133
+ or prop_key == "setProps"
134
+ ):
135
+ continue
136
+ required = prop .get ("required" )
137
+ type_info = prop .get ("type" )
138
+
139
+ if not type_info :
140
+ print (f"Invalid prop type: { prop_key } " )
141
+ continue
142
+
143
+ type_name = type_info .get ("name" )
144
+
145
+ typed = get_prop_typing (type_name , type_info )
146
+
147
+ if required :
148
+ arg_value = f"{ prop_key } : { typed } = Component.REQUIRED"
149
+ else :
150
+ arg_value = f"{ prop_key } : { typed } = Component.UNDEFINED"
151
+
152
+ default_arglist .append (arg_value )
130
153
131
154
if max_props :
132
155
final_max_props = max_props - (1 if "children" in props else 0 )
@@ -139,7 +162,7 @@ def __init__(self, {default_argtext}):
139
162
"they may still be used as keyword arguments."
140
163
)
141
164
142
- default_argtext += ", " .join (default_arglist + ["**kwargs" ])
165
+ default_argtext += ",\n " .join (default_arglist + ["**kwargs" ])
143
166
nodes = collect_nodes ({k : v for k , v in props .items () if k != "children" })
144
167
145
168
return dedent (
@@ -181,8 +204,9 @@ def generate_class_file(
181
204
"""
182
205
import_string = (
183
206
"# AUTO GENERATED FILE - DO NOT EDIT\n \n "
184
- + "from dash.development.base_component import "
185
- + "Component, _explicitize_args\n \n \n "
207
+ "import typing # noqa: F401\n "
208
+ "from dash.development.base_component import "
209
+ "Component, _explicitize_args\n \n \n "
186
210
)
187
211
188
212
class_string = generate_class_string (
@@ -242,7 +266,11 @@ def generate_class(
242
266
string = generate_class_string (
243
267
typename , props , description , namespace , prop_reorder_exceptions
244
268
)
245
- scope = {"Component" : Component , "_explicitize_args" : _explicitize_args }
269
+ scope = {
270
+ "Component" : Component ,
271
+ "_explicitize_args" : _explicitize_args ,
272
+ "typing" : typing ,
273
+ }
246
274
# pylint: disable=exec-used
247
275
exec (string , scope )
248
276
result = scope [typename ]
0 commit comments