Permit comparison operator strings (<, >= etc) in python ds constructor
authorPanu Matilainen <pmatilai@redhat.com>
Thu, 16 Dec 2010 12:11:25 +0000 (14:11 +0200)
committerPanu Matilainen <pmatilai@redhat.com>
Tue, 21 Dec 2010 09:49:51 +0000 (11:49 +0200)
- Creating ('foo', '>=', '1.2') dependency is much nicer than
  or'ing rpm.RPMSENSE_FOO for flags. Allow (but validate) the string
  usage, ints get passed as is.
(cherry picked from commit bf37b06d19b769572c06a667b31164d6ed279155)

python/rpmds-py.c

index cd933b5..7729d85 100644 (file)
@@ -263,6 +263,45 @@ static int rpmds_init(rpmdsObject * s, PyObject *args, PyObject *kwds)
     return 0;
 }
 
+static int depflags(PyObject *o, rpmsenseFlags *senseFlags)
+{
+    int ok = 0;
+    PyObject *str = NULL;
+    rpmsenseFlags flags = RPMSENSE_ANY;
+
+    if (PyInt_Check(o)) {
+       ok = 1;
+       flags = PyInt_AsLong(o);
+    } else if (utf8FromPyObject(o, &str)) {
+       ok = 1;
+       for (const char *s = PyBytes_AsString(str); *s; s++) {
+           switch (*s) {
+           case '=':
+               flags |= RPMSENSE_EQUAL;
+               break;
+           case '<':
+               flags |= RPMSENSE_LESS;
+               break;
+           case '>':
+               flags |= RPMSENSE_GREATER;
+               break;
+           default:
+               ok = 0;
+               break;
+           }
+       }
+       Py_DECREF(str);
+    }
+
+    if (flags == (RPMSENSE_EQUAL|RPMSENSE_LESS|RPMSENSE_GREATER))
+       ok = 0;
+
+    if (ok)
+       *senseFlags = flags;
+
+    return ok;
+}
+
 static PyObject * rpmds_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
 {
     PyObject *obj;
@@ -279,8 +318,12 @@ static PyObject * rpmds_new(PyTypeObject * subtype, PyObject *args, PyObject *kw
        const char *name = NULL;
        const char *evr = NULL;
        rpmsenseFlags flags = RPMSENSE_ANY;
-       if (PyArg_ParseTuple(obj, "s|is", &name, &flags, &evr)) {
+       /* TODO: if flags are specified, evr should be required too */
+       if (PyArg_ParseTuple(obj, "s|O&s", &name, depflags, &flags, &evr)) {
            ds = rpmdsSingle(tagN, name, evr, flags);
+       } else {
+           PyErr_SetString(PyExc_ValueError, "invalid dependency tuple");
+           return NULL;
        }
     } else if (hdrFromPyObject(obj, &h)) {
        if (tagN == RPMTAG_NEVR) {