Re: [C++-sig] test if object instance is instance of extension class in C++
Stefan, many thanks, that of course did the trick. I'm not seeing the wood for the trees any more, I fear. > > what's the recommended way to check if an object instance is an instance of > > my extension class > > in C++ code? > > > > I'm currently doing a very ugly > > > > #define isMyExtensionClass(pyobj) (strcmp(pyobj->ob_type->tp_name, > > "MyExtensionClass") == 0) > > > > on PyObj* pyobj. > > > > I bet there is a better way but just can't seem to find it. > > bpl::extract e(pyobj); > if (e.check()) ... > > Note that you may want to use a reference type as template argument to > the boost::python::extract type, if you want to retrieve the object by > reference instead of by value. > > See http://www.boost.org/doc/libs/1_40_0/libs/python/doc/v2/extract.html > for details. Just for the record, this is what I do now: inline bool isMyExtensionClass(PyObject* &pyobj) { bp::extract extractor(pyobj); return extractor.check(); } inline bool isMyExtensionClass(bp::object &obj) { bp::extract extractor(obj); return extractor.check(); } Thanks again & have a nice weekend Holger Landesbank Baden-Wuerttemberg Anstalt des oeffentlichen Rechts Hauptsitze: Stuttgart, Karlsruhe, Mannheim, Mainz HRA 12704 Amtsgericht Stuttgart ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] test if object instance is instance of extension class in C++
On 02/24/2012 05:44 AM, Holger Joukl wrote: > Just for the record, this is what I do now: > > inline > bool isMyExtensionClass(PyObject* &pyobj) { > bp::extract extractor(pyobj); > return extractor.check(); > } I'm not sure why you use raw PyObject pointers in the first place. That should all be hidden behind bpl::object instances (which will then take care of the ref counting business for you). > inline > bool isMyExtensionClass(bp::object &obj) { > bp::extract extractor(obj); > return extractor.check(); > } bp::object itself has reference (smart pointer) semantics, so there is no need to pass objects by reference. Stefan -- ...ich hab' noch einen Koffer in Berlin... ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] test if object instance is instance of extension class in C++
Hi, > On 02/24/2012 05:44 AM, Holger Joukl wrote: > > Just for the record, this is what I do now: > > > > inline > > bool isMyExtensionClass(PyObject* &pyobj) { > > bp::extract extractor(pyobj); > > return extractor.check(); > > } > > I'm not sure why you use raw PyObject pointers in the first place. That > should all be hidden behind bpl::object instances (which will then take > care of the ref counting business for you). We're porting a legacy boost.python v1-wrapped library to current boost.python. Some parts of its internal methods operate on raw PyObject pointers. While we're probably going to change that for now I all I want is a running version and change as little as possible. > > inline > > bool isMyExtensionClass(bp::object &obj) { > > bp::extract extractor(obj); > > return extractor.check(); > > } > > bp::object itself has reference (smart pointer) semantics, so there is > no need to pass objects by reference. I see. Just out of curiosity: If I pass by reference I do save a copy constructor call, don't I? But I circumvent the bp::object refcount safety, though(?). But in a type check like above this shouldn't be dangerous - right? Holger Landesbank Baden-Wuerttemberg Anstalt des oeffentlichen Rechts Hauptsitze: Stuttgart, Karlsruhe, Mannheim, Mainz HRA 12704 Amtsgericht Stuttgart ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] test if object instance is instance of extension class in C++
On 02/24/2012 09:33 AM, Holger Joukl wrote: > bp::object itself has reference (smart pointer) semantics, so there is > no need to pass objects by reference. > I see. Just out of curiosity: > If I pass by reference I do save a copy constructor call, don't I? In principle, yes. I'm not sure how much of this the compiler would be able to optimize away, though. > But I circumvent the bp::object refcount safety, though(?). Well, yes, but you don't need that as C++ language semantics ensure the object lifetime. > But in a type check like above this shouldn't be dangerous - right? There is definitely no danger in doing this. It may just add a little bit of overhead (since in certain cases passing by value is cheaper than passing by reference, depending on the involved types and optimization level. Stefan -- ...ich hab' noch einen Koffer in Berlin... ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] test if object instance is instance of extension class in C++
> > bp::object itself has reference (smart pointer) semantics, so there is > > no need to pass objects by reference. > > I see. Just out of curiosity: > > If I pass by reference I do save a copy constructor call, don't I? > > In principle, yes. I'm not sure how much of this the compiler would be > able to optimize away, though. > > > But I circumvent the bp::object refcount safety, though(?). > > Well, yes, but you don't need that as C++ language semantics ensure the > object lifetime. > > > But in a type check like above this shouldn't be dangerous - right? > > There is definitely no danger in doing this. It may just add a little > bit of overhead (since in certain cases passing by value is cheaper than > passing by reference, depending on the involved types and optimization > level. Ok, this sounds like its best to do inline bool isMyExtensionClass(PyObject* pyobj) { bp::extract extractor(pyobj); return extractor.check(); } inline bool isMyExtensionClass(bp::object obj) { bp::extract extractor(obj); return extractor.check(); } Many thanks again Stefan, Holger Landesbank Baden-Wuerttemberg Anstalt des oeffentlichen Rechts Hauptsitze: Stuttgart, Karlsruhe, Mannheim, Mainz HRA 12704 Amtsgericht Stuttgart ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] how to override __setattr__ of an extension class
On 02/23/2012 12:04 PM, Holger Joukl wrote: Hi, I'm trying to instrument a wrapped class with custom __setattr__ mechanics: .def("__setattr__",&MyExtensionClass::setattr) How can I call the base class __setattr__ from within setattr and not run into infinite recursion? I.e. the analogon in C++ to class Foo(object): ... def __setattr__(self, attr, value): ... print "custom __setattr__" ... object.__setattr__(self, attr, value) ... foo = Foo() foo.x = 23 custom __setattr__ foo.x 23 To actually write to my instance dict I currently do PyObject* __dict__ = PyObject_GetAttrString(m_self, const_cast ("__dict__")); PyDict_SetItemString(__dict__, name, value.ptr()); inside MyExtensionClass::setattr (where m_self is PyObj*) Is there a better way? Everything I can think of (e.g. extract the base class from __bases__[0] and call its setattr) is functionally equivalent and not any prettier. On a sidenote, I initially thought I could wrap the __dict__ in bp::dict() to use its nice Python-like API for item assignment but this seems to always make a copy of the __dict__. I.e something like bp::dict bp_dict(__dict__); bp_dict[name] = value; won't work. The trick is to do: bp::dict bp_dict = bp::extract(__dict__); bp_dict[name] = value; Just calling the bp::dict invokes Python's dict constructor, which does a copy. Jim ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
Re: [C++-sig] Wrapping a function that takes class type, such as type_info
On 02/24/2012 02:31 AM, Adam Preble wrote: Jim, I'll top post since I think this might get messy nice and fast otherwise. I found I couldn't get to a method wrapped to type a PyTypeObject* and only PyObject* would do. Yeah, that's not surprising. You can also have it take a boost::python::object; that's essentially a smart pointer for PyObject*. if(PyObject_IsInstance((PyObject*) internal_type, noIdea) == 1) I think this is the only line that needs to change; you just need to use PyObject_IsSubClass instead of PyObject_IsInstance. Right now you're asking whether "internal_type" is an instance of "noIdea", so the answer is only True when "noIdea" is "type". I think you want to ask whether "internal_type" is a subclass of "noIdea". And that's just: if (PyObject_IsInstance((PyObject*)internal_type, noIdea) == 1) Jim ___ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig