예제 #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 프로젝트: mozillazg/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 = [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

    # prepare dictionary for meta class
    d_meta = {}

    # prepare dictionary for 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_class = {"_cpp_proxy"   : cppclass,
         "__dispatch__" : dispatch,
         "__new__"      : make_new(class_name),
         }

    # insert (static) methods into the class dictionary
    for name in cppclass.get_method_names():
        cppol = cppclass.get_overload(name)
        if cppol.is_static():
            d_class[name] = make_static_function(name, cppol)
        else:
            d_class[name] = make_method(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 name in cppclass.get_datamember_names():
        cppdm = cppclass.get_datamember(name)
        d_class[name] = cppdm
        if cppdm.is_static():
            d_meta[name] = cppdm

    # 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), d_meta)

    # create the python-side C++ class
    pycppclass = metacpp(class_name, _drop_cycles(bases), d_class)

    # store the class on its outer scope
    setattr(scope, final_class_name, pycppclass)

    # 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
예제 #4
0
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 = [CPPObject,]
    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(CppyyClass)(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)
        pydm = make_datamember(cppdm)

        setattr(pycppclass, dm_name, pydm)
        if cppdm.is_static():
            setattr(metacpp, dm_name, pydm)

    _pythonize(pycppclass)
    cppyy._register_class(pycppclass)
    return pycppclass
예제 #5
0
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

    # prepare dictionary for meta class
    d_meta = {}

    # prepare dictionary for 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_class = {
        "_cpp_proxy": cppclass,
        "__dispatch__": dispatch,
        "__new__": make_new(class_name),
    }

    # insert (static) methods into the class dictionary
    for name in cppclass.get_method_names():
        cppol = cppclass.get_overload(name)
        if cppol.is_static():
            d_class[name] = make_static_function(name, cppol)
        else:
            d_class[name] = make_method(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 name in cppclass.get_datamember_names():
        cppdm = cppclass.get_datamember(name)
        d_class[name] = cppdm
        if cppdm.is_static():
            d_meta[name] = cppdm

    # 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),
                             d_meta)

    # create the python-side C++ class
    pycppclass = metacpp(class_name, _drop_cycles(bases), d_class)

    # store the class on its outer scope
    setattr(scope, final_class_name, pycppclass)

    # 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