Proxy.__rfloordiv__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
c 2
b 0
f 0
dl 0
loc 2
rs 10
1
import operator
2
3
from .compat import PY2
4
from .compat import PY3
5
from .compat import with_metaclass
6
from .utils import cached_property
7
from .utils import identity
8
9
10
def make_proxy_method(code):
11
    def proxy_wrapper(self, *args):
12
        return code(self.__wrapped__, *args)
13
14
    return proxy_wrapper
15
16
17
class _ProxyMethods(object):
18
    # We use properties to override the values of __module__ and
19
    # __doc__. If we add these in ObjectProxy, the derived class
20
    # __dict__ will still be setup to have string variants of these
21
    # attributes and the rules of descriptors means that they appear to
22
    # take precedence over the properties in the base class. To avoid
23
    # that, we copy the properties into the derived class type itself
24
    # via a meta class. In that way the properties will always take
25
    # precedence.
26
27
    @property
28
    def __module__(self):
29
        return self.__wrapped__.__module__
30
31
    @__module__.setter
32
    def __module__(self, value):
33
        self.__wrapped__.__module__ = value
34
35
    @property
36
    def __doc__(self):
37
        return self.__wrapped__.__doc__
38
39
    @__doc__.setter
40
    def __doc__(self, value):
41
        self.__wrapped__.__doc__ = value
42
43
    # Need to also propagate the special __weakref__ attribute for case
44
    # where decorating classes which will define this. If do not define
45
    # it and use a function like inspect.getmembers() on a decorator
46
    # class it will fail. This can't be in the derived classes.
47
48
    @property
49
    def __weakref__(self):
50
        return self.__wrapped__.__weakref__
51
52
53
class _ProxyMetaType(type):
54
    def __new__(cls, name, bases, dictionary):
55
        # Copy our special properties into the class so that they
56
        # always take precedence over attributes of the same name added
57
        # during construction of a derived class. This is to save
58
        # duplicating the implementation for them in all derived classes.
59
60
        dictionary.update(vars(_ProxyMethods))
61
        dictionary.pop('__dict__')
62
63
        return type.__new__(cls, name, bases, dictionary)
64
65
66
class Proxy(with_metaclass(_ProxyMetaType)):
67
    __factory__ = None
68
69
    def __init__(self, factory):
70
        self.__dict__['__factory__'] = factory
71
72
    @cached_property
73
    def __wrapped__(self):
74
        self = self.__dict__
75
        if '__factory__' in self:
76
            factory = self['__factory__']
77
            return factory()
78
        else:
79
            raise ValueError("Proxy hasn't been initiated: __factory__ is missing.")
80
81
    __name__ = property(make_proxy_method(operator.attrgetter('__name__')))
82
    __class__ = property(make_proxy_method(operator.attrgetter('__class__')))
83
    __annotations__ = property(make_proxy_method(operator.attrgetter('__anotations__')))
84
    __dir__ = make_proxy_method(dir)
85
    __str__ = make_proxy_method(str)
86
87
    if PY3:
88
        __bytes__ = make_proxy_method(bytes)
89
90
    def __repr__(self, __getattr__=object.__getattribute__):
91
        if '__wrapped__' in self.__dict__:
92
            return '<%s at 0x%x wrapping %r at 0x%x with factory %r>' % (
93
                type(self).__name__, id(self),
94
                self.__wrapped__, id(self.__wrapped__),
95
                self.__factory__
96
            )
97
        else:
98
            return '<%s at 0x%x with factory %r>' % (
99
                type(self).__name__, id(self),
100
                self.__factory__
101
            )
102
103
    __reversed__ = make_proxy_method(reversed)
104
105
    if PY3:
106
        __round__ = make_proxy_method(round)
107
108
    __lt__ = make_proxy_method(operator.lt)
109
    __le__ = make_proxy_method(operator.le)
110
    __eq__ = make_proxy_method(operator.eq)
111
    __ne__ = make_proxy_method(operator.ne)
112
    __gt__ = make_proxy_method(operator.gt)
113
    __ge__ = make_proxy_method(operator.ge)
114
    __hash__ = make_proxy_method(hash)
115
    __nonzero__ = make_proxy_method(bool)
116
    __bool__ = make_proxy_method(bool)
117
118
    def __setattr__(self, name, value):
119
        if hasattr(type(self), name):
120
            self.__dict__[name] = value
121
        else:
122
            setattr(self.__wrapped__, name, value)
123
124
    def __getattr__(self, name):
125
        if name in ('__wrapped__', '__factory__'):
126
            raise AttributeError(name)
127
        else:
128
            return getattr(self.__wrapped__, name)
129
130
    def __delattr__(self, name):
131
        if hasattr(type(self), name):
132
            del self.__dict__[name]
