[Rpm-maint] PATCH: Python: allow access to packages & headers from spec object

Daniel P. Berrange berrange at redhat.com
Thu Sep 18 16:00:03 UTC 2008


On Thu, Sep 18, 2008 at 11:34:10AM -0400, James Antill wrote:
> On Thu, 2008-09-18 at 16:23 +0100, Daniel P. Berrange wrote:
> > I'm trying todo some automated processing & analysis of RPM specfiles
> > and have found the python binding is lacking a number of key features
> > 
> >  - The 'spec' object allows access to the lists of sources, but doesn't
> >    expose the RPMBUILD_ISXXXX constants
> > 
> >  - The 'spec' object does not provide access to the 'packages' objects
> >    so you can't query most metadata about the spec.
> > 
> >  - None of the RPMTAG_XXX constants are defined, which makes using the
> >    'header' object unpleasant.
> 
>  RPMTAG is already there in the rpm module ... see init_rpm() and search
> for TAG.

Oh, i see its generated on the fly. Here's an update without that 3rd
chunk

 Makefile.am |    1 
 pkg-py.c    |  113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 pkg-py.h    |   26 +++++++++++++
 rpmmodule.c |   13 ++++++
 spec-py.c   |   30 +++++++++++++++
 5 files changed, 182 insertions(+), 1 deletion(-)

Daniel

diff -rupN rpm-4.5.90.git8461.orig/python/Makefile.am rpm-4.5.90.git8461.new/python/Makefile.am
--- rpm-4.5.90.git8461.orig/python/Makefile.am	2008-06-26 05:26:01.000000000 -0400
+++ rpm-4.5.90.git8461.new/python/Makefile.am	2008-09-18 07:24:51.000000000 -0400
@@ -36,5 +36,6 @@ _rpmmodule_la_SOURCES = rpmmodule.c syst
 	rpmmacro-py.c rpmmacro-py.h \
 	rpmte-py.c rpmte-py.h \
 	rpmts-py.c rpmts-py.h \
+	pkg-py.c pkg-py.h \
 	spec-py.c spec-py.h
 endif
diff -rupN rpm-4.5.90.git8461.orig/python/pkg-py.c rpm-4.5.90.git8461.new/python/pkg-py.c
--- rpm-4.5.90.git8461.orig/python/pkg-py.c	1969-12-31 19:00:00.000000000 -0500
+++ rpm-4.5.90.git8461.new/python/pkg-py.c	2008-09-18 07:24:45.000000000 -0400
@@ -0,0 +1,113 @@
+/** \ingroup py_c
+ * \file python/pkg-py.c
+ */
+
+#include "system.h"
+
+#include "pkg-py.h"
+#include "header-py.h"
+
+/** \ingroup python
+ * \name Class: Rpmpkg
+ * \class Rpmpkg
+ *
+ */
+
+
+static void 
+pkg_dealloc(pkgObject * s) 
+{
+        PyObject_Del(s);
+}
+
+static int
+pkg_print(pkgObject * s)
+{
+    return 0;
+}
+
+
+static hdrObject *
+pkg_get_header(pkgObject *s)
+{
+    PyObject *headerObj;
+    Package pkg;
+
+    pkg = pkgFromPkg(s);
+    if ( pkg != NULL) {
+        return hdr_Wrap(pkg->header);
+    }
+    else {
+        return NULL;
+    }
+
+}
+
+/**
+ */
+
+static char pkg_doc[] = "RPM Pkg file object";
+
+static PyMethodDef pkg_Pkg_methods[] = {
+    {"header",   (PyCFunction) pkg_get_header, METH_VARARGS,  NULL },
+    {NULL}  /* Sentinel */
+};
+
+PyTypeObject pkg_Type = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,                         /*ob_size*/
+    "rpm.pkg",               /*tp_name*/
+    sizeof(pkgObject),        /*tp_basicsize*/
+    0,                         /*tp_itemsize*/
+    (destructor) pkg_dealloc, /*tp_dealloc*/
+    (printfunc) pkg_print,    /*tp_print*/
+    0,                         /*tp_getattr*/
+    0,                         /*tp_setattr*/
+    0,                         /*tp_compare*/
+    0,                         /*tp_repr*/
+    0,                         /*tp_as_number*/
+    0,                         /*tp_as_sequence*/
+    0,                         /*tp_as_mapping*/
+    0,                         /*tp_hash */
+    0,                         /*tp_call*/
+    0,                         /*tp_str*/
+    0,                         /*tp_getattro*/
+    0,                         /*tp_setattro*/
+    0,                         /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+    pkg_doc,                  /* tp_doc */
+    0,                         /* tp_traverse */
+    0,                         /* tp_clear */
+    0,                         /* tp_richcompare */
+    0,                         /* tp_weaklistoffset */
+    0,                         /* tp_iter */
+    0,                         /* tp_iternext */
+    pkg_Pkg_methods,         /* tp_methods */
+    0,                         /* tp_members */
+    0,                         /* tp_getset */
+    0,                         /* tp_base */
+    0,                         /* tp_dict */
+    0,                         /* tp_descr_get */
+    0,                         /* tp_descr_set */
+    0,                         /* tp_dictoffset */
+    0,                         /* tp_init */
+    0,                         /* tp_alloc */
+    0,                         /* tp_new */
+    0,                         /* tp_free */
+    0,                         /* tp_is_gc */
+};
+
+Package pkgFromPkg(pkgObject *s) 
+{
+    return s->pkg;
+}
+
+pkgObject *
+pkg_Wrap(Package pkg) 
+{
+    pkgObject * s = PyObject_New(pkgObject, &pkg_Type);
+    if (s == NULL)
+        return NULL;
+    s->pkg = pkg; 
+    return s;
+}
diff -rupN rpm-4.5.90.git8461.orig/python/pkg-py.h rpm-4.5.90.git8461.new/python/pkg-py.h
--- rpm-4.5.90.git8461.orig/python/pkg-py.h	1969-12-31 19:00:00.000000000 -0500
+++ rpm-4.5.90.git8461.new/python/pkg-py.h	2008-09-18 07:24:48.000000000 -0400
@@ -0,0 +1,26 @@
+#ifndef RPMPYTHON_PKG
+#define RPMPYTHON_PKG
+
+#include <rpm/rpmbuild.h>
+
+/** \ingroup py_c
+ * \file python/pkg-py.h
+ */
+
+typedef struct pkgObject_s {
+    PyObject_HEAD
+    /*type specific fields */
+    Package pkg;
+} pkgObject;
+
+extern PyTypeObject pkg_Type;
+
+/**
+ */
+Package pkgFromPkg(pkgObject * pkg);
+
+/**
+ */
+pkgObject * pkg_Wrap(Package pkg);
+
+#endif /* RPMPYTHON_PKG */
diff -rupN rpm-4.5.90.git8461.orig/python/rpmmodule.c rpm-4.5.90.git8461.new/python/rpmmodule.c
--- rpm-4.5.90.git8461.orig/python/rpmmodule.c	2008-06-30 08:15:38.000000000 -0400
+++ rpm-4.5.90.git8461.new/python/rpmmodule.c	2008-09-18 11:25:08.000000000 -0400
@@ -21,6 +21,7 @@
 #include "rpmte-py.h"
 #include "rpmts-py.h"
 #include "spec-py.h"
