def genfiles(template, fname='temp', pxdname=None, testname=None, pyxheader=None, pxdheader=None, testheader=None, package='..'): """Generates all cython source files needed to create the wrapper.""" # munge some filenames fname = fname[:-4] if fname.endswith('.pyx') else fname pxdname = fname if pxdname is None else pxdname pxdname = pxdname + '.pxd' if not pxdname.endswith('.pxd') else pxdname testname = 'test_' + fname if testname is None else testname testname = testname + '.py' if not testname.endswith('.py') else testname fname += '.pyx' # register dtypes for t in template: if t[0] == 'vector': ts.register_numpy_dtype(t[1]) pyx = genpyx(template, pyxheader) pxd = genpxd(template, pxdheader) test = gentest(template, testheader, package) newoverwrite(pyx, fname) newoverwrite(pxd, pxdname) newoverwrite(test, testname)
def genbindings(ns, rc): """Generates bidnings using the command line setting specified in ns. """ ns.cyclus = False # FIXME cyclus bindings don't exist yet! for i, cls in enumerate(rc.classes): if len(cls) == 2: rc.classes[i] = (cls[0], cls[1], cls[1]) load_pysrcmod(cls[1], ns, rc) for i, fnc in enumerate(rc.functions): if len(fnc) == 2: rc.functions[i] = (fnc[0], fnc[1], fnc[1]) load_pysrcmod(fnc[1], ns, rc) # register dtypes for t in rc.stlcontainers: if t[0] == 'vector': ts.register_numpy_dtype(t[1]) # compute all class descriptions first classes = {} env = {} # target environment, not source one for classname, srcname, tarname in rc.classes: print("parsing " + classname) desc = classes[classname] = compute_desc(classname, srcname, tarname, 'class', ns, rc) if ns.verbose: pprint(desc) print("registering " + classname) #pxd_base = desc['pxd_filename'].rsplit('.', 1)[0] # eg, fccomp pxd_base = tarname or srcname # eg, fccomp #cpppxd_base = desc['cpppxd_filename'].rsplit('.', 1)[0] # eg, cpp_fccomp cpppxd_base = 'cpp_' + (tarname or srcname) # eg, cpp_fccomp class_c2py = ('{pytype}({var})', ('{proxy_name} = {pytype}()\n' '(<{ctype} *> {proxy_name}._inst)[0] = {var}'), ('if {cache_name} is None:\n' ' {proxy_name} = {pytype}()\n' ' {proxy_name}._free_inst = False\n' ' {proxy_name}._inst = &{var}\n' ' {cache_name} = {proxy_name}\n') ) class_py2c = ('{proxy_name} = <{cytype}> {var}', '(<{ctype} *> {proxy_name}._inst)[0]') class_cimport = (rc.package, cpppxd_base) ts.register_class(classname, # FCComp cython_c_type=cpppxd_base + '.' + classname, # cpp_fccomp.FCComp cython_cimport=class_cimport, cython_cy_type=pxd_base + '.' + classname, # fccomp.FCComp cython_py_type=pxd_base + '.' + classname, # fccomp.FCComp cython_template_class_name=classname.replace('_', '').capitalize(), cython_cyimport=pxd_base, # fccomp cython_pyimport=pxd_base, # fccomp cython_c2py=class_c2py, cython_py2c=class_py2c, ) cache.dump() _adddesc2env(desc, env, classname, srcname, tarname) # then compute all function descriptions for funcname, srcname, tarname in rc.functions: print("parsing " + classname) desc = compute_desc(funcname, srcname, tarname, 'func', ns, rc) if ns.verbose: pprint(desc) cache.dump() _adddesc2env(desc, env, funcname, srcname, tarname) # next, make cython bindings # generate first, then write out to ensure this is atomic per-class if ns.cython: print("making cython bindings") cpppxds = gencpppxd(env) pxds = genpxd(env) pyxs = genpyx(env, classes) for key, cpppxd in cpppxds.iteritems(): newoverwrite(cpppxd, os.path.join(rc.package, env[key]['cpppxd_filename'])) for key, pxd in pxds.iteritems(): newoverwrite(pxd, os.path.join(rc.package, env[key]['pxd_filename'])) for key, pyx in pyxs.iteritems(): newoverwrite(pyx, os.path.join(rc.package, env[key]['pyx_filename'])) # next, make cyclus bindings if ns.cyclus: print("making cyclus bindings")