summaryrefslogtreecommitdiffstats
path: root/validate.py
blob: 5827ddfaa3177afad1bc5447825e291fb62f1c26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
"""
Hooks for validating CPython extension source code
"""
def get_types(strfmt):
    """
    Generate a list of C type names from a PyArg_ParseTuple format string
    """
    result = []
    i = 0
    while i < len(strfmt):
        c = strfmt[i]
        if c == 'i':
            result.append('int *')
        if c in [':', ';']:
            break
        i += 1
    return result

class CExtensionError(Exception):
    # Base class for errors discovered by static analysis in C extension code
    pass

class WrongNumberOfVars(CExtensionError):
    pass

class NotEnoughVars(WrongNumberOfVars):
    pass

class TooManyVars(WrongNumberOfVars):
    pass

class MismatchingType(WrongNumberOfVars):
    pass

def validate_types(format_string, actual_types):
    exp_types = get_types(format_string)
    if len(actual_types) < len(exp_types):
        raise NotEnoughVars(actual_types, exp_types)
    if len(actual_types) > len(exp_types):
        raise TooManyVars(actual_types, exp_types)
    for exp, actual in zip(exp_types, actual_types):
        if exp != actual:
            raise MismatchingType(exp, actual)