diff options
author | David Malcolm <dmalcolm@redhat.com> | 2009-11-14 12:37:11 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2009-11-14 12:37:11 -0500 |
commit | 190351e18b307ae4fef728208fa973e2c8ffd018 (patch) | |
tree | 78cfc8376eff838efc26f42d30fab8d21bcb2e81 | |
parent | a35aa12a916f0ba167b109e709538e4289141e58 (diff) | |
download | check-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.py | 51 |
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: |