File: reference.py

package info (click to toggle)
python-testbook 0.4.2-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 408 kB
  • sloc: python: 1,045; makefile: 11
file content (93 lines) | stat: -rw-r--r-- 3,009 bytes parent folder | download | duplicates (2)
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from .exceptions import (
    TestbookExecuteResultNotFoundError,
    TestbookAttributeError,
    TestbookSerializeError,
    TestbookRuntimeError
)
from .utils import random_varname
from .translators import PythonTranslator


class TestbookObjectReference:
    def __init__(self, tb, name):
        self.tb = tb
        self.name: str = name

    @property
    def _type(self):
        return self.tb.value(f"type({self.name}).__name__")

    def __repr__(self):
        return repr(self.tb.value(f"repr({self.name})"))

    def __getattr__(self, name):
        if self.tb.value(f"hasattr({self.name}, '{name}')"):
            return TestbookObjectReference(self.tb, f"{self.name}.{name}")

        raise TestbookAttributeError(f"'{self._type}' object has no attribute {name}")

    def __eq__(self, rhs):
        return self.tb.value(
            "{lhs} == {rhs}".format(lhs=self.name, rhs=PythonTranslator.translate(rhs))
        )

    def __len__(self):
        return self.tb.value(f"len({self.name})")

    def __iter__(self):
        iterobjectname = f"___iter_object_{random_varname()}"
        self.tb.inject(f"""
            {iterobjectname} = iter({self.name})
        """)
        return TestbookObjectReference(self.tb, iterobjectname)

    def __next__(self):
        try:
            return self.tb.value(f"next({self.name})")
        except TestbookRuntimeError as e:
            if e.eclass is StopIteration:
                raise StopIteration
            else:
                raise

    def __getitem__(self, key):
        try:
            return self.tb.value(f"{self.name}.__getitem__({PythonTranslator.translate(key)})")
        except TestbookRuntimeError as e:
            if e.eclass is TypeError:
                raise TypeError(e.evalue)
            elif e.eclass is IndexError:
                raise IndexError(e.evalue)
            else:
                raise

    def __setitem__(self, key, value):
        try:
            return self.tb.inject("{name}[{key}] = {value}".format(
                name=self.name,
                key=PythonTranslator.translate(key),
                value=PythonTranslator.translate(value)
            ), pop=True)
        except TestbookRuntimeError as e:
            if e.eclass is TypeError:
                raise TypeError(e.evalue)
            elif e.eclass is IndexError:
                raise IndexError(e.evalue)
            else:
                raise

    def __contains__(self, item):
        return self.tb.value(f"{self.name}.__contains__({PythonTranslator.translate(item)})")

    def __call__(self, *args, **kwargs):
        code = self.tb._construct_call_code(self.name, args, kwargs)
        try:
            return self.tb.value(code)
        except TestbookExecuteResultNotFoundError:
            # No return value from function call
            pass
        except TestbookSerializeError as e:
            return TestbookObjectReference(self.tb, e.save_varname)

    def resolve(self):
        return self.tb.value(self.name)