extern PyObject *abstract_pynew(PyTypeObject *, PyObject *, PyObject *);
/* A `tp_new' function which refuses to make the object. */
-#define KWLIST (/*unconst*/ char **)kwlist
+#ifndef CONVERT_CAREFULLY
+# define CONVERT_CAREFULLY(newty, expty, obj) \
+ (!sizeof(*(expty *)0 = (obj)) + (/*unconst*/ newty)(obj))
+ /* Convert OBJ to the type NEWTY, having previously checked that it is
+ * convertible to the expected type EXPTY.
+ *
+ * Because of the way we set up types, we can make many kinds of tables be
+ * `const' which can't usually be so (because Python will want to fiddle
+ * with their reference counts); and, besides, Python's internals are
+ * generally quite bad at being `const'-correct about tables. One frequent
+ * application of this macro, then, is in removing `const' from a type
+ * without sacrificing all type safety. The other common use is in
+ * checking that method function types match up with the signatures
+ * expected in their method definitions.
+ */
+#endif
+
+#define KWLIST CONVERT_CAREFULLY(char **, const char *const *, kwlist)
/* Strip `const' qualifiers from the keyword list `kwlist'. Useful when
* calling `PyArg_ParseTupleAndKeywords', which isn't `const'-correct.
*/
#define INITTYPE(ty, base) INITTYPE_META(ty, base, type)
/* Macros to initialize a type from its skeleton. */
+/* Macros for filling in `PyMethodDef' tables, ensuring that functions have
+ * the expected signatures.
+ */
+#define STD_METHOD(decor, func, doc) \
+ { #func, decor(func), METH_VARARGS, doc },
+#define KEYWORD_METHOD(decor, func, doc) \
+ { #func, \
+ CONVERT_CAREFULLY(PyCFunction, PyCFunctionWithKeywords, decor(func)), \
+ METH_VARARGS | METH_KEYWORDS, \
+ doc },
+
/* Convenience wrappers for filling in `PyMethodDef' tables, following
* Pyke naming convention. Define `METHNAME' locally as
*
*
* around the method table.
*/
-#define METH(func, doc) \
- { #func, METHNAME(func), METH_VARARGS, doc },
-#define KWMETH(func, doc) \
- { #func, (PyCFunction)METHNAME(func), \
- METH_VARARGS | METH_KEYWORDS, doc },
+#define METH(func, doc) STD_METHOD(METHNAME, func, doc)
+#define KWMETH(func, doc) KEYWORD_METHOD(METHNAME, func, doc)
/* Convenience wrappers for filling in `PyGetSetDef' tables, following Pyke
* naming convention. Define `GETSETNAME' locally as
/*----- Generic mapping support -------------------------------------------*/
/* Mapping methods. */
-#define GMAP_METH(func, doc) { #func, gmapmeth_##func, METH_VARARGS, doc },
-#define GMAP_KWMETH(func, doc) \
- { #func, (PyCFunction)gmapmeth_##func, METH_VARARGS|METH_KEYWORDS, doc },
+#define GMAP_METMNAME(func) gmapmeth_##func
+#define GMAP_METH(func, doc) STD_METHOD(GMAP_METMNAME, func, doc)
+#define GMAP_KWMETH(func, doc) KEYWORD_METHOD(GMAP_METMNAME, func, doc)
#define GMAP_METHDECL(func, doc) \
extern PyObject *gmapmeth_##func(PyObject *, PyObject *);
#define GMAP_KWMETHDECL(func, doc) \