Hi. Current libapparmor python bindings are very "unpythonic". Also lack ability to access "why" information in case of failure.
In python when something fail the normal behaviour is exception to occur. In case of apparmor functions die silently and require user to verify returned value. And here comes second problem. In C api when return value is -1 (and the same value is returned in python API) we can access errno to get information why this occured. Unfortunately in python there is no way to access the same information. Pythonic way of accessing errno is via exception (which is never raised in python bindings currently). So the patch adds exceptions on failures. First %exception creates a wrapper that swig adds to each function listed below. Empty %exception causes that the rest of code (beside listed functions) won't be wrapped. How this works? Example on apparmor disabled system: Before: >>> LibAppArmor.aa_change_hat(hat, random.randint(1, sys.maxint)) -1 After: >>> LibAppArmor.aa_change_hat(hat, random.randint(1, sys.maxint)) Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [Errno 22] Invalid argument so pythonic way of accessing "why": >>> try: ... LibAppArmor.aa_change_hat(hat, random.randint(1, sys.maxint)) ... except OSError, e: ... print e.errno ... 22 Signed-off-by: Arkadiusz Miśkiewicz <[email protected]> diff -urN apparmor-2.8.3.org/libraries/libapparmor/swig/SWIG/libapparmor.i apparmor-2.8.3/libraries/libapparmor/swig/SWIG/libapparmor.i --- apparmor-2.8.3.org/libraries/libapparmor/swig/SWIG/libapparmor.i 2011-08-09 15:48:56.000000000 +0200 +++ apparmor-2.8.3/libraries/libapparmor/swig/SWIG/libapparmor.i 2014-03-07 12:32:04.000000000 +0100 @@ -9,6 +9,16 @@ %include "typemaps.i" %include "aalogparse.h" +#ifdef SWIGPYTHON +%exception { + $action + if (result < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } +} +#endif + /* swig doesn't like the macro magic we do in apparmor.h so the fn prototypes * are manually inserted here */ @@ -27,3 +37,5 @@ extern int aa_getcon(char **con, char **mode); extern int aa_getpeercon_raw(int fd, char *buffer, int *size); extern int aa_getpeercon(int fd, char **con); + +%exception; -- Arkadiusz Miśkiewicz, arekm / maven.pl -- AppArmor mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
