1

I'm trying to invoke a python function from robotframework keyword. The python function has been decorated to be invoked using run_keyword from Builtin library. This is because robot logs appear well structured if library functions are invoked via run_keyword function from built in library. rather than invoked directly. However this is resulting in an infinite loop. Is there a solution to gracefully accomplish the goal?

robotkeyword :

do something
#creates a user by calling a function from python based library
create user

python function
@wrap_with_run_keyword
def create_user():
    pass

def wrap_with_run_keyword(func):
    def func_wrapper(*args, **kwargs):
        return run_keyword(func, *args, **kwargs)
    return func_wrapper

I couldn't solve the problem using partial application.

However, I broker the recursive loop by setting and unsetting an attribute as give below.

def wrap_with_run_keyword(func):
def func_wrapper(*args, **kwargs):
    if not hasattr(func, 'second'):
        setattr(func, "second", True)
        return run_keyword(func, *args, **kwargs)
    else:
        delattr(func, "second")
        return func(*args, **kwargs)

return func_wrapper

I have however run into another problem. I defined create_user as follows

def create_user(properties):
    #some code
    pass

On Calling this function in the way below

create_user("name=abc")

I'm getting the following error : got an unexpected keyword argument 'name'

decoder
  • 23
  • 3
  • Why are you calling the keyword "create user" when you call the keyword "create user"? You've created a keyword that calls itself. Are you intending to create a _new_ keyword that calls _an existing_ keyword from some other library? And what do you mean by "well structured"? There should be no difference in the logs if you call the keyword directly vs via "run keyword", except in the latter case you have one extra level of nesting. – Bryan Oakley Apr 22 '16 at 11:21
  • @BryanOakley there is a difference in the way logs are formed. If you call a library keyword from robot, it appears nicely nested. However, if your library further calls another function/keyword it appears flat at the same level. However, if you call one library function from another via run keyword, the nesting also appears in the logs in a tree sort of structure make it much more readable. – decoder Apr 25 '16 at 09:26

2 Answers2

1

I did run in the same issue, but solved it, only wondering if i can detect the caller...if the call is done from robotframework or by python in case that the call is done by the rf it should do only the second call

    @wraps(function)
    def wrapper(self, *args, **kwargs):

        if not hasattr(function, 'second'):
            setattr(function, 'second', True)
            ar= list(args)
            for key, value in kwargs.items():                    
                ar.append(value)     
            return BuiltIn().run_keyword('Mylib.' + function.__name__, ar)
        else:
            delattr(function, 'second')
            return function(self,*args[0])
    return wrapper
ruud
  • 23
  • 4
-2

Take a look at the partial class from the functools module. I think this might help you.

Or take a look at how decorators work in python.

Community
  • 1
  • 1
salomonderossi
  • 2,180
  • 14
  • 20