Robotframework: Regression with keywords implemented as methods with wrapping decorator

Created on 28 Apr 2020  路  3Comments  路  Source: robotframework/robotframework


_This regression in RF 3.2 affects at least AppiumLibrary (#3559) and FakerLibrary (#3560)._


If a keyword is implemented as a method in a class and the method is decorated with a "wrapping decorator", argument detection doesn't work correctly. A "wrapping decorator" is a decorator that sets the __wrapped__ attribute using functools.wraps or otherwise.

The following is enough to reproduce the problem. Running the test fails because Robot Framework incorrectly things that Keyword requires one argument.

from functools import wraps


def decorator(func):
    @wraps(func)
    def wrapper(*args, **kws):
        return func(*args, **kws)
    return wrapper


class ExampleLibrary:

    @decorator
    def keyword(self):
        pass
*** Settings ***
Library          ExampleLibrary.py

*** Test Cases ***
Example
    Keyword

Prior to Robot Framework 3.2 arguments of wrapped methods like the above were not seen at all and Robot just blindly accepted all arguments. This was changed by #3027 that added inspect.unwrap to our argument resolving logic. The PR implementing that feature didn't actually yet cause this issue because it used code like inspect.getfullargspec(inspect.unwrap)) which is fine. Unfortunately the PR only added tests for unwrapping functions, not methods, so when the code was changed later this bug wasn't detected.

This was broken as part of refactoring in fa5ad5153f8ea77e70b4c07a1561810aac78f169 when code like hander = inspect.unwrap(hander) was introduced because it affected also inspect.ismethod(hander) call a bit later. As the result the handler wasn't detected to be a method and the self argument wasn't dropped from the argument list.

bug critical

Most helpful comment

This issue is already fixed, but I decided to keep this issue open to have it visible in the issue tracker until RF 3.2.1 is out.

All 3 comments

Issue #3560 demonstrates a concrete problem caused by this issue with FakerLibrary. FakerLibrary exposes Faker functionality directly (it uses the hybrid library API) and some of the methods it exposes are decorated so that the decorator uses functools.wraps().

Issue #3559 that affects AppiumLibrary seems to be caused by the same underlying issue as well. Instead of functools.wraps() it uses the decorator module that also sets the __wrapped__ attribute.

Due to the problems with two widely used libraries it is clear that we need RF 3.2.1 release pretty soon, possibly already this week. It is very unfortunate nobody tested RF 3.2 release candidates with these libraries because then the problem could have been fixed already earlier.

This problem was fixed by b43f5823407030940823ae2a477ac6f5b98c3ed1 and the fix has been verified both with AppiumLibrary (#3559) and FakerLibrary (#3560). If you want to test the fix in your environment, you can install the latest code with this command:

pip install https://github.com/robotframework/robotframework/archive/master.zip

RF 3.2.1 with the fix will be released next Monday. Please continue using RF 3.2, or the fixed version, until that so we learn about possible other issues and can get them fixed as well.

This issue is already fixed, but I decided to keep this issue open to have it visible in the issue tracker until RF 3.2.1 is out.

Was this page helpful?
0 / 5 - 0 ratings