[C++-sig] Wrapping a function that takes class type, such as type_info

Adam Preble adam.preble at gmail.com
Fri Feb 24 08:31:49 CET 2012


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.  Despite all this, I managed to twist your advice
around just enough to birth this abomination:

bool ContainsImplementables::Has(PyObject* noIdea)
{
for(std::list<boost::shared_ptr<Implementable> >::iterator i =
implementables.begin(); i != implementables.end(); ++i)
{
Implementable* imp = (*i).get();
boost::python::converter::registration registration =
boost::python::converter::registry::lookup(boost::python::type_info(typeid(*imp)));
PyTypeObject* internal_type =
const_cast<PyTypeObject*>(registration.to_python_target_type());      //
const_cast heresy
if(internal_type != NULL)
{
if(PyObject_IsInstance((PyObject*) internal_type, noIdea) == 1)
{
return true;
}
}
}

return false;
}

Well, it doesn't crash!  I really don't know if I'm getting all the right
things in order, but I know in the debugger the stuff doesn't look like
complete garbage, and  internal_type isn't NULL.  The PyObject_IsInstance()
is never working when I pass in a class to Has() and it's always claiming
true if I pass type(class) to the Has() method there, regardless if the
particular class in question is actually contained inside there.  I tried
to step into that particular code and it was pretty rough on the eyes; I
couldn't figure out anything.

So to be more explicit about what happens:

cont = ContainsImplementables()
cont.Add(CImplementation())
cont.Add(PythonImplementation())

cont.Has(CImplementation) # False
cont.Has(type(CImplementation)) # True
cont.Has(PythonImplementation) # False
cont.Has(type( Python Implementation)) # True
cont.Has(AnotherPythonImplementation) # False
cont.Has(type(AnotherPythonImplementation)) # True

Am I anywhere near close on this?

On Thu, Feb 23, 2012 at 10:03 AM, Jim Bosch <talljimbo at gmail.com> wrote:
>
>
> You can probably find out a lot from just looking at the Python C API
> reference documentation for type objects.  You'll need to use that directly
> for a lot of your interaction with them, because there's no Boost.Python
> wrapper (like there is for, say, tuple or str).
>
> The main place you'll see them in Boost.Python is that this is actually
> what a boost::python::class_ object holds under the hood; you can assign
> that to a boost::python::object to get the type object without having to
> carry around all the template parameters.
>
>
>  I suppose the overall situation is this: imagine I have a container of
>> pointers referencing some interface.  The container contains potentially
>> both C++ and Python implementations.  All implementations are exposed in
>> Python.  Is there a way I could pass in some kind of type information and
>> be able to positively identify if something in that container matches the
>> type?
>>
>>
> Yes, as long as:
>
> - You can do the checking with a Python function that operates on type
> objects, like isinstance and issubclass (or their C API equivalents,
> PyObject_IsInstance and PyObject_IsSubclass).
>
> - You are content with looking up a PyTypeObject* given a C++ type_info,
> and not the other way around; you can use boost::python::converter::**registry::lookup
> to find the PyTypeObject for a Boost.Python-wrapped class.  That's deep in
> the bowels of Boost.Python's internals - see converter/registry.hpp and
> converter/registration.hpp to learn more - but it's quite usable.
>
>
>
> Jim
>
> ______________________________**_________________
> Cplusplus-sig mailing list
> Cplusplus-sig at python.org
> http://mail.python.org/**mailman/listinfo/cplusplus-sig<http://mail.python.org/mailman/listinfo/cplusplus-sig>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20120224/3d48b9d7/attachment-0001.html>


More information about the Cplusplus-sig mailing list