File: pretend.py

package info (click to toggle)
python-pretend 1.0.8-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid, stretch
  • size: 136 kB
  • ctags: 31
  • sloc: python: 131; makefile: 3
file content (132 lines) | stat: -rw-r--r-- 3,024 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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import functools
import sys


PY3K = sys.version_info >= (3,)


methods = set([
    "__iter__",
    "__len__",
    "__contains__",
    "__getitem__",
    "__setitem__",
    "__delitem__",

    "__enter__",
    "__exit__",

    "__lt__",
    "__le__",
    "__eq__",
    "__ne__",
    "__gt__",
    "__ge__",

    "__add__",
    "__and__",
    "__divmod__",
    "__floordiv__",
    "__lshift__",
    "__mod__",
    "__mul__",
    "__or__",
    "__pow__",
    "__rshift__",
    "__sub__",
    "__truediv__",
    "__xor__",

    "__repr__",
])
if PY3K:
    methods.add("__next__")
    methods.add("__bool__")
else:
    methods.add("__div__")
    methods.add("__nonzero__")
MAGIC_METHODS = frozenset(methods)
del methods


def _build_magic_dispatcher(method):
    def inner(self, *args, **kwargs):
        return self.__dict__[method](*args, **kwargs)
    inner.__name__ = method
    return inner


class stub(object):
    _classes_cache = {}

    def __new__(cls, **kwargs):
        magic_methods_present = MAGIC_METHODS.intersection(kwargs)
        if magic_methods_present not in cls._classes_cache:
            attrs = dict(
                (method, _build_magic_dispatcher(method))
                for method in magic_methods_present
            )
            attrs["__module__"] = cls.__module__
            cls._classes_cache[magic_methods_present] = (
                type("stub", (cls,), attrs)
            )
        new_cls = cls._classes_cache[magic_methods_present]
        return super(stub, new_cls).__new__(new_cls)

    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

    def __repr__(self):
        return '<stub(%s)>' % ', '.join([
            '%s=%r' % (key, val)
            for key, val in self.__dict__.items()
        ])


def raiser(exc):
    if (
        not (
            isinstance(exc, BaseException) or
            isinstance(exc, type) and issubclass(exc, BaseException)
        )
    ):
        raise TypeError("exc must be either an exception instance or class.")

    def inner(*args, **kwargs):
        raise exc
    return inner


class call(object):
    def __init__(self, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs

    def __eq__(self, other):
        if not isinstance(other, call):
            return NotImplemented
        return self.args == other.args and self.kwargs == other.kwargs

    def __ne__(self, other):
        return not (self == other)

    def __hash__(self):
        return hash((
            self.args,
            frozenset(self.kwargs.items())
        ))

    def __repr__(self):
        args = ", ".join(map(repr, self.args))
        kwargs = ", ".join("%s=%r" % (k, v) for k, v in self.kwargs.items())
        comma = ", " if args and kwargs else ""
        return "<call(%s%s%s)>" % (args, comma, kwargs)


def call_recorder(func):
    @functools.wraps(func)
    def inner(*args, **kwargs):
        inner.calls.append(call(*args, **kwargs))
        return func(*args, **kwargs)
    inner.calls = []
    return inner