예제 #1
0
파일: pythonify.py 프로젝트: charred/pypy
def make_pycppclass(scope, class_name, final_class_name, cppclass):

    # get a list of base classes for class creation
    bases = [get_pycppclass(base) for base in cppclass.get_base_names()]
    if not bases:
        bases = [CppyyClass,]
    else:
        # it's technically possible that the required class now has been built
        # if one of the base classes uses it in e.g. a function interface
        try:
            return scope.__dict__[final_class_name]
        except KeyError:
            pass

    # create a meta class to allow properties (for static data write access)
    metabases = [type(base) for base in bases]
    metacpp = type(CppyyClassMeta)(class_name+'_meta', _drop_cycles(metabases), {})

    # create the python-side C++ class representation
    def dispatch(self, name, signature):
        cppol = cppclass.dispatch(name, signature)
        return types.MethodType(make_method(name, cppol), self, type(self))
    d = {"_cpp_proxy"   : cppclass,
         "__dispatch__" : dispatch,
         "__new__"      : make_new(class_name, cppclass),
         }
    pycppclass = metacpp(class_name, _drop_cycles(bases), d)
 
    # cache result early so that the class methods can find the class itself
    setattr(scope, final_class_name, pycppclass)

    # insert (static) methods into the class dictionary
    for meth_name in cppclass.get_method_names():
        cppol = cppclass.get_overload(meth_name)
        if cppol.is_static():
            setattr(pycppclass, meth_name, make_static_function(meth_name, cppol))
        else:
            setattr(pycppclass, meth_name, make_method(meth_name, cppol))

    # add all data members to the dictionary of the class to be created, and
    # static ones also to the meta class (needed for property setters)
    for dm_name in cppclass.get_datamember_names():
        cppdm = cppclass.get_datamember(dm_name)

        # here, setattr() can not be used, because a data member can shadow one in
        # its base class, resulting in the __set__() of its base class being called
        # by setattr(); so, store directly on the dictionary
        pycppclass.__dict__[dm_name] = cppdm
        import cppyy
        if cppyy._is_static(cppdm):     # TODO: make this a method of cppdm
            metacpp.__dict__[dm_name] = cppdm

    # the call to register will add back-end specific pythonizations and thus
    # needs to run first, so that the generic pythonizations can use them
    import cppyy
    cppyy._register_class(pycppclass)
    _pythonize(pycppclass)
    return pycppclass
예제 #2
0
파일: pythonify.py 프로젝트: sota/pypy-old
def make_pycppclass(scope, class_name, final_class_name, cppclass):

    # get a list of base classes for class creation
    bases = [get_pycppclass(base) for base in cppclass.get_base_names()]
    if not bases:
        bases = [CPPInstance,]
    else:
        # it's technically possible that the required class now has been built
        # if one of the base classes uses it in e.g. a function interface
        try:
            return scope.__dict__[final_class_name]
        except KeyError:
            pass

    # create a meta class to allow properties (for static data write access)
    metabases = [type(base) for base in bases]
    metacpp = type(CPPClass)(class_name+'_meta', _drop_cycles(metabases), {})

    # create the python-side C++ class representation
    def dispatch(self, name, signature):
        cppol = cppclass.dispatch(name, signature)
        return types.MethodType(make_method(name, cppol), self, type(self))
    d = {"_cpp_proxy"   : cppclass,
         "__dispatch__" : dispatch,
         "__new__"      : make_new(class_name),
         }
    pycppclass = metacpp(class_name, _drop_cycles(bases), d)
 
    # cache result early so that the class methods can find the class itself
    setattr(scope, final_class_name, pycppclass)

    # insert (static) methods into the class dictionary
    for meth_name in cppclass.get_method_names():
        cppol = cppclass.get_overload(meth_name)
        if cppol.is_static():
            setattr(pycppclass, meth_name, make_static_function(meth_name, cppol))
        else:
            setattr(pycppclass, meth_name, make_method(meth_name, cppol))

    # add all data members to the dictionary of the class to be created, and
    # static ones also to the meta class (needed for property setters)
    for dm_name in cppclass.get_datamember_names():
        cppdm = cppclass.get_datamember(dm_name)

        # here, setattr() can not be used, because a data member can shadow one in
        # its base class, resulting in the __set__() of its base class being called
        # by setattr(); so, store directly on the dictionary
        pycppclass.__dict__[dm_name] = cppdm
        import cppyy
        if cppyy._is_static(cppdm):     # TODO: make this a method of cppdm
            metacpp.__dict__[dm_name] = cppdm

    # the call to register will add back-end specific pythonizations and thus
    # needs to run first, so that the generic pythonizations can use them
    import cppyy
    cppyy._register_class(pycppclass)
    _pythonize(pycppclass)
    return pycppclass