133
        else:
134
            delattr(self.__wrapped__, name)
135
136
    __add__ = make_proxy_method(operator.add)
137
    __sub__ = make_proxy_method(operator.sub)
138
    __mul__ = make_proxy_method(operator.mul)
139
    __div__ = make_proxy_method(operator.div if PY2 else operator.truediv)
140
    __truediv__ = make_proxy_method(operator.truediv)
141
    __floordiv__ = make_proxy_method(operator.floordiv)
142
    __mod__ = make_proxy_method(operator.mod)
143
    __divmod__ = make_proxy_method(divmod)
144
    __pow__ = make_proxy_method(pow)
145
    __lshift__ = make_proxy_method(operator.lshift)
146
    __rshift__ = make_proxy_method(operator.rshift)
147
    __and__ = make_proxy_method(operator.and_)
148
    __xor__ = make_proxy_method(operator.xor)
149
    __or__ = make_proxy_method(operator.or_)
150
151
    def __radd__(self, other):
152
        return other + self.__wrapped__
153
154
    def __rsub__(self, other):
155
        return other - self.__wrapped__
156
157
    def __rmul__(self, other):
158
        return other * self.__wrapped__
159
160
    def __rdiv__(self, other):
161
        return operator.div(other, self.__wrapped__)
162
163
    def __rtruediv__(self, other):
164
        return operator.truediv(other, self.__wrapped__)
165
166
    def __rfloordiv__(self, other):
167
        return other // self.__wrapped__
168
169
    def __rmod__(self, other):
170
        return other % self.__wrapped__
171
172
    def __rdivmod__(self, other):
173
        return divmod(other, self.__wrapped__)
174
175
    def __rpow__(self, other, *args):
176
        return pow(other, self.__wrapped__, *args)
177
178
    def __rlshift__(self, other):
179
        return other << self.__wrapped__
180
181
    def __rrshift__(self, other):
182
        return other >> self.__wrapped__
183
184
    def __rand__(self, other):
185
        return other & self.__wrapped__
186
187
    def __rxor__(self, other):
188
        return other ^ self.__wrapped__
189
190
    def __ror__(self, other):
191
        return other | self.__wrapped__
192
193
    __iadd__ = make_proxy_method(operator.iadd)
194
    __isub__ = make_proxy_method(operator.isub)
195
    __imul__ = make_proxy_method(operator.imul)
196
    __idiv__ = make_proxy_method(operator.idiv if PY2 else operator.itruediv)
197
    __itruediv__ = make_proxy_method(operator.itruediv)
198
    __ifloordiv__ = make_proxy_method(operator.ifloordiv)
199
    __imod__ = make_proxy_method(operator.imod)
200
    __ipow__ = make_proxy_method(operator.ipow)
201
    __ilshift__ = make_proxy_method(operator.ilshift)
202
    __irshift__ = make_proxy_method(operator.irshift)
203
    __iand__ = make_proxy_method(operator.iand)
204
    __ixor__ = make_proxy_method(operator.ixor)
205
    __ior__ = make_proxy_method(operator.ior)
206
    __neg__ = make_proxy_method(operator.neg)
207
    __pos__ = make_proxy_method(operator.pos)
208
    __abs__ = make_proxy_method(operator.abs)
209
    __invert__ = make_proxy_method(operator.invert)
210
211
    __int__ = make_proxy_method(int)
212
213
    if PY2:
214
        __long__ = make_proxy_method(long)  # flake8: noqa
215
216
    __float__ = make_proxy_method(float)
217
    __oct__ = make_proxy_method(oct)
218
    __hex__ = make_proxy_method(hex)
219
    __index__ = make_proxy_method(operator.index)
220
    __len__ = make_proxy_method(len)
221
    __contains__ = make_proxy_method(operator.contains)
222
    __getitem__ = make_proxy_method(operator.getitem)
223
    __setitem__ = make_proxy_method(operator.setitem)
224
    __delitem__ = make_proxy_method(operator.delitem)
225
226
    if PY2:
227
        __getslice__ = make_proxy_method(operator.getslice)
228
        __setslice__ = make_proxy_method(operator.setslice)
229
        __delslice__ = make_proxy_method(operator.delslice)
230
231
    def __enter__(self):
232
        return self.__wrapped__.__enter__()
233
234
    def __exit__(self, *args, **kwargs):
235
        return self.__wrapped__.__exit__(*args, **kwargs)
236
237
    __iter__ = make_proxy_method(iter)
238
239
    def __call__(self, *args, **kwargs):
240
        return self.__wrapped__(*args, **kwargs)
241
242
    def __reduce__(self):
243
        return identity, (self.__wrapped__,)
244
245
    def __reduce_ex__(self, protocol):
246
        return identity, (self.__wrapped__,)
247