예제 #1
0
파일: stlwrap.py 프로젝트: kif/xdress
def genpyx_map(t, u):
    """Returns the pyx snippet for a map of type <t, u>."""
    t = ts.canon(t)
    u = ts.canon(u)
    kw = dict(tclsname=ts.cython_classname(t)[1], uclsname=ts.cython_classname(u)[1],
              thumname=ts.humanname(t)[1], uhumname=ts.humanname(u)[1],
              tctype=ts.cython_ctype(t), uctype=ts.cython_ctype(u),
              tpytype=ts.cython_pytype(t), upytype=ts.cython_pytype(u),
              tcytype=ts.cython_cytype(t), ucytype=ts.cython_cytype(u),)
    tisnotinst = ["not isinstance(key, {0})".format(x) for x in ts.from_pytypes[t]]
    kw['tisnotinst'] = " and ".join(tisnotinst)
    tc2pykeys = ['tc2pydecl', 'tc2pybody', 'tc2pyrtn']
    tc2py = ts.cython_c2py("deref(inow).first", t, cached=False)
    kw.update([(k, indentstr(v or '')) for k, v in zip(tc2pykeys, tc2py)])
    uc2pykeys = ['uc2pydecl', 'uc2pybody', 'uc2pyrtn']
    uc2py = ts.cython_c2py("v", u, cached=False, 
                           existing_name="deref(self.map_ptr)[k]")
    kw.update([(k, indentstr(v or '')) for k, v in zip(uc2pykeys, uc2py)])
    tpy2ckeys = ['tpy2cdecl', 'tpy2cbody', 'tpy2crtn']
    tpy2c = ts.cython_py2c("key", t)
    kw.update([(k, indentstr(v or '')) for k, v in zip(tpy2ckeys, tpy2c)])
    upy2ckeys = ['upy2cdecl', 'upy2cbody', 'upy2crtn']
    upy2c = ts.cython_py2c("value", u)
    kw.update([(k, indentstr(v or '')) for k, v in zip(upy2ckeys, upy2c)])
    return _pyxmap.format(**kw)
예제 #2
0
파일: cythongen.py 프로젝트: kif/xdress
def classpxd(desc):
    """Generates a ``*pxd`` Cython header snippet for exposing a C/C++ class to 
    other Cython wrappers based off of a dictionary description.

    Parameters
    ----------
    cimport_tups : set of tuples
        Set of Cython cimport tuples for .pxd header file.
    desc : dict
        Class description dictonary.

    Returns
    -------
    pxd : str
        Cython ``*.pxd`` header snippet for class.

    """
    if 'pxd_filename' not in desc:
        desc['pxd_filename'] = '{0}.pxd'.format(desc['name'].lower())
    pars = ', '.join([cython_cytype(p) for p in desc['parents'] or ()])
    d = {'parents': pars if 0 == len(pars) else '('+pars+')'}
    copy_from_desc = ['name',]
    for key in copy_from_desc:
        d[key] = desc[key]

    cimport_tups = set()
    for parent in desc['parents'] or ():
        cython_cimport_tuples(parent, cimport_tups, set(['cy']))
    

    from_cpppxd = desc['cpppxd_filename'].rsplit('.', 1)[0]
    # This is taken care of in main!
    #register_class(desc['name'], cython_cimport=from_cpppxd,
    #               cython_c_type="{0}.{1}".format(from_cpppxd, desc['name']),)
    d['name_type'] = cython_ctype(desc['name'])
    cython_cimport_tuples(desc['name'], cimport_tups, set(['c']))

    parentless_body = ['cdef void * _inst', 'cdef public bint _free_inst'] 
    body = parentless_body if desc['parents'] is None else []
    attritems = sorted(desc['attrs'].items())
    for aname, atype in attritems:
        if aname.startswith('_'):
            continue  # skip private
        _, _, cachename, iscached = cython_c2py(aname, atype, cache_prefix=None)
        if iscached:
            cython_cimport_tuples(atype, cimport_tups)
            cyt = cython_cytype(atype)
            decl = "cdef public {0} {1}".format(cyt, cachename)
            body.append(decl)

    d['body'] = indent(body or ['pass'])
    d['extra'] = desc.get('extra', {}).get('pxd', '')
    pxd = _pxd_class_template.format(**d)
    return cimport_tups, pxd
예제 #3
0
파일: stlwrap.py 프로젝트: kif/xdress
def genpxd_vector(t):
    """Returns the pxd snippet for a vector of type t."""
    t = ts.canon(t)
    kw = dict(clsname=ts.cython_classname(t)[1], humname=ts.humanname(t)[1], 
              ctype=ts.cython_ctype(t), pytype=ts.cython_pytype(t), 
              fncname=ts.cython_functionname(t)[1], 
              cytype=ts.cython_cytype(t),)
    return _pxdvector.format(**kw)
예제 #4
0
파일: stlwrap.py 프로젝트: kif/xdress
def genpyx_set(t):
    """Returns the pyx snippet for a set of type t."""
    t = ts.canon(t)
    kw = dict(clsname=ts.cython_classname(t)[1], humname=ts.humanname(t)[1], 
              ctype=ts.cython_ctype(t), pytype=ts.cython_pytype(t), 
              cytype=ts.cython_cytype(t),)
    fpt = ts.from_pytypes[t]
    kw['isinst'] = " or ".join(["isinstance(value, {0})".format(x) for x in fpt])
    c2pykeys = ['c2pydecl', 'c2pybody', 'c2pyrtn']
    c2py = ts.cython_c2py("deref(inow)", t, cached=False)
    kw.update([(k, indentstr(v or '')) for k, v in zip(c2pykeys, c2py)])
    py2ckeys = ['py2cdecl', 'py2cbody', 'py2crtn']
    py2c = ts.cython_py2c("value", t)
    kw.update([(k, indentstr(v or '')) for k, v in zip(py2ckeys, py2c)])
    return _pyxset.format(**kw)
예제 #5
0
파일: stlwrap.py 프로젝트: kif/xdress
def genpyx_vector(t):
    """Returns the pyx snippet for a vector of type t."""
    t = ts.canon(t)
    kw = dict(clsname=ts.cython_classname(t)[1], humname=ts.humanname(t)[1], 
              fncname=ts.cython_functionname(t)[1], 
              ctype=ts.cython_ctype(t), pytype=ts.cython_pytype(t), 
              cytype=ts.cython_cytype(t), stlcontainers=ts.STLCONTAINERS, 
              extra_types=ts.EXTRA_TYPES)
    t0 = t
    while not isinstance(t0, basestring):
        t0 = t[0]
    fpt = ts.from_pytypes[t0]
    kw['isinst'] = " or ".join(["isinstance(value, {0})".format(x) for x in fpt])
    c2pykeys = ['c2pydecl', 'c2pybody', 'c2pyrtn']
    c2py = ts.cython_c2py("deref(<{0} *> data)".format(kw['ctype']), t, cached=False,
                          proxy_name="data_proxy")
    kw.update([(k, indentstr(v or '')) for k, v in zip(c2pykeys, c2py)])
    cself2pykeys = ['cself2pydecl', 'cself2pybody', 'cself2pyrtn']
    cself2py = ts.cython_c2py("(cself.obval)", t, cached=False, proxy_name="val_proxy")
    kw.update([(k, indentstr(v or '')) for k, v in zip(cself2pykeys, cself2py)])
    py2ckeys = ['py2cdecl', 'py2cbody', 'py2crtn']
    py2c = ts.cython_py2c("value", t)
    kw.update([(k, indentstr(v or '')) for k, v in zip(py2ckeys, py2c)])
    return _pyxvector.format(**kw)
예제 #6
0
파일: cythongen.py 프로젝트: kif/xdress
def classpyx(desc, classes=None):
    """Generates a ``*.pyx`` Cython wrapper implementation for exposing a C/C++ 
    class based off of a dictionary description.  The environment is a 
    dictionary of all class names known to their descriptions.

    Parameters
    ----------
    desc : dict
        Class description dictonary.
    classes : dict, optional
        Dictionary which maps all class names that are required to 
        their own descriptions.  This is required for resolving class heirarchy
        dependencies.

    Returns
    -------
    pyx : str
        Cython ``*.pyx`` implementation file as in-memory string.

    """
    if classes is None:
        classes = {desc['name']: desc}
    nodocmsg = "no docstring for {0}, please file a bug report!"
    pars = ', '.join([cython_cytype(p) for p in desc['parents'] or ()])
    d = {'parents': pars if 0 == len(pars) else '('+pars+')'}
    copy_from_desc = ['name', 'namespace', 'header_filename']
    for key in copy_from_desc:
        d[key] = desc[key]
    class_doc = desc.get('docstrings', {}).get('class', nodocmsg.format(desc['name']))
    d['class_docstring'] = indent('\"\"\"{0}\"\"\"'.format(class_doc))

    class_ctype = cython_ctype(desc['name'])
    inst_name = "(<{0} *> self._inst)".format(class_ctype)

    import_tups = set()
    cimport_tups = set()
    for parent in desc['parents'] or ():
        cython_import_tuples(parent, import_tups)
        cython_cimport_tuples(parent, cimport_tups)

    alines = []
    cached_names = []
    attritems = sorted(desc['attrs'].items())
    for aname, atype in attritems:
        if aname.startswith('_'):
            continue  # skip private
        adoc = desc.get('docstrings', {}).get('attrs', {})\
                                         .get(aname, nodocmsg.format(aname))
        alines += _gen_property(aname, atype, adoc, cached_names=cached_names, 
                                inst_name=inst_name)
        cython_import_tuples(atype, import_tups)
        cython_cimport_tuples(atype, cimport_tups)
    d['attrs_block'] = indent(alines)
    pd = ["{0} = None".format(n) for n in cached_names]
    d['property_defaults'] = indent(indent(pd, join=False))

    mlines = []
    clines = []
    methcounts = _count0(desc['methods'])
    currcounts = {k: 0 for k in methcounts}
    mangled_mnames = {}
    methitems = sorted(desc['methods'].items())
    for mkey, mrtn in methitems:
        mname, margs = mkey[0], mkey[1:]
        if mname.startswith('_'):
            continue  # skip private
        if 1 < methcounts[mname]:
            mname_mangled = "_{0}_{1}_{2:0{3}}".format(desc['name'], mname, 
                    currcounts[mname], int(math.log(methcounts[mname], 10)+1)).lower()
        else:
            mname_mangled = mname
        currcounts[mname] += 1
        mangled_mnames[mkey] = mname_mangled
        for a in margs:
            cython_import_tuples(a[1], import_tups)
            cython_cimport_tuples(a[1], cimport_tups)
        minst_name, mcname = _method_instance_names(desc, classes, mkey, mrtn)
        if mcname != desc['name']:
            cython_import_tuples(mcname, import_tups)
            cython_cimport_tuples(mcname, cimport_tups)
        if mrtn is None:
            # this must be a constructor
            if mname not in (desc['name'], '__init__'):
                continue  # skip destuctors
            if 1 == methcounts[mname]:
                mname_mangled = '__init__'
                mangled_mnames[mkey] = mname_mangled
            mdoc = desc.get('docstrings', {}).get('methods', {}).get(mname, '')
            mdoc = _doc_add_sig(mdoc, mname, margs)
            clines += _gen_constructor(mname, mname_mangled, 
                                       desc['name'], margs, doc=mdoc, 
                                       cpppxd_filename=desc['cpppxd_filename'],
                                       inst_name=minst_name)
            if 1 < methcounts[mname] and currcounts[mname] == methcounts[mname]:
                # write dispatcher
                nm = {k: v for k, v in mangled_mnames.iteritems() if k[0] == mname}
                clines += _gen_dispatcher('__init__', nm, doc=mdoc, hasrtn=False)
        else:
            # this is a normal method
            cython_import_tuples(mrtn, import_tups)
            cython_cimport_tuples(mrtn, cimport_tups)
            mdoc = desc.get('docstrings', {}).get('methods', {})\
                                             .get(mname, nodocmsg.format(mname))
            mdoc = _doc_add_sig(mdoc, mname, margs)
            mlines += _gen_method(mname, mname_mangled, margs, mrtn, mdoc, 
                                  inst_name=minst_name)
            if 1 < methcounts[mname] and currcounts[mname] == methcounts[mname]:
                # write dispatcher
                nm = {k: v for k, v in mangled_mnames.iteritems() if k[0] == mname}
                mlines += _gen_dispatcher(mname, nm, doc=mdoc)
    if desc['parents'] is None:
        clines += ["def __dealloc__(self):"]
        clines += indent("if self._free_inst:", join=False)
        clines += indent(indent("free(self._inst)", join=False), join=False)
        cimport_tups.add(('libc.stdlib', 'free'))

    d['methods_block'] = indent(mlines)
    d['constructor_block'] = indent(clines)

    d['extra'] = desc.get('extra', {}).get('pyx', '')
    pyx = _pyx_class_template.format(**d)
    if 'pyx_filename' not in desc:
        desc['pyx_filename'] = '{0}.pyx'.format(d['name'].lower())
    return import_tups, cimport_tups, pyx