예제 #3
0
파일: pythonify.py 프로젝트: charred/pypy
def get_pycppitem(scope, name):
    import cppyy

    # resolve typedefs/aliases
    full_name = (scope == gbl) and name or (scope.__name__+'::'+name)
    true_name = cppyy._resolve_name(full_name)
    if true_name != full_name:
        return get_pycppclass(true_name)

    pycppitem = None

    # classes
    cppitem = cppyy._scope_byname(true_name)
    if cppitem:
        if cppitem.is_namespace():
            pycppitem = make_cppnamespace(scope, true_name, cppitem)
            setattr(scope, name, pycppitem)
        else:
            pycppitem = make_pycppclass(scope, true_name, name, cppitem)

    # templates
    if not cppitem:
        cppitem = cppyy._template_byname(true_name)
        if cppitem:
            pycppitem = make_cpptemplatetype(scope, name)
            setattr(scope, name, pycppitem)

    # functions
    if not cppitem:
        try:
            cppitem = scope._cpp_proxy.get_overload(name)
            pycppitem = make_static_function(name, cppitem)
            setattr(scope.__class__, name, pycppitem)
            pycppitem = getattr(scope, name)      # binds function as needed
        except AttributeError:
            pass

    # data
    if not cppitem:
        try:
            cppdm = scope._cpp_proxy.get_datamember(name)
            setattr(scope, name, cppdm)
            if cppyy._is_static(cppdm): # TODO: make this a method of cppdm
                setattr(scope.__class__, name, cppdm)
            pycppitem = getattr(scope, name)      # gets actual property value
        except AttributeError:
            pass

    if pycppitem is not None:      # pycppitem could be a bound C++ NULL, so check explicitly for Py_None
        return pycppitem

    raise AttributeError("'%s' has no attribute '%s'" % (str(scope), name))
예제 #4
0
파일: pythonify.py 프로젝트: sota/pypy-old
def get_pycppitem(scope, name):
    import cppyy

    # resolve typedefs/aliases
    full_name = (scope == gbl) and name or (scope.__name__+'::'+name)
    true_name = cppyy._resolve_name(full_name)
    if true_name != full_name:
        return get_pycppclass(true_name)

    pycppitem = None

    # classes
    cppitem = cppyy._scope_byname(true_name)
    if cppitem:
        if cppitem.is_namespace():
            pycppitem = make_cppnamespace(scope, true_name, cppitem)
            setattr(scope, name, pycppitem)
        else:
            pycppitem = make_pycppclass(scope, true_name, name, cppitem)

    # templates
    if not cppitem:
        cppitem = cppyy._template_byname(true_name)
        if cppitem:
            pycppitem = make_cpptemplatetype(scope, name)
            setattr(scope, name, pycppitem)

    # functions
    if not cppitem:
        try:
            cppitem = scope._cpp_proxy.get_overload(name)
            pycppitem = make_static_function(name, cppitem)
            setattr(scope.__class__, name, pycppitem)
            pycppitem = getattr(scope, name)      # binds function as needed
        except AttributeError:
            pass

    # data
    if not cppitem:
        try:
            cppdm = scope._cpp_proxy.get_datamember(name)
            setattr(scope, name, cppdm)
            if cppyy._is_static(cppdm): # TODO: make this a method of cppdm
                setattr(scope.__class__, name, cppdm)
            pycppitem = getattr(scope, name)      # gets actual property value
        except AttributeError:
            pass

    if pycppitem is not None:      # pycppitem could be a bound C++ NULL, so check explicitly for Py_None
        return pycppitem

    raise AttributeError("'%s' has no attribute '%s'" % (str(scope), name))