]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
lib/smbconf: expose smbconf error codes to python wrapper
authorJohn Mulligan <jmulligan@redhat.com>
Mon, 6 Jun 2022 19:55:22 +0000 (15:55 -0400)
committerGünther Deschner <gd@samba.org>
Wed, 8 Jun 2022 13:13:10 +0000 (13:13 +0000)
The smbconf library defines an enum of error codes that can be returned
from the C calls. The error codes were getting stored in the python
SMBConfError type but it was not easy to access or obvious what the
integer code represented.

This change makes it easier to get the returned error code: via a
`error_code` attribute on the exception value. It also exposes the
integer constants to the module. Simple tests for a few of the more
obvious error codes check that this new error handling correctly
exposes the error code values.

Signed-off-by: John Mulligan <jmulligan@redhat.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
Autobuild-User(master): Günther Deschner <gd@samba.org>
Autobuild-Date(master): Wed Jun  8 13:13:10 UTC 2022 on sn-devel-184

lib/smbconf/pysmbconf.c
python/samba/tests/smbconf.py

index b0aca4508af16466d53f20de6aeab830d85071bc..1b3c101005ab98858d68032f7eb81844df0c6e55 100644 (file)
@@ -35,7 +35,6 @@ static void py_raise_SMBConfError(sbcErr err)
 
        /*
         * TODO: have the exception type accept arguments in new/init
-        * and make the error value accessible as a property
         */
        args = Py_BuildValue("(is)", err, sbcErrorString(err));
        if (args == NULL) {
@@ -44,11 +43,22 @@ static void py_raise_SMBConfError(sbcErr err)
                return;
        }
        v = PyObject_Call(PyExc_SMBConfError, args, NULL);
-       Py_DECREF(args);
-       if (v != NULL) {
-               PyErr_SetObject((PyObject *) Py_TYPE(v), v);
-               Py_DECREF(v);
+       if (v == NULL) {
+               Py_CLEAR(args);
+               return;
+       }
+       /*
+        * It's clearer to set an explicit error_code attribute for use in calling
+        * code to check what kind of SMBConfError was raised.
+        */
+       if (PyObject_SetAttrString(v, "error_code", PyTuple_GetItem(args, 0)) == -1) {
+               Py_CLEAR(v);
+               Py_CLEAR(args);
+               return;
        }
+       Py_CLEAR(args);
+       PyErr_SetObject((PyObject *) Py_TYPE(v), v);
+       Py_DECREF(v);
 }
 
 /*
@@ -780,5 +790,24 @@ MODULE_INIT_FUNC(smbconf)
                return NULL;
        }
 
+/*
+ * ADD_FLAGS macro borrowed from source3/libsmb/pylibsmb.c
+ */
+#define ADD_FLAGS(val) PyModule_AddObject(m, #val, PyLong_FromLong(val))
+
+       ADD_FLAGS(SBC_ERR_OK);
+       ADD_FLAGS(SBC_ERR_NOT_IMPLEMENTED);
+       ADD_FLAGS(SBC_ERR_NOT_SUPPORTED);
+       ADD_FLAGS(SBC_ERR_UNKNOWN_FAILURE);
+       ADD_FLAGS(SBC_ERR_NOMEM);
+       ADD_FLAGS(SBC_ERR_INVALID_PARAM);
+       ADD_FLAGS(SBC_ERR_BADFILE);
+       ADD_FLAGS(SBC_ERR_NO_SUCH_SERVICE);
+       ADD_FLAGS(SBC_ERR_IO_FAILURE);
+       ADD_FLAGS(SBC_ERR_CAN_NOT_COMPLETE);
+       ADD_FLAGS(SBC_ERR_NO_MORE_ITEMS);
+       ADD_FLAGS(SBC_ERR_FILE_EXISTS);
+       ADD_FLAGS(SBC_ERR_ACCESS_DENIED);
+
        return m;
 }
index e023e2ad59b148ff9518996db33473bb8871f987..1f432a346088920fcb6c29436b763ba93390de10 100644 (file)
@@ -324,6 +324,27 @@ class SMBConfTests(samba.tests.TestCase):
         names = sconf.share_names()
         self.assertEqual(names, ["hello", "goodnight"])
 
+    def test_error_badfile(self):
+        with self.assertRaises(self.smbconf.SMBConfError) as raised:
+            self.smbconf.init_txt("/foo/bar/baz/_I-dont/.exist/-ok-")
+        self.assertEqual(
+            self.smbconf.SBC_ERR_BADFILE, raised.exception.error_code)
+
+    def test_error_not_supported(self):
+        sconf = self.smbconf.init_txt(self.example_conf_default)
+        with self.assertRaises(self.smbconf.SMBConfError) as raised:
+            sconf.set_global_parameter("client min protocol", "NT1")
+        self.assertEqual(
+            self.smbconf.SBC_ERR_NOT_SUPPORTED, raised.exception.error_code)
+
+    def test_error_no_such_service(self):
+        sconf = self.smbconf.init_txt(self.example_conf_default)
+        with self.assertRaises(self.smbconf.SMBConfError) as raised:
+            sconf.get_share("zilch"),
+        self.assertEqual(
+            self.smbconf.SBC_ERR_NO_SUCH_SERVICE, raised.exception.error_code)
+
+
 
 if __name__ == "__main__":
     import unittest