summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2009-11-14 12:37:11 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2009-11-14 12:37:11 -0500
commit190351e18b307ae4fef728208fa973e2c8ffd018 (patch)
tree78cfc8376eff838efc26f42d30fab8d21bcb2e81
parenta35aa12a916f0ba167b109e709538e4289141e58 (diff)
downloadcheck-cpython-190351e18b307ae4fef728208fa973e2c8ffd018.tar.gz
check-cpython-190351e18b307ae4fef728208fa973e2c8ffd018.tar.xz
check-cpython-190351e18b307ae4fef728208fa973e2c8ffd018.zip
Report the format string when reporting on errors
-rw-r--r--validate.py51
1 files changed, 30 insertions, 21 deletions
diff --git a/validate.py b/validate.py
index ebe5977..ced4611 100644
--- a/validate.py
+++ b/validate.py
@@ -13,26 +13,32 @@ class CExtensionError(Exception):
self._get_desc())
def _get_desc(self):
+ # Hook for additional descriptive text about the error
raise NotImplementedError
-class UnknownFormatChar(CExtensionError):
- def __init__(self, location, ch):
+class FormatStringError(CExtensionError):
+ def __init__(self, location, format_string):
CExtensionError.__init__(self, location)
+ self.format_string = format_string
+
+class UnknownFormatChar(FormatStringError):
+ def __init__(self, location, format_string, ch):
+ FormatStringError.__init__(self, location, format_string)
self.ch = ch
def _get_desc(self):
- return "unknown format char: '%s'" % self.ch
+ return "unknown format char in \"%s\": '%s'" % (self.format_string, self.ch)
class UnhandledCode(UnknownFormatChar):
def _get_desc(self):
- return "unhandled format code: '%s' (FIXME)" % self.ch
+ return "unhandled format code in \"%s\": '%s' (FIXME)" % (self.format_string, self.ch)
def get_types(location, strfmt):
"""
Generate a list of C type names from a PyArg_ParseTuple format string
Compare to Python/getargs.c:vgetargs1
- FIXME: only implements a very small subset of the various cases; no tuples, etc
+ FIXME: only implements a subset of the various cases; no tuples yet etc
"""
result = []
i = 0
@@ -44,7 +50,7 @@ def get_types(location, strfmt):
else:
next = None
- # FIXME: '(', ')'
+ # FIXME: '(', ')' tuple support
if c in [':', ';']:
break
@@ -99,7 +105,7 @@ def get_types(location, strfmt):
result += ['PyTypeObject *', 'PyObject * *']
i += 1
elif next == '?':
- raise UnhandledCode(location, c + next) # FIXME
+ raise UnhandledCode(location, strfmt, c + next) # FIXME
elif next == '&':
# FIXME: can't really handle this case as is, fixing for fcntmodule.c
result += ['int ( PyObject * object , int * target )', # converter
@@ -108,25 +114,26 @@ def get_types(location, strfmt):
else:
result.append('PyObject * *')
elif c == 'w':
- raise UnhandledCode(location, c) # FIXME
+ raise UnhandledCode(location, strfmt, c) # FIXME
elif c == 't':
if next == '#':
result += ['char * *', 'int *']
i += 1
else:
- raise UnknownFormatChar(location, c)
+ raise UnknownFormatChar(location, strfmt, c)
return result
-class WrongNumberOfVars(CExtensionError):
- def __init__(self, location, exp_types, actual_types):
- CExtensionError.__init__(self, location)
+class WrongNumberOfVars(FormatStringError):
+ def __init__(self, location, format_string, exp_types, actual_types):
+ FormatStringError.__init__(self, location, format_string)
self.exp_types = exp_types
self.actual_types = actual_types
class NotEnoughVars(WrongNumberOfVars):
def _get_desc(self):
- return 'Not enough arguments: expected %i (%s), but got %i (%s)' % (
+ return 'Not enough arguments in "%s" : expected %i (%s), but got %i (%s)' % (
+ self.format_string,
len(self.exp_types),
self.exp_types,
len(self.actual_types),
@@ -134,22 +141,24 @@ class NotEnoughVars(WrongNumberOfVars):
class TooManyVars(WrongNumberOfVars):
def _get_desc(self):
- return 'Too many arguments: expected %i (%s), but got %i (%s)' % (
+ return 'Too many arguments in "%s": expected %i (%s), but got %i (%s)' % (
+ self.format_string,
len(self.exp_types),
self.exp_types,
len(self.actual_types),
self.actual_types)
-class MismatchingType(CExtensionError):
- def __init__(self, location, arg_num, exp_type, actual_type):
- super(self.__class__, self).__init__(location)
+class MismatchingType(FormatStringError):
+ def __init__(self, location, format_string, arg_num, exp_type, actual_type):
+ super(self.__class__, self).__init__(location, format_string)
self.arg_num = arg_num
self.exp_type = exp_type
self.actual_type = actual_type
def _get_desc(self):
- return 'Mismatching type of argument %i: expected "%s" but got "%s"' % (
+ return 'Mismatching type of argument %i in "%s": expected "%s" but got "%s"' % (
self.arg_num,
+ self.format_string,
self.exp_type,
self.actual_type)
@@ -176,12 +185,12 @@ def validate_types(location, format_string, actual_types):
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, exp_types, actual_types)
+ raise NotEnoughVars(location, format_string, exp_types, actual_types)
if len(actual_types) > len(exp_types):
- raise TooManyVars(location, exp_types, actual_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, i+1, exp, actual)
+ raise MismatchingType(location, format_string, i+1, exp, actual)
except CExtensionError, err:
print err
if False: