Skip to content

Commit 90040af

Browse files
apaszkesoumith
authored andcommitted
Fix cwrap option filtering
1 parent 59bc96b commit 90040af

File tree

3 files changed

+39
-31
lines changed

3 files changed

+39
-31
lines changed

tools/cwrap/plugins/KwargsPlugin.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
class KwargsPlugin(CWrapPlugin):
55

66
ACCESSOR_TEMPLATE = Template('(__tuplecount > $idx ? PyTuple_GET_ITEM(args, $idx) : __kw_$name)')
7+
KWARG_ONLY_ACCESSOR_TEMPLATE = Template('__kw_$name')
78
CHECK_TEMPLATE = Template('(__tuplecount > $idx || __kw_$name) && $code')
9+
KWARG_ONLY_CHECK_TEMPLATE = Template('__kw_$name && $code')
810
WRAPPER_TEMPLATE = Template("""
911
$declarations
1012
if (kwargs) {
@@ -24,13 +26,18 @@ def process_declarations(self, declarations):
2426
return declarations
2527

2628
def get_arg_accessor(self, arg, option):
27-
if not arg.get('no_kwargs'):
28-
return self.ACCESSOR_TEMPLATE.substitute(idx=arg['idx'], name=arg['name'])
29+
if arg.get('no_kwargs'):
30+
return
31+
if arg.get('kwarg_only'):
32+
return self.KWARG_ONLY_ACCESSOR_TEMPLATE.substitute(name=arg['name'])
33+
return self.ACCESSOR_TEMPLATE.substitute(idx=arg['idx'], name=arg['name'])
2934

3035
def process_single_check(self, code, arg, arg_accessor):
31-
if not arg.get('no_kwargs'):
32-
return self.CHECK_TEMPLATE.substitute(idx=arg['idx'], name=arg['name'], code=code)
33-
return code
36+
if arg.get('no_kwargs'):
37+
return code
38+
if arg.get('kwarg_only'):
39+
return self.KWARG_ONLY_CHECK_TEMPLATE.substitute(name=arg['name'], code=code)
40+
return self.CHECK_TEMPLATE.substitute(idx=arg['idx'], name=arg['name'], code=code)
3441

3542
def process_wrapper(self, code, declaration):
3643
if declaration.get('no_kwargs'):

tools/cwrap/plugins/OptionalArguments.py

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,37 @@ def process_declarations(self, declarations):
2222
# PyYAML interprets NULL as None...
2323
arg['name'] = 'NULL' if arg['default'] is None else arg['default']
2424
new_options.append(option_copy)
25-
declaration['options'] = self.filter_unique_options(declaration['options'] + new_options)
25+
declaration['options'] = self.filter_unique_options(new_options)
2626
return declarations
2727

2828
def filter_unique_options(self, options):
29-
def signature(option):
30-
return '#'.join(arg['type'] for arg in option['arguments'] if not 'ignore_check' in arg or not arg['ignore_check'])
29+
def signature(option, kwarg_only_count):
30+
if kwarg_only_count == 0:
31+
kwarg_only_count = None
32+
else:
33+
kwarg_only_count = -kwarg_only_count
34+
arg_signature = '#'.join(
35+
arg['type']
36+
for arg in option['arguments'][:kwarg_only_count]
37+
if not arg.get('ignore_check'))
38+
if kwarg_only_count is None:
39+
return arg_signature
40+
kwarg_only_signature = '#'.join(
41+
arg['name'] + '#' + arg['type']
42+
for arg in option['arguments'][kwarg_only_count:]
43+
if not arg.get('ignore_check'))
44+
return arg_signature + "#-#" + kwarg_only_signature
3145
seen_signatures = set()
3246
unique = []
3347
for option in options:
34-
sig = signature(option)
35-
if sig not in seen_signatures:
36-
unique.append(option)
37-
seen_signatures.add(sig)
48+
for num_kwarg_only in range(0, len(option['arguments'])+1):
49+
sig = signature(option, num_kwarg_only)
50+
if sig not in seen_signatures:
51+
if num_kwarg_only > 0:
52+
for arg in option['arguments'][-num_kwarg_only:]:
53+
arg['kwarg_only'] = True
54+
unique.append(option)
55+
seen_signatures.add(sig)
56+
break
3857
return unique
3958

tools/cwrap/plugins/THPPlugin.py

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ def generate_out_options(self, declaration):
291291
arg['no_kwargs'] = True
292292
arg['no_idx'] = True
293293
new_options.append(option_copy)
294-
declaration['options'] = self.filter_unique_options(new_options)
294+
declaration['options'] = new_options
295295

296296
def process_declarations(self, declarations):
297297
new_declarations = []
@@ -344,9 +344,6 @@ def has_output_args(declaration):
344344
for arg in option['arguments']:
345345
if arg['name'] == 'self':
346346
arg['ignore_check'] = True
347-
# TODO: we can probably allow duplicate signatures once we implement
348-
# keyword arguments
349-
declaration['options'] = self.filter_unique_options(declaration['options'])
350347

351348

352349
declarations = [d for d in declarations if not d.get('only_stateless', False)]
@@ -368,21 +365,6 @@ def make_stateless(self, declaration):
368365
arg['name'] = 'source'
369366
return declaration
370367

371-
def filter_unique_options(self, options):
372-
def signature(option):
373-
return '#'.join(
374-
arg['type'] + str(arg.get('output', False))
375-
for arg in option['arguments']
376-
if not arg.get('ignore_check'))
377-
seen_signatures = set()
378-
unique = []
379-
for option in options:
380-
sig = signature(option)
381-
if sig not in seen_signatures:
382-
unique.append(option)
383-
seen_signatures.add(sig)
384-
return unique
385-
386368
def declare_methods(self, stateless, sparse):
387369
tensor_methods = ''
388370
for declaration in (self.declarations if not stateless else self.stateless_declarations):

0 commit comments

Comments
 (0)