[Rpm-maint] [PATCH] fix the signatures of the METH_NOARGS callbacks

David Malcolm dmalcolm at redhat.com
Thu Dec 22 23:59:51 UTC 2011


Various Python method callbacks have signatures of the form:

  static PyObject *
  foo(some_object_subclass *obj)

and are registered within the PyMethodDef tables with the METH_NOARGS
flag [1], with a cast to (PyCFunction) due to the PyObject/subclass
mismatch.

However, such callbacks do receive two arguments: they are invoked with
a signature of this form:

  static PyObject *
  foo(some_object_subclass *obj, PyObject *ignored)

The CPython interpreter only uses METH_NOARGS to allow it to pass NULL as the
second parameter: there are still two parameters.  The dispatch code is in
Python's Python/ceval.c:call_function:

            if (flags & METH_NOARGS && na == 0) {
                C_TRACE(x, (*meth)(self,NULL));
            }

The fact that this has ever worked may be a coincidence of the
platform/compiler's calling conventions, and I don't think it's guaranteed to
keep working.

Found using my static analysis tool:
http://gcc-python-plugin.readthedocs.org/en/latest/cpychecker.html#verification-of-pymethoddef-tables


[1] http://docs.python.org/c-api/structures.html#METH_NOARGS
---
 python/rpmfi-py.c |   42 +++++++++++++++++++++---------------------
 python/rpmmi-py.c |    4 ++--
 python/rpmte-py.c |   34 +++++++++++++++++-----------------
 3 files changed, 40 insertions(+), 40 deletions(-)

diff --git a/python/rpmfi-py.c b/python/rpmfi-py.c
index a43fee3..4bfcc81 100644
--- a/python/rpmfi-py.c
+++ b/python/rpmfi-py.c
@@ -14,74 +14,74 @@ struct rpmfiObject_s {
 };
 
 static PyObject *
-rpmfi_FC(rpmfiObject * s)
+rpmfi_FC(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmfiFC(s->fi));
 }
 
 static PyObject *
-rpmfi_FX(rpmfiObject * s)
+rpmfi_FX(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmfiFX(s->fi));
 }
 
 static PyObject *
-rpmfi_DC(rpmfiObject * s)
+rpmfi_DC(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmfiDC(s->fi));
 }
 
 static PyObject *
-rpmfi_DX(rpmfiObject * s)
+rpmfi_DX(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmfiDX(s->fi));
 }
 
 static PyObject *
-rpmfi_BN(rpmfiObject * s)
+rpmfi_BN(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmfiBN(s->fi));
 }
 
 static PyObject *
-rpmfi_DN(rpmfiObject * s)
+rpmfi_DN(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmfiDN(s->fi));
 }
 
 static PyObject *
-rpmfi_FN(rpmfiObject * s)
+rpmfi_FN(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmfiFN(s->fi));
 }
 
 static PyObject *
-rpmfi_FFlags(rpmfiObject * s)
+rpmfi_FFlags(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmfiFFlags(s->fi));
 }
 
 static PyObject *
-rpmfi_VFlags(rpmfiObject * s)
+rpmfi_VFlags(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmfiVFlags(s->fi));
 }
 
 static PyObject *
-rpmfi_FMode(rpmfiObject * s)
+rpmfi_FMode(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmfiFMode(s->fi));
 }
 
 static PyObject *
-rpmfi_FState(rpmfiObject * s)
+rpmfi_FState(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmfiFState(s->fi));
 }
 
 /* XXX rpmfiFDigest */
 static PyObject *
-rpmfi_Digest(rpmfiObject * s)
+rpmfi_Digest(rpmfiObject * s, PyObject * unused)
 {
     char *digest = rpmfiFDigestHex(s->fi, NULL);
     if (digest) {
@@ -94,49 +94,49 @@ rpmfi_Digest(rpmfiObject * s)
 }
 
 static PyObject *
-rpmfi_FLink(rpmfiObject * s)
+rpmfi_FLink(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmfiFLink(s->fi));
 }
 
 static PyObject *
-rpmfi_FSize(rpmfiObject * s)
+rpmfi_FSize(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("L", rpmfiFSize(s->fi));
 }
 
 static PyObject *
-rpmfi_FRdev(rpmfiObject * s)
+rpmfi_FRdev(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmfiFRdev(s->fi));
 }
 
 static PyObject *
-rpmfi_FMtime(rpmfiObject * s)
+rpmfi_FMtime(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmfiFMtime(s->fi));
 }
 
 static PyObject *
-rpmfi_FUser(rpmfiObject * s)
+rpmfi_FUser(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmfiFUser(s->fi));
 }
 
 static PyObject *
-rpmfi_FGroup(rpmfiObject * s)
+rpmfi_FGroup(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmfiFGroup(s->fi));
 }
 
 static PyObject *
