Re: [C++-sig] test if object instance is instance of extension class in C++

2012-02-24 Thread Holger Joukl
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++

2012-02-24 Thread Stefan Seefeld
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++

2012-02-24 Thread Holger Joukl
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++

2012-02-24 Thread Stefan Seefeld
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++

2012-02-24 Thread Holger Joukl

> > 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

2012-02-24 Thread Jim Bosch

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

2012-02-24 Thread Jim Bosch

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