[Tutor] How to wrap ctype functions

Steven D'Aprano steve at pearwood.info
Wed Mar 3 23:17:51 CET 2010


On Thu, 4 Mar 2010 04:43:28 am Jan Jansen 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()


Something like this:

class MyCLibraryError(ValueError):  # Create our own exception.
    pass


import functools
def decorate_error_code(func):
    @functools.wraps(func)
    def inner(*args, **kwargs):
        error_code = func(*args, **kwargs)
        if error_code != 0:
            msg = my_c_library.GET_ERROR_TEXT(error_code)
            my_c_library.EXIT_AND_CLEAN_UP()
            raise MyCLibraryError(msg)
    return inner  # note *no* brackets

Then wrap the functions:

some_function_call = decorate_error_code(
    my_c_library.SOME_FUNCTION_CALL)
another_function_call = decorate_error_code(
    my_c_library.ANOTHER_FUNCTION_CALL)



> 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)

That's not how the decorator syntax works. You can only use the 
@decorator syntax immediately above a function definition:

@error_handling
def some_function():
    ...


Otherwise, you use the decorator like a function, you give the name of 
another function as argument, and it returns a new function:

new_function = error_handling(some_function)




-- 
Steven D'Aprano


More information about the Tutor mailing list