-rpmfi_FColor(rpmfiObject * s)
+rpmfi_FColor(rpmfiObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmfiFColor(s->fi));
 }
 
 static PyObject *
-rpmfi_FClass(rpmfiObject * s)
+rpmfi_FClass(rpmfiObject * s, PyObject * unused)
 {
     const char * FClass;
 
@@ -196,7 +196,7 @@ rpmfi_iternext(rpmfiObject * s)
 	    PyTuple_SET_ITEM(result, 11, Py_None);
 	} else
 	    PyTuple_SET_ITEM(result, 11, Py_BuildValue("s", FGroup));
-	PyTuple_SET_ITEM(result, 12, rpmfi_Digest(s));
+	PyTuple_SET_ITEM(result, 12, rpmfi_Digest(s, NULL));
 
     } else
 	s->active = 0;
diff --git a/python/rpmmi-py.c b/python/rpmmi-py.c
index 977e475..8e670ce 100644
--- a/python/rpmmi-py.c
+++ b/python/rpmmi-py.c
@@ -78,7 +78,7 @@ rpmmi_iternext(rpmmiObject * s)
 }
 
 static PyObject *
-rpmmi_Instance(rpmmiObject * s)
+rpmmi_Instance(rpmmiObject * s, PyObject * unused)
 {
     int rc = 0;
 
@@ -89,7 +89,7 @@ rpmmi_Instance(rpmmiObject * s)
 }
 
 static PyObject *
-rpmmi_Count(rpmmiObject * s)
+rpmmi_Count(rpmmiObject * s, PyObject * unused)
 {
     DEPRECATED_METHOD("use len(mi) instead");
     return Py_BuildValue("i", PyMapping_Size((PyObject *)s));
diff --git a/python/rpmte-py.c b/python/rpmte-py.c
index 73006e3..0850fc4 100644
--- a/python/rpmte-py.c
+++ b/python/rpmte-py.c
@@ -46,83 +46,83 @@ struct rpmteObject_s {
 };
 
 static PyObject *
-rpmte_TEType(rpmteObject * s)
+rpmte_TEType(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmteType(s->te));
 }
 
 static PyObject *
-rpmte_N(rpmteObject * s)
+rpmte_N(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmteN(s->te));
 }
 
 static PyObject *
-rpmte_E(rpmteObject * s)
+rpmte_E(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmteE(s->te));
 }
 
 static PyObject *
-rpmte_V(rpmteObject * s)
+rpmte_V(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmteV(s->te));
 }
 
 static PyObject *
-rpmte_R(rpmteObject * s)
+rpmte_R(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmteR(s->te));
 }
 
 static PyObject *
-rpmte_A(rpmteObject * s)
+rpmte_A(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmteA(s->te));
 }
 
 static PyObject *
-rpmte_O(rpmteObject * s)
+rpmte_O(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmteO(s->te));
 }
 
 static PyObject *
-rpmte_NEVR(rpmteObject * s)
+rpmte_NEVR(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmteNEVR(s->te));
 }
 
 static PyObject *
-rpmte_NEVRA(rpmteObject * s)
+rpmte_NEVRA(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("s", rpmteNEVRA(s->te));
 }
 
 static PyObject *
-rpmte_Color(rpmteObject * s)
+rpmte_Color(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmteColor(s->te));
 }
 
 static PyObject *
-rpmte_PkgFileSize(rpmteObject * s)
+rpmte_PkgFileSize(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("L", rpmtePkgFileSize(s->te));
 }
 
 static PyObject *
-rpmte_Parent(rpmteObject * s)
+rpmte_Parent(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmteParent(s->te));
 }
 
-static PyObject * rpmte_Failed(rpmteObject * s)
+static PyObject * rpmte_Failed(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmteFailed(s->te));
 }
 
-static PyObject * rpmte_Problems(rpmteObject * s)
+static PyObject * rpmte_Problems(rpmteObject * s, PyObject * unused)
 {
     rpmps ps = rpmteProblems(s->te);
     PyObject *problems = rpmps_AsList(ps);
@@ -132,20 +132,20 @@ static PyObject * rpmte_Problems(rpmteObject * s)
 
 /*
 static PyObject *
-rpmte_DependsOnKey(rpmteObject * s)
+rpmte_DependsOnKey(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmteDependsOnKey(s->te));
 }
 */
 
 static PyObject *
-rpmte_DBOffset(rpmteObject * s)
+rpmte_DBOffset(rpmteObject * s, PyObject * unused)
 {
     return Py_BuildValue("i", rpmteDBOffset(s->te));
 }
 
 static PyObject *
-rpmte_Key(rpmteObject * s)
+rpmte_Key(rpmteObject * s, PyObject * unused)
 {
     PyObject * Key;
 
-- 
1.7.6.2




More information about the Rpm-maint mailing list