[Pyrex] (no subject)

Patrick Maupin pmaupin at speakeasy.net
Sun Apr 25 02:16:59 CEST 2004


I use Pyrex a lot for speeding up Python (rather than interfacing to external libraries).  For this use, I find it easiest to develop in pure Python, then switch over to Pyrex at some point.

To make a long story short, I decided I needed a very simple version of the C preprocessor to be able to generate both Pyrex and Python versions from the same source file.  I looked around (though admittedly not too hard, because it didn't seem like too hard of a problem), didn't see what I wanted, so wrote a little script.

This script does two things:

1) It tries to automagically do the right thing with 'cdef' depending on context.  For my coding style, it does this pretty much all the time.  The right thing is either to strip the 'c' off of 'cdef', strip the 'c' off of cdef and add '(object)' right before ':' for classes, or strip the whole line with the 'cdef'.  If you use continuation lines a lot your mileage will certainly vary.

2) It allows '#if pyrex', '#if !pyrex', '#else', and '#endif' to control the output.

The script takes a single parameter, e.g. 'foo' and reads 'foo.src' and writes 'foo.py' and 'foo.pyx'.

I hope others find this useful (and please let me know if there is a fancier version out there somewhere I missed).

Thanks,
Pat

from operator import __mul__
import sys

if len(sys.argv) != 2:
    raise SystemExit("\nExpected exactly one argument.")

fn = sys.argv[1]+'.'

sf = file(fn+'src','r')
df = file(fn+'py','w'), file(fn+'pyx','w')
enable = (1,1)

for line in sf:
    outlines = map(__mul__,enable,[line,line])
    tokens = line.split()
    if tokens:
        tok = tokens[0]
        if tok == 'cdef':
            if tokens[1] == 'class':
                tokens = line.split('cdef',1)
                outlines[0] = tokens[0]+tokens[1].lstrip().replace(':','(object):',1)
            elif ':' in line.split('#',1)[0]:
                outlines[0] = line.replace('cdef','def',1)
            else:
                outlines[0] = ''
        elif tok in ('#if','#else','#endif'):
            if tok == '#if':
                assert enable == (1,1) and tokens[1] in ('pyrex','!pyrex')
                enable = ((1,0),(0,1))[tokens[1] == 'pyrex']
            elif tok == '#else':
                assert enable in ((1,0),(0,1))
                enable = ((1,0),(0,1))[enable==(1,0)]
            else:
                assert enable in ((1,0),(0,1))
                enable = (1,1)
            continue #without writing
    for f,l in zip(df,outlines):
        f.write(l)

for f in df:
    f.close()







More information about the Pyrex mailing list