[Tutor] How to wrap ctype functions
Hugo Arts
hugo.yoshi at gmail.com
Wed Mar 3 22:44:35 CET 2010
On Wed, Mar 3, 2010 at 6:43 PM, Jan Jansen <knacktus at googlemail.com> wrote:
> Hi there,
>
> I wonder what's the best way to wrap given function calls (in this case
> ctype function calls but more generally built-in functions and those kinds).
> I have a huge c library and almost all functions return an error code. The
> library also contains a function, that returns the corresponding error
> message to the error code. So, what I need to do for every call to one of
> the libraries functions looks like this:
>
> error_code = my_c_library.SOME_FUNCTION_
> CALL(argument)
> if error_code != 0:
> error_message = my_c_library.GET_ERROR_TEXT(error_code)
> print "error in function call SOME_FUNCTION_CALL"
> print error_message
> my_c_library.EXIT_AND_CLEAN_UP()
>
> Also, for some function calls I would need to do some preperations like:
>
> error_code = my_c_library.LOG_IN_AS_ADMINISTRATOR(admin_user,
> admin_password)
> error_code = my_c_library.SOME_FUNCTION_CALL(argument)
>
> I like the decorator idea, but I can't figure out if it's applicable here.
> To be able to call the function in a manner like this would be great, e.g.
>
> @change_user(admin_user, admin_password)
> @error_handling
> my_c_library.SOME_FUNCTION_CALL(argument)
>
Well, decorators only work on function definitions, not function
calls. What you could do is
a) write a function that takes your c function as an argument and does
the error handling for you
would probably look something like this:
def call_with_errorhandling(func, *args):
error_code = func(*args)
if error_code != 0:
error_message = my_c_library.GET_ERROR_TEXT(error_code)
print "error in function call SOME_FUNCTION_CALL"
print error_message
my_c_library.EXIT_AND_CLEAN_UP()
b) wrap all your c functions in a python function that does error handling.
the wrapper/decorator would look somewhat like this:
from functools import wraps
def with_error_handling(func):
@wraps(func)
def new_func(*args):
error_code = func(*args)
if error_code != 0:
error_message = my_c_library.GET_ERROR_TEXT(error_code)
print "error in function call SOME_FUNCTION_CALL"
print error_message
my_c_library.EXIT_AND_CLEAN_UP()
return new_func
and you'd wrap functions with it like so:
# old syntax
wrapped_function = with_error_handling(library.some_C_function)
#decorator syntax
@with_error_handling
def wrapped_function(*args)
return library.some_C_function(*args)
#just call your wrapped function now, the error handling will take place.
wrapped_function(argument)
You can write similar functions that do admin login in both ways. Both
approaches wrap C functions in python functions, so the overhead
should be about the same (the decorator way should consume somewhat
more memory, since it creates a new function object for everything you
wrap, but it's probably not very significant).
HTH,
Hugo
More information about the Tutor
mailing list