Yes, this looks very much like what I had in mind, except that you demonstrate how to store and retrieve a C structure in the type's tp_dict.
Indeed. I also think it is more appropriate than either a new metatype or a ParseTuple extension for the problem at hand (supporting arbitrary types in calldll), for the following reasons:
- There may be different ways of how an object converts to a "native" type. In particular, in some cases, ParseTuple may need to return (fill out) something more complex than a void*, something that calldll cannot support by nature.
- A type may need to provide various independent extensions to the standard protocols, e.g. it may provide "give me a Unicode doc string" in addition to "give me a conversion function to void*". In this case, you'd need multiple inheritance on the metatype level, something that does not reflect well in C. For Python, it is much more common not to care at all about inheritance. Instead, just access the protocol, and expect an exception if it is not supported.
Also notice that this *does* make use of new-style classes: In 2.1, types did not have a tp_dict slot. Of course, the PyType_Ready call should go immediately before the place where tp_dict is accessed, and a check should be added whether tp_flags contains Py_TPFLAGS_HAVE_CLASS.