Better python and C++ exception handling/error reporting. long long support use Python generic numeric coercion in from_python() for C++ numeric types Consider renaming PyPtr to Reference. Report Cygwin linker memory issues pickling support Make abstract classes non-instantiable (?) Support for Python LONG types in Objects.h Concept checking for to_python() template function (Ullrich did this) Throw TypeError after asserting when objects from objects.cpp detect a type mismatch. Add callback-through-function ability to callback.h Fix repr() for extension classes to print Testing Python 2.0 object revival in __del__ More thorough tests of objects.h/cpp classes Optimizations Reference-counting for UniquePodSet? Remove one level of indirection on type objects (no vtbl?). Specializations of Caller<> for commmon combinations of argument types (?) Collect common code into a nice shared library. Documentation: differences between Python classes and ExtensionClasses additional capabilities of ExtensionClasses slice adjustment Why special attributes other than __doc__ and __name__ are immutable. An example of the problems with the built-in Python classes. >>> class A: ... def __getattr__(self, name): ... return 'A.__getattr__' ... >>> class B(A): pass ... >>> class C(B): pass ... >>> C().x 'A.__getattr__' >>> B.__bases__ = () >>> C().x 'A.__getattr__' Multiple inheritance Smart pointers exception handling Advanced Topics: Advanced Type Conversion adding conversions for fundamental types generic conversions for template types (with partial spec). Interacting with built-in Python objects and types from C++ dealing with non-const reference/pointer parameters Private virtual functions with default implementations extending multiple-argument support using gen_all.py Calling back into Python: // caveat: UNTESTED! #include #include #include #include int main() { try { py::Ptr module(PyImport_ImportModule("weapons")); const int strength = 10; const char* manufacturer = "Vordon Empire"; py::Ptr a_blaster(py::Callback::call_method( module.get(), "Blaster", strength, manufacturer)); py::Callback::call_method(a_blaster.get(), "Fire"); int old_strength = py::Callback::call_method(a_blaster.get(), "get_strength"); py::Callback::call_method(a_blaster.get(), "set_strength", 5); } catch(...) { } } Fancy wrapping tricks templates Yes. If you look at the examples in extclass_demo.cpp you'll see that I have exposed several template instantiations (e.g. std::pair) in Python. Keep in mind, however, that you can only expose a template instantiation, not a template. In other words, MyTemplate can be exposed. MyTemplate itself cannot. Well, that's not strictly true. Wow, this is more complicated to explain than I thought. You can't make an ExtensionClass, since after all MyTemplate is not a type. You can only expose a concrete type to Python. What you *can* do (if your compiler supports partial ordering of function templates - MSVC is broken and does not) is to write appropriate from_python() and to_python() functions for converting a whole class of template instantiations to/from Python. That won't let you create an instance of MyTemplate from Python, but it will let you pass/return arbitrary MyTemplate instances to/from your wrapped C++ functions. template MyTemplate from_python(PyObject* x, py::Type >) { // code to convert x into a MyTemplate... that part is up to you } template PyObject* from_python(const MyTemplate&) { // code to convert MyTemplate into a PyObject*... that part is up to you } For example, you could use this to convert Python lists to/from std::vector automatically. Types that are already wrapped by other libraries It's not documented yet, but you should be able to use a raw PyObject* or a py::Ptr as one parameter to your C++ function. Then you can manipulate it as any other generic Python object. Alternatively, If the NTL gives you a C/C++ interface, you can also write your own converter function: some_ntl_type& from_python(PyObject* p, py::Type) { // an Example implementation. Basically, you need // to extract the NTL type from the PyObject*. if (p->ob_type != NTL_long_type) { PyErr_SetString(PyExc_TypeErr, "NTL long required"); throw py::ArgumentError(); } return *static_cast(p); } then the C++ functions you're wrapping can take a some_NTL_type& parameter directly. enums To handle this case, you need to decide how you want the enum to show up in Python (since Python doesn't have enums). If you are satisfied with a Python int as a way to get your enum value, you can write a simple from_python() function in namespace py:: #ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE namespace py { #endif mynamespace::SomeMeasure from_python(PyObject* x, py::Type) { return static_cast( from_python(x, py::Type())); } #ifndef PY_NO_INLINE_FRIENDS_IN_NAMESPACE } #endif You may also want to add a bunch of lines like this to your module initialization: mymodule.add(PyInt_FromLong(case1), "case1"); mymodule.add(PyInt_FromLong(case2), "case2"); ... raw C++ arrays You could expose a function like this one to get the desired effect: #include void set_len(UnitCell& x, py::Tuple tuple) { double len[3]; for (std::size_t i =0; i < 3; ++i) len[i] = py::from_python(tuple[i].get(), py::Type()); x.set_len(len); } "Thin converting wrappers" for constructors hijack some of the functionality described in the section on Overridable Virtual Functions (even though you don't have any virtual functions). I suggest this workaround: struct UnitCellWrapper : UnitCell { UnitCellWrapper(PyObject* self, py::Tuple x, py::Tuple y) : UnitCell(from_python(x[1], py::Type()), from_python(x[2], py::Type()), from_python(x[3], py::Type()), from_python(y[1], py::Type()), from_python(y[2], py::Type()), from_python(y[3], py::Type())) {} } py::ClassWrapper unit_cell_class; unit_cell_class.def(py::Constructor()); ... returning references to wrapped objects the importance of declaration order of ClassWrappers/ExtensionInstances out parameters and non-const pointers Miscellaneous About the vc6 project and the debug build About doctest.py Boost remarks: > > One of us is completely nuts ;->. How can I move the test > > (is_prefix(enablers[i].name + 2, name + 2)) outside the loop if it depends > > on the loop index, i? > > > name += 2; > for() > { > if (is_prefix(enablers[i].name + 2, name)) > } I see now. I guess I should stop pussyfooting and either go for optimization or clarity here, eh? ------ > Re: Dict > Why abbreviate this? Code is read 5 or 6 times for every time its > written. The few extra characters don't affect compile time or program > speed. It's part of my personal goal of write what you mean, name them what > they are. I completely agree. Abbrevs rub me the wrong way, 2 ;-> ------- Later: keyword and varargs? Put explicit Type<> arguments at the beginnings of overloads, to make them look more like template instance specifications. Known bugs can't handle 'const void' return values Who returns 'const void'? I did it once, by mistake ;)