+#include "pkg-py.h"
 
 #include "debug.h"
 
@@ -247,6 +248,7 @@ void init_rpm(void)
     if (PyType_Ready(&rpmte_Type) < 0) return;
     if (PyType_Ready(&rpmts_Type) < 0) return;
     if (PyType_Ready(&spec_Type) < 0) return;
+    if (PyType_Ready(&pkg_Type) < 0) return;
 #endif
 
     m = Py_InitModule3("_rpm", rpmModuleMethods, rpm__doc__);
@@ -304,6 +306,9 @@ void init_rpm(void)
 
     Py_INCREF(&spec_Type);
     PyModule_AddObject(m, "spec", (PyObject *) &spec_Type);
+
+    Py_INCREF(&pkg_Type);
+    PyModule_AddObject(m, "pkg", (PyObject *) &pkg_Type);
 #else
     hdr_Type.ob_type = &PyType_Type;
     rpmal_Type.ob_type = &PyType_Type;
@@ -315,6 +320,7 @@ void init_rpm(void)
     rpmte_Type.ob_type = &PyType_Type;
     rpmts_Type.ob_type = &PyType_Type;
     spec_Type.ob_type =  &PyType_Type;
+    pkg_Type.ob_type =  &PyType_Type;
 #endif
 
     dict = PyDict_New();
@@ -492,5 +498,12 @@ void init_rpm(void)
     REGISTER_ENUM(RPMDBI_PACKAGES);
 
     REGISTER_ENUM((int)RPMAL_NOMATCH);
+
+    /* Sync with build/rpmspec.h */
+    REGISTER_ENUM(RPMBUILD_ISSOURCE);
+    REGISTER_ENUM(RPMBUILD_ISPATCH);
+    REGISTER_ENUM(RPMBUILD_ISICON);
+    REGISTER_ENUM(RPMBUILD_ISNO);
+
 }
 
diff -rupN rpm-4.5.90.git8461.orig/python/spec-py.c rpm-4.5.90.git8461.new/python/spec-py.c
--- rpm-4.5.90.git8461.orig/python/spec-py.c	2008-06-26 05:26:01.000000000 -0400
+++ rpm-4.5.90.git8461.new/python/spec-py.c	2008-09-18 07:24:45.000000000 -0400
@@ -5,6 +5,7 @@
 #include "system.h"
 
 #include "spec-py.h"
+#include "pkg-py.h"
 
 /** \ingroup python
  * \name Class: Rpmspec
@@ -147,13 +148,40 @@ spec_get_sources(specObject *s)
 
 }
 
+static PyObject *
+spec_get_packages(specObject *s)
+{
+    Package pkg;
+    PyObject *packageList, *pkgObj;
+    rpmSpec spec;
+
+    packageList = PyList_New(0);
+    spec = specFromSpec(s);
+    if ( spec != NULL) {
+        pkg = spec->packages;
+
+        while (pkg != NULL) {
+            pkgObj = (PyObject *)pkg_Wrap(pkg);
+            PyList_Append(packageList, pkgObj);
+            pkg=pkg->next;
+        } 
+
+        return PyList_AsTuple(packageList);
+    }
+    else {
+        return NULL;
+    }
+
+}
+
 /**
  */
 
-static char spec_doc[] = "RPM Spec file object";
+static char spec_doc[] = "RPM Spec file package object";
 
 static PyMethodDef spec_Spec_methods[] = {
     {"sources",   (PyCFunction) spec_get_sources, METH_VARARGS,  NULL },
+    {"packages",   (PyCFunction) spec_get_packages, METH_VARARGS,  NULL },
     {"prep",   (PyCFunction) spec_get_prep, METH_VARARGS,  NULL },
     {"build",   (PyCFunction) spec_get_build, METH_VARARGS,  NULL },
     {"install",   (PyCFunction) spec_get_install, METH_VARARGS,  NULL },


-- 
|: Red Hat, Engineering, London   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|



More information about the Rpm-maint mailing list