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 <tallji...@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@python.org > http://mail.python.org/**mailman/listinfo/cplusplus-sig<http://mail.python.org/mailman/listinfo/cplusplus-sig> >
_______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig