Ticket #1795: cdef-coverage.patch

File cdef-coverage.patch, 5.6 KB (added by roed, 14 years ago)

Adds cdef, cpdef support to sage-coverage

  • sage-coverage

    # HG changeset patch
    # User David Roe <roed@math.harvard.edu>
    # Date 1200506400 18000
    # Node ID d6493bcd84a594f460cbfb3cb00594dce1471435
    # Parent  3eafd4b77abd10206f667ba67f8c4ed97ab428b4
    Added support for cdef'd and cpdef'd functions, classes and cdef'd classes to sage-coverage.
    
    diff -r 3eafd4b77abd -r d6493bcd84a5 sage-coverage
    a b def functions_without_doctests(file): 
    1717    possibly_wrong = []
    1818    while True:
    1919        i = file.find('def ')
    20         if i == -1:
     20        ii = file.find('class ')
     21        # cdef extern blocks really screw us up, so we have to get rid of them.
     22        iii = file.find('cdef extern')
     23        if iii != -1 and iii < i and iii < ii:
     24            file = file[file.find("\n", iii):]
     25            while file.startswith(("\n    ","\n\n","\n \n","\n  \n", "\n   \n")):
     26                file = file[file.find("\n", 1):]
     27            continue
     28        if i == -1 and ii == -1:
    2129            break
     30        if ii != -1 and ii <= i:
     31            i = ii
    2232        j = file[i:].find(':')
    2333        if j == -1:
    2434            break
    def functions_without_doctests(file): 
    3141                file = file[j:]
    3242                continue
    3343
    34         function_name = ' '.join(file[i:j].lstrip('def').split())
    35         bare_function_name = function_name[:function_name.find("(")]
     44        if i == ii:
     45            function_name = ' '.join(file[i:j].lstrip('class').split())
     46        else:
     47            function_name = ' '.join(file[i:j].lstrip('def').split())
     48        if function_name.find("(") == -1 and (i != ii and function_name[:5] != 'class'):
     49            file = file[i+3:]
     50            continue
     51        bare_function_name = function_name[:function_name.find("(")].rstrip()
     52        # a cdef'd or cpdef'd function may or may not indicate the type of its return value
     53        # if it does, then function name and bare function name have that return
     54        # value type at the beginning.
     55        # Functions cannot have spaces in their names, so we find the last space and strip off what
     56        # comes before that.
     57        # We also have to differentiate between cdef'd functions and cdef's of variables.
     58        # We do so by checking that there are two or three entries in bare_function_name.split()
     59        if (i > 0 and file[i-1] == 'e'):
     60            #print "e skipping"
     61            file = file[i+3:]
     62            continue
     63        elif (i > 0 and file[i-1] == 'c'):
     64            split = bare_function_name.split()
     65            if len(split) > 2:
     66                #print "c skipping, len = %s, beginning = %s"%(len(split), split[:3])
     67                file = file[i+3:]
     68                continue
     69            elif len(split) > 0:
     70                if split[0] == 'class': # we don't strip class off of cdef class classname
     71                    # but it might be a forward declaration...
     72                    if bare_function_name[bare_function_name.find(")") + 1] != ":":
     73                        file = file[i + 9:]
     74                        continue
     75                else:
     76                    #print "c pre bare_function_name = %s\n\nc pre function_name = %s"%(bare_function_name, function_name)
     77                    last_space = len(bare_function_name) - len(split[-1])
     78                    bare_function_name = bare_function_name[last_space:]
     79                    function_name = function_name[last_space:]
     80                if bare_function_name == "*" or bare_function_name == "void":
     81                    # someone's pulling the wool over the eyes of cython.  We won't mess with such a person.
     82                    file = file[i + 3:]
     83                    continue                   
     84                #print "c post bare_function_name = %s\nc post function_name = %s\n"%(bare_function_name, function_name)
     85        elif (i > 1 and file[i-2:i] == 'cp'):
     86            #print "cp pre bare_function_name = %s\n\ncp pre function_name = %s"%(bare_function_name, function_name)
     87            last_space = len(bare_function_name) - len(bare_function_name.split()[-1])
     88            bare_function_name = bare_function_name[last_space:]
     89            function_name = function_name[last_space:]
     90            #print "cp post bare_function_name = %s\ncp post function_name = %s\n"%(bare_function_name, function_name)
     91        elif i == ii: # we're checking a class
     92            if len(bare_function_name.split()) > 1:
     93                file = file[i + 5:]
     94                continue
     95            #else:
     96            #    print "class post bare_function_name = %s\nc post function_name = %s\n"%(bare_function_name, function_name)
    3697
    37         if i > 0 and file[i-1] in ['c', 'e']: # and ('\n' in file[i:j] or '(' not in file[i:j]):
    38             file = file[i+10:]
    39             continue
    4098        skip_this = False
    4199        for skip in ['__dealloc__', '__new__']:
    42100            if skip in function_name:
    def functions_without_doctests(file): 
    70128                    tests.append(function_name)
    71129                else:
    72130                    good.append(function_name)
    73                     if not (bare_function_name[0:2] == '__' and
    74                         bare_function_name[-2:] == '__'):
     131                    # we don't check for the file name in cdef'd functions or in __blah__ functions
     132                    if not ((len(bare_function_name) > 4 and bare_function_name[0:2] == '__' and
     133                        bare_function_name[-2:] == '__') or (i > 0 and file[i-1] == 'c')):
    75134                        d = file[q0:q1].find(bare_function_name)
    76135                        e = file[q0:q1].find('indirect doctest')
    77136                        if d == -1 and e == -1: