diff options
author | David Malcolm <dmalcolm@redhat.com> | 2009-11-17 14:47:25 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2009-11-17 14:47:25 -0500 |
commit | 28a01c0fd593df0f64d06b4205c5a93b8068ea51 (patch) | |
tree | 36eddd2ca00184c26d86af817f5ab6adceba69f5 /validate.py | |
parent | 254f88a995334acfe04b5774a6be048a365cdb86 (diff) | |
download | check-cpython-28a01c0fd593df0f64d06b4205c5a93b8068ea51.tar.gz check-cpython-28a01c0fd593df0f64d06b4205c5a93b8068ea51.tar.xz check-cpython-28a01c0fd593df0f64d06b4205c5a93b8068ea51.zip |
Generalize variadic function handling
Avoid having to manually write a rule for each number of variable arguments to PyArg_ParseTuple etc by capturing each argument in turn (with lists of prior and subsequent expressions). The downside is that the rule is invoked once per argument at each callsite, with knowledge of only one type, rather than invoking it once per callsite with knowledge of all arguments.
Thanks to Julia Lawall and Nicolas Palix
Diffstat (limited to 'validate.py')
-rw-r--r-- | validate.py | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/validate.py b/validate.py index 786d7c0..6d50921 100644 --- a/validate.py +++ b/validate.py @@ -141,28 +141,26 @@ def get_types(location, strfmt): class WrongNumberOfVars(FormatStringError): - def __init__(self, location, format_string, exp_types, actual_types): + def __init__(self, location, format_string, exp_types, num_args): FormatStringError.__init__(self, location, format_string) self.exp_types = exp_types - self.actual_types = actual_types + self.num_args = num_args class NotEnoughVars(WrongNumberOfVars): def _get_desc(self): - return 'Not enough arguments in "%s" : expected %i (%s), but got %i (%s)' % ( + return 'Not enough arguments in "%s" : expected %i (%s), but got %i' % ( self.format_string, len(self.exp_types), self.exp_types, - len(self.actual_types), - self.actual_types) + self.num_args) class TooManyVars(WrongNumberOfVars): def _get_desc(self): - return 'Too many arguments in "%s": expected %i (%s), but got %i (%s)' % ( + return 'Too many arguments in "%s": expected %i (%s), but got %i' % ( self.format_string, len(self.exp_types), self.exp_types, - len(self.actual_types), - self.actual_types) + self.num_args) class MismatchingType(FormatStringError): def __init__(self, location, format_string, arg_num, exp_type, actual_type): @@ -194,24 +192,33 @@ def type_equality(t1, t2): return False -def validate_types(location, format_string, actual_types): +def validate_type(location, format_string, index, actual_num_args, actual_type): if False: - print 'validate_types(%s, %s, %s)' % ( - repr(location), repr(format_string), repr(actual_types)) + print 'validate_types(%s, %s, %s, %s, %s)' % ( + repr(location), + repr(format_string), + repr(index), + repr(actual_num_args), + repr(actual_type)) + try: exp_types = get_types(location, format_string[1:-1]) # strip leading and trailing " chars - if len(actual_types) < len(exp_types): - raise NotEnoughVars(location, format_string, exp_types, actual_types) - if len(actual_types) > len(exp_types): - raise TooManyVars(location, format_string, exp_types, actual_types) - for i, (exp, actual) in enumerate(zip(exp_types, actual_types)): - if not type_equality(exp, actual): - raise MismatchingType(location, format_string, i+1, exp, actual) + if actual_num_args < len(exp_types): + raise NotEnoughVars(location, format_string, exp_types, actual_num_args) + if actual_num_args > len(exp_types): + raise TooManyVars(location, format_string, exp_types, actual_num_args) + exp_type = exp_types[index] + if not type_equality(exp_type, actual_type): + raise MismatchingType(location, format_string, index+1, exp_type, actual_type) except CExtensionError, err: print err if False: - print 'validate_types(%s, %s, %s)' % ( - repr(location), repr(format_string), repr(actual_types)) + print 'validate_types(%s, %s, %s, %s, %s)' % ( + repr(location), + repr(format_string), + repr(index), + repr(actual_num_args), + repr(actual_type)) return 1 return 0 |