python: xml_parser: Callbacks interface is similar as c interface since now.
authorTomas Mlcoch <xtojaj@gmail.com>
Sat, 1 Jun 2013 16:35:01 +0000 (18:35 +0200)
committerTomas Mlcoch <xtojaj@gmail.com>
Sat, 1 Jun 2013 16:35:01 +0000 (18:35 +0200)
src/python/xml_parser-py.c
tests/python/tests/test_xml_parser.py

index a4e6756..b46a7c0 100644 (file)
@@ -80,18 +80,19 @@ c_pkgcb(cr_Package *pkg,
         void *cbdata,
         GError **err)
 {
-    PyObject *result;
+    PyObject *arglist, *result, *py_pkg;
     CbData *data = cbdata;
 
-    CR_UNUSED(pkg);
+    if (data->py_pkg)
+        py_pkg = data->py_pkg;
+    else
+        py_pkg = Object_FromPackage(pkg, 1);
 
-    if (data->py_pkg) {
-        // Decref ref count on processed package
-        Py_DECREF(data->py_pkg);
-        data->py_pkg = NULL;
-    }
-
-    result = PyObject_CallObject(data->py_pkgcb, NULL);
+    arglist = Py_BuildValue("(O)", py_pkg);
+    result = PyObject_CallObject(data->py_pkgcb, arglist);
+    Py_DECREF(arglist);
+    Py_DECREF(py_pkg);
+    data->py_pkg = NULL;
 
     if (result == NULL) {
         // Exception raised
@@ -146,8 +147,8 @@ py_xml_parse_primary(PyObject *self, PyObject *args)
         return NULL;
     }
 
-    if (!PyCallable_Check(py_newpkgcb)) {
-        PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable");
+    if (!PyCallable_Check(py_newpkgcb) && py_newpkgcb != Py_None) {
+        PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable or None");
         return NULL;
     }
 
@@ -161,13 +162,21 @@ py_xml_parse_primary(PyObject *self, PyObject *args)
         return NULL;
     }
 
+    if (py_newpkgcb == Py_None && py_pkgcb == Py_None) {
+        PyErr_SetString(PyExc_TypeError, "both pkgcb and newpkgcb cannot be None");
+        return NULL;
+    }
+
     Py_XINCREF(py_newpkgcb);
     Py_XINCREF(py_pkgcb);
     Py_XINCREF(py_warningcb);
 
+    cr_XmlParserNewPkgCb    ptr_c_newpkgcb  = NULL;
     cr_XmlParserPkgCb       ptr_c_pkgcb     = NULL;
     cr_XmlParserWarningCb   ptr_c_warningcb = NULL;
 
+    if (py_newpkgcb != Py_None)
+        ptr_c_newpkgcb = c_newpkgcb;
     if (py_pkgcb != Py_None)
         ptr_c_pkgcb = c_pkgcb;
     if (py_warningcb != Py_None)
@@ -179,7 +188,7 @@ py_xml_parse_primary(PyObject *self, PyObject *args)
     cbdata.py_pkg       = NULL;
 
     cr_xml_parse_primary(filename,
-                         c_newpkgcb,
+                         ptr_c_newpkgcb,
                          &cbdata,
                          ptr_c_pkgcb,
                          &cbdata,
@@ -220,8 +229,8 @@ py_xml_parse_filelists(PyObject *self, PyObject *args)
         return NULL;
     }
 
-    if (!PyCallable_Check(py_newpkgcb)) {
-        PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable");
+    if (!PyCallable_Check(py_newpkgcb) && py_newpkgcb != Py_None) {
+        PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable or None");
         return NULL;
     }
 
@@ -235,13 +244,21 @@ py_xml_parse_filelists(PyObject *self, PyObject *args)
         return NULL;
     }
 
+    if (py_newpkgcb == Py_None && py_pkgcb == Py_None) {
+        PyErr_SetString(PyExc_TypeError, "both pkgcb and newpkgcb cannot be None");
+        return NULL;
+    }
+
     Py_XINCREF(py_newpkgcb);
     Py_XINCREF(py_pkgcb);
     Py_XINCREF(py_warningcb);
 
+    cr_XmlParserNewPkgCb    ptr_c_newpkgcb  = NULL;
     cr_XmlParserPkgCb       ptr_c_pkgcb     = NULL;
     cr_XmlParserWarningCb   ptr_c_warningcb = NULL;
 
+    if (py_newpkgcb != Py_None)
+        ptr_c_newpkgcb = c_newpkgcb;
     if (py_pkgcb != Py_None)
         ptr_c_pkgcb = c_pkgcb;
     if (py_warningcb != Py_None)
@@ -253,7 +270,7 @@ py_xml_parse_filelists(PyObject *self, PyObject *args)
     cbdata.py_pkg       = NULL;
 
     cr_xml_parse_filelists(filename,
-                           c_newpkgcb,
+                           ptr_c_newpkgcb,
                            &cbdata,
                            ptr_c_pkgcb,
                            &cbdata,
@@ -293,8 +310,8 @@ py_xml_parse_other(PyObject *self, PyObject *args)
         return NULL;
     }
 
-    if (!PyCallable_Check(py_newpkgcb)) {
-        PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable");
+    if (!PyCallable_Check(py_newpkgcb) && py_newpkgcb != Py_None) {
+        PyErr_SetString(PyExc_TypeError, "newpkgcb must be callable or None");
         return NULL;
     }
 
@@ -308,13 +325,21 @@ py_xml_parse_other(PyObject *self, PyObject *args)
         return NULL;
     }
 
+    if (py_newpkgcb == Py_None && py_pkgcb == Py_None) {
+        PyErr_SetString(PyExc_TypeError, "both pkgcb and newpkgcb cannot be None");
+        return NULL;
+    }
+
     Py_XINCREF(py_newpkgcb);
     Py_XINCREF(py_pkgcb);
     Py_XINCREF(py_warningcb);
 
+    cr_XmlParserNewPkgCb    ptr_c_newpkgcb  = NULL;
     cr_XmlParserPkgCb       ptr_c_pkgcb     = NULL;
     cr_XmlParserWarningCb   ptr_c_warningcb = NULL;
 
+    if (py_newpkgcb != Py_None)
+        ptr_c_newpkgcb = c_newpkgcb;
     if (py_pkgcb != Py_None)
         ptr_c_pkgcb = c_pkgcb;
     if (py_warningcb != Py_None)
@@ -326,7 +351,7 @@ py_xml_parse_other(PyObject *self, PyObject *args)
     cbdata.py_pkg       = NULL;
 
     cr_xml_parse_other(filename,
-                       c_newpkgcb,
+                       ptr_c_newpkgcb,
                        &cbdata,
                        ptr_c_pkgcb,
                        &cbdata,
index 5385f68..fff7167 100644 (file)
@@ -22,7 +22,7 @@ class TestCaseXmlParserPrimary(unittest.TestCase):
             userdata["pkgs"].append(pkg)
             return pkg
 
-        def pkgcb():
+        def pkgcb(pkg):
             userdata["pkgcb_calls"] += 1
 
         def warningcb(warn_type, msg):
@@ -96,7 +96,7 @@ class TestCaseXmlParserPrimary(unittest.TestCase):
             userdata["pkgs"].append(pkg)
             return pkg
 
-        def pkgcb():
+        def pkgcb(pkg):
             userdata["pkgcb_calls"] += 1
 
         def warningcb(warn_type, msg):
@@ -109,6 +109,23 @@ class TestCaseXmlParserPrimary(unittest.TestCase):
         self.assertEqual(userdata["pkgcb_calls"], 2)
         self.assertEqual(userdata["warnings"], [])
 
+    def test_xml_parser_primary_repo02_only_pkgcb(self):
+
+        pkgs = []
+
+        def pkgcb(pkg):
+            pkgs.append(pkg)
+
+        cr.xml_parse_primary(REPO_02_PRIXML, None, pkgcb, None, 1)
+
+        self.assertEqual([pkg.name for pkg in pkgs],
+            ['fake_bash', 'super_kernel'])
+
+    def test_xml_parser_primary_repo02_no_cbs(self):
+        self.assertRaises(TypeError,
+                          cr.xml_parse_primary,
+                          REPO_02_PRIXML, None, None, None, 1)
+
     def test_xml_parser_primary_warnings(self):
 
         userdata = {
@@ -165,7 +182,7 @@ class TestCaseXmlParserPrimary(unittest.TestCase):
     def test_xml_parser_primary_pkgcb_abort(self):
         def newpkgcb(pkgId, name, arch):
             return cr.Package()
-        def pkgcb():
+        def pkgcb(pkg):
             raise Error("Foo error")
         self.assertRaises(cr.CreaterepoCError,
                           cr.xml_parse_primary,
@@ -196,7 +213,7 @@ class TestCaseXmlParserFilelists(unittest.TestCase):
             userdata["pkgs"].append(pkg)
             return pkg
 
-        def pkgcb():
+        def pkgcb(pkg):
             userdata["pkgcb_calls"] += 1
 
         def warningcb(warn_type, msg):
@@ -257,7 +274,7 @@ class TestCaseXmlParserFilelists(unittest.TestCase):
             userdata["pkgs"].append(pkg)
             return pkg
 
-        def pkgcb():
+        def pkgcb(pkg):
             userdata["pkgcb_calls"] += 1
 
         def warningcb(warn_type, msg):
@@ -270,6 +287,23 @@ class TestCaseXmlParserFilelists(unittest.TestCase):
         self.assertEqual(userdata["pkgcb_calls"], 2)
         self.assertEqual(userdata["warnings"], [])
 
+    def test_xml_parser_filelists_repo02_only_pkgcb(self):
+
+        pkgs = []
+
+        def pkgcb(pkg):
+            pkgs.append(pkg)
+
+        cr.xml_parse_filelists(REPO_02_FILXML, None, pkgcb, None)
+
+        self.assertEqual([pkg.name for pkg in pkgs],
+            ['fake_bash', 'super_kernel'])
+
+    def test_xml_parser_filelists_repo02_no_cbs(self):
+        self.assertRaises(TypeError,
+                          cr.xml_parse_filelists,
+                          REPO_02_FILXML, None, None, None)
+
     def test_xml_parser_filelists_warnings(self):
 
         userdata = {
@@ -322,7 +356,7 @@ class TestCaseXmlParserFilelists(unittest.TestCase):
     def test_xml_parser_filelists_pkgcb_abort(self):
         def newpkgcb(pkgId, name, arch):
             return cr.Package()
-        def pkgcb():
+        def pkgcb(pkg):
             raise Error("Foo error")
         self.assertRaises(cr.CreaterepoCError,
                           cr.xml_parse_filelists,
@@ -353,7 +387,7 @@ class TestCaseXmlParserOther(unittest.TestCase):
             userdata["pkgs"].append(pkg)
             return pkg
 
-        def pkgcb():
+        def pkgcb(pkg):
             userdata["pkgcb_calls"] += 1
 
         def warningcb(warn_type, msg):
@@ -418,7 +452,7 @@ class TestCaseXmlParserOther(unittest.TestCase):
             userdata["pkgs"].append(pkg)
             return pkg
 
-        def pkgcb():
+        def pkgcb(pkg):
             userdata["pkgcb_calls"] += 1
 
         def warningcb(warn_type, msg):
@@ -431,6 +465,23 @@ class TestCaseXmlParserOther(unittest.TestCase):
         self.assertEqual(userdata["pkgcb_calls"], 2)
         self.assertEqual(userdata["warnings"], [])
 
+    def test_xml_parser_other_repo02_only_pkgcb(self):
+
+        pkgs = []
+
+        def pkgcb(pkg):
+            pkgs.append(pkg)
+
+        cr.xml_parse_other(REPO_02_OTHXML, None, pkgcb, None)
+
+        self.assertEqual([pkg.name for pkg in pkgs],
+            ['fake_bash', 'super_kernel'])
+
+    def test_xml_parser_other_repo02_no_cbs(self):
+        self.assertRaises(TypeError,
+                          cr.xml_parse_other,
+                          REPO_02_OTHXML, None, None, None)
+
     def test_xml_parser_other_warnings(self):
 
         userdata = {
@@ -483,7 +534,7 @@ class TestCaseXmlParserOther(unittest.TestCase):
     def test_xml_parser_other_pkgcb_abort(self):
         def newpkgcb(pkgId, name, arch):
             return cr.Package()
-        def pkgcb():
+        def pkgcb(pkg):
             raise Error("Foo error")
         self.assertRaises(cr.CreaterepoCError,
                           cr.xml_parse_other,