summaryrefslogtreecommitdiffstats
path: root/validate.py
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2009-11-17 14:47:25 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2009-11-17 14:47:25 -0500
commit28a01c0fd593df0f64d06b4205c5a93b8068ea51 (patch)
tree36eddd2ca00184c26d86af817f5ab6adceba69f5 /validate.py
parent254f88a995334acfe04b5774a6be048a365cdb86 (diff)
downloadcheck-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.py47
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