summaryrefslogtreecommitdiffstats
path: root/contrib/python/allure-pytest/allure_pytest/stash.py
blob: 31d9302b80278faf5f2741aa3eb6a072eea78ba9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import pytest
from functools import wraps

HAS_STASH = hasattr(pytest, 'StashKey')


def create_stashkey_safe():
    """
    If pytest stash is available, returns a new stash key.
    Otherwise, returns `None`.
    """

    return pytest.StashKey() if HAS_STASH else None


def stash_get_safe(item, key):
    """
    If pytest stash is available and contains the key, retrieves the associated value.
    Otherwise, returns `None`.
    """

    if HAS_STASH and key in item.stash:
        return item.stash[key]


def stash_set_safe(item: pytest.Item, key, value):
    """
    If pytest stash is available, associates the value with the key in the stash.
    Otherwise, does nothing.
    """

    if HAS_STASH:
        item.stash[key] = value


def stashed(arg=None):
    """
    Cashes the result of the decorated function in the pytest item stash.
    The first argument of the function must be a pytest item.

    In pytest<7.0 the stash is not available, so the decorator does nothing.
    """

    key = create_stashkey_safe() if arg is None or callable(arg) else arg

    def decorator(func):
        if not HAS_STASH:
            return func

        @wraps(func)
        def wrapper(item, *args, **kwargs):
            if key in item.stash:
                return item.stash[key]

            value = func(item, *args, **kwargs)
            item.stash[key] = value
            return value

        return wrapper

    return decorator(arg) if callable(arg) else decorator