Skip to content

Commit 1cbfaa1

Browse files
author
Burak Yigit Kaya
committed
Update interfaces.json and refactor type info processing a bit
1 parent ddd6513 commit 1cbfaa1

File tree

3 files changed

+35
-31
lines changed

3 files changed

+35
-31
lines changed

phabricator/__init__.py

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@
103103
'type': string_types,
104104
}
105105

106-
STR_RE = re.compile(r'([a-zA-Z_]+)')
106+
TYPE_INFO_COMMENT_RE = re.compile(r'\s*\([^)]+\)\s*|,.+$')
107+
TYPE_INFO_SPLITTER_RE = re.compile(r'(\w+(?:<.+>)?)(?:\s+|$)')
108+
TYPE_INFO_RE = re.compile(r'(\w+)(<[^>]+>)?(?:\s+|$)')
107109

108110

109111
def map_param_type(param_type):
@@ -112,18 +114,20 @@ def map_param_type(param_type):
112114
This requires a bit of logic since this isn't standardized.
113115
If a type doesn't map, assume str
114116
"""
115-
m = STR_RE.match(param_type)
116-
main_type = m.group(0)
117+
main_type, sub_type = TYPE_INFO_RE.match(param_type).groups()
117118

118119
if main_type in ('list', 'array'):
119-
info = param_type.replace(' ', '').split('<', 1)
120-
121120
# Handle no sub-type: "required list"
122-
sub_type = info[1] if len(info) > 1 else 'str'
121+
if sub_type is not None:
122+
sub_type = sub_type.strip()
123+
124+
if not sub_type:
125+
sub_type = 'str'
123126

124127
# Handle list of pairs: "optional list<pair<callsign, path>>"
125-
sub_match = STR_RE.match(sub_type)
126-
sub_type = sub_match.group(0).lower()
128+
sub_match = TYPE_INFO_RE.match(sub_type)
129+
if sub_match:
130+
sub_type = sub_match.group(0).lower()
127131

128132
return [PARAM_TYPE_MAP.setdefault(sub_type, string_types)]
129133

@@ -151,25 +155,23 @@ def parse_interfaces(interfaces):
151155
method['required'] = {}
152156

153157
for name, type_info in iteritems(dict(d['params'])):
158+
# Set the defaults
159+
optionality = 'required'
160+
param_type = 'string'
161+
154162
# Usually in the format: <optionality> <param_type>
155-
info_pieces = type_info.split(' ', 1)
156-
157-
# If optionality isn't specified, assume required
158-
if info_pieces[0] not in ('optional', 'required'):
159-
optionality = 'required'
160-
param_type = info_pieces[0]
161-
# Just make an optional string for "ignored" params
162-
elif info_pieces[0] == 'ignored':
163-
optionality = 'optional'
164-
param_type = 'string'
165-
else:
166-
optionality = info_pieces[0]
167-
param_type = info_pieces[1]
168-
169-
# This isn't validated by the client
170-
if param_type.startswith('nonempty'):
171-
optionality = 'required'
172-
param_type = param_type[9:]
163+
type_info = TYPE_INFO_COMMENT_RE.sub('', type_info)
164+
info_pieces = TYPE_INFO_SPLITTER_RE.findall(type_info)
165+
for info_piece in info_pieces:
166+
if info_piece in ('optional', 'required'):
167+
optionality = info_piece
168+
elif info_piece == 'ignored':
169+
optionality = 'optional'
170+
param_type = 'string'
171+
elif info_piece == 'nonempty':
172+
optionality = 'required'
173+
else:
174+
param_type = info_piece
173175

174176
method[optionality][name] = map_param_type(param_type)
175177

@@ -238,8 +240,12 @@ def _request(self, **kwargs):
238240

239241
def validate_kwarg(key, target):
240242
# Always allow list
241-
if isinstance(key, list):
242-
return all([validate_kwarg(x, target[0]) for x in key])
243+
if isinstance(target, list):
244+
return (
245+
isinstance(key, (list, tuple, set)) and
246+
all(validate_kwarg(x, target[0]) for x in key)
247+
)
248+
243249
return isinstance(key, tuple(target) if isinstance(target, list) else target)
244250

245251
for key, val in resource.get('required', {}).items():

0 commit comments

Comments
 (0)