def __init__(self): import cppyy self.lib = cppyy.load_reflection_info("./example01Dict.so") self.cls = cppyy._scope_byname("example01") self.inst = self.cls.get_overload(self.cls.type_name).call(None, 0)
def cpp_proxy_loader(cls): import cppyy cpp_proxy = cppyy._scope_byname( cls.__name__ != '::' and cls.__name__ or '') del cls.__class__._cpp_proxy cls._cpp_proxy = cpp_proxy return cpp_proxy
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))
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))
def cpp_proxy_loader(cls): import cppyy cpp_proxy = cppyy._scope_byname(cls.__name__ != '::' and cls.__name__ or '') del cls.__class__._cpp_proxy cls._cpp_proxy = cpp_proxy return cpp_proxy
def _pythonize(pyclass): try: _pythonizations[pyclass.__name__](pyclass) except KeyError: pass # general note: use 'in pyclass.__dict__' rather than 'hasattr' to prevent # adding pythonizations multiple times in derived classes import cppyy # map __eq__/__ne__ through a comparison to None if '__eq__' in pyclass.__dict__: def __eq__(self, other): if other is None: return not self if not self and not other: return True try: return self._cxx_eq(other) except TypeError: return NotImplemented pyclass._cxx_eq = pyclass.__dict__['__eq__'] pyclass.__eq__ = __eq__ if '__ne__' in pyclass.__dict__: def __ne__(self, other): if other is None: return not not self if type(self) is not type(other): return True return self._cxx_ne(other) pyclass._cxx_ne = pyclass.__dict__['__ne__'] pyclass.__ne__ = __ne__ # map size -> __len__ (generally true for STL) if 'size' in pyclass.__dict__ and not '__len__' in pyclass.__dict__ \ and callable(pyclass.size): pyclass.__len__ = pyclass.size # map push_back -> __iadd__ (generally true for STL) if 'push_back' in pyclass.__dict__ and not '__iadd__' in pyclass.__dict__: def __iadd__(self, ll): [self.push_back(x) for x in ll] return self pyclass.__iadd__ = __iadd__ # map begin()/end() protocol to iter protocol on STL(-like) classes, but # not on vector, for which otherwise the user has to make sure that the # global == and != for its iterators are reflected, which is a hassle ... if not 'vector' in pyclass.__name__[:11] and \ ('begin' in pyclass.__dict__ and 'end' in pyclass.__dict__): if cppyy._scope_byname(pyclass.__name__+'::iterator') or \ cppyy._scope_byname(pyclass.__name__+'::const_iterator'): def __iter__(self): i = self.begin() while i != self.end(): yield i.__deref__() i.__preinc__() i.destruct() raise StopIteration pyclass.__iter__ = __iter__ # else: rely on numbered iteration # combine __getitem__ and __len__ to make a pythonized __getitem__ if '__getitem__' in pyclass.__dict__ and '__len__' in pyclass.__dict__: pyclass._getitem__unchecked = pyclass.__getitem__ if '__setitem__' in pyclass.__dict__ and '__iadd__' in pyclass.__dict__: pyclass.__getitem__ = python_style_sliceable_getitem else: pyclass.__getitem__ = python_style_getitem # string comparisons if pyclass.__name__ == cppyy._std_string_name(): def eq(self, other): if type(other) == pyclass: return self.c_str() == other.c_str() else: return self.c_str() == other pyclass.__eq__ = eq pyclass.__str__ = pyclass.c_str # std::pair unpacking through iteration if 'std::pair' == pyclass.__name__[:9] or 'pair' == pyclass.__name__[:4]: def getitem(self, idx): if idx == 0: return self.first if idx == 1: return self.second raise IndexError("out of bounds") def return2(self): return 2 pyclass.__getitem__ = getitem pyclass.__len__ = return2
def __init__(self): import cppyy self.lib = cppyy.load_reflection_info("./example01Dict.so") self.cls = cppyy._scope_byname("example01") self.inst = self.cls.get_overload(self.cls.type_name).call(None, 0)
def _pythonize(pyclass): try: _pythonizations[pyclass.__name__](pyclass) except KeyError: pass # general note: use 'in pyclass.__dict__' rather than 'hasattr' to prevent # adding pythonizations multiple times in derived classes import cppyy # map __eq__/__ne__ through a comparison to None if '__eq__' in pyclass.__dict__: def __eq__(self, other): if other is None: return not self if not self and not other: return True try: return self._cxx_eq(other) except TypeError: return NotImplemented pyclass._cxx_eq = pyclass.__dict__['__eq__'] pyclass.__eq__ = __eq__ if '__ne__' in pyclass.__dict__: def __ne__(self, other): if other is None: return not not self if type(self) is not type(other): return True return self._cxx_ne(other) pyclass._cxx_ne = pyclass.__dict__['__ne__'] pyclass.__ne__ = __ne__ # map size -> __len__ (generally true for STL) if 'size' in pyclass.__dict__ and not '__len__' in pyclass.__dict__ \ and callable(pyclass.size): pyclass.__len__ = pyclass.size # map push_back -> __iadd__ (generally true for STL) if 'push_back' in pyclass.__dict__ and not '__iadd__' in pyclass.__dict__: def __iadd__(self, ll): [self.push_back(x) for x in ll] return self pyclass.__iadd__ = __iadd__ # map begin()/end() protocol to iter protocol on STL(-like) classes, but # not on vector, for which otherwise the user has to make sure that the # global == and != for its iterators are reflected, which is a hassle ... if not 'vector' in pyclass.__name__[:11] and \ ('begin' in pyclass.__dict__ and 'end' in pyclass.__dict__): if cppyy._scope_byname(pyclass.__name__+'::iterator') or \ cppyy._scope_byname(pyclass.__name__+'::const_iterator'): def __iter__(self): i = self.begin() while i != self.end(): yield i.__deref__() i.__preinc__() i.destruct() raise StopIteration pyclass.__iter__ = __iter__ # else: rely on numbered iteration # combine __getitem__ and __len__ to make a pythonized __getitem__ if '__getitem__' in pyclass.__dict__ and '__len__' in pyclass.__dict__: pyclass._getitem__unchecked = pyclass.__getitem__ if '__setitem__' in pyclass.__dict__ and '__iadd__' in pyclass.__dict__: pyclass.__getitem__ = python_style_sliceable_getitem else: pyclass.__getitem__ = python_style_getitem # string comparisons if pyclass.__name__ == cppyy._std_string_name(): def eq(self, other): if type(other) == pyclass: return self.c_str() == other.c_str() else: return self.c_str() == other pyclass.__eq__ = eq pyclass.__str__ = pyclass.c_str # std::pair unpacking through iteration if 'std::pair' == pyclass.__name__[:9] or 'pair' == pyclass.__name__[:4]: def getitem(self, idx): if idx == 0: return self.first if idx == 1: return self.second raise IndexError("out of bounds") def return2(self): return 2 pyclass.__getitem__ = getitem pyclass.__len__ = return2