Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

simple.py 8.0KB

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