add WeakProxy with comparison

This commit is contained in:
Ryan Pessa 2015-03-04 10:36:06 -06:00
parent 60d642a875
commit a7784eb31f
3 changed files with 292 additions and 2 deletions

View File

@ -178,7 +178,7 @@ from kivy.graphics import (Canvas, Translate, Fbo, ClearColor, ClearBuffers,
from kivy.base import EventLoop from kivy.base import EventLoop
from kivy.lang import Builder from kivy.lang import Builder
from kivy.context import get_current_context from kivy.context import get_current_context
from weakref import proxy from kivy.weakproxy import WeakProxy
from functools import partial from functools import partial
from itertools import islice from itertools import islice
@ -293,7 +293,7 @@ class Widget(WidgetBase):
return _proxy_ref return _proxy_ref
f = partial(_widget_destructor, self.uid) f = partial(_widget_destructor, self.uid)
self._proxy_ref = _proxy_ref = proxy(self, f) self._proxy_ref = _proxy_ref = WeakProxy(self, f)
# Only f should be enough here, but it appears that is a very # Only f should be enough here, but it appears that is a very
# specific case, the proxy destructor is not called if both f and # specific case, the proxy destructor is not called if both f and
# _proxy_ref are not together in a tuple. # _proxy_ref are not together in a tuple.

289
kivy/weakproxy.pyx Normal file
View File

@ -0,0 +1,289 @@
import weakref
import operator
cdef class WeakProxy(object):
'''Replacement for weakref.proxy to support comparisons
'''
cdef public object __ref
def __init__(self, obj, destructor=None):
self.__ref = weakref.ref(obj, destructor)
def __ref__(self):
r = self.__ref()
if r is None:
raise ReferenceError('weakly-referenced object no longer exists')
return r
def __getattr__(self, name):
return getattr(self.__ref__(), name)
def __setattr__(self, name, value):
setattr(self.__ref__(), name, value)
def __delattr__(self, name):
delattr(self.__ref__(), name)
property __class__:
def __get__(self):
return self.__ref__().__class__
def __dir__(self):
return dir(self.__ref__())
def __reversed__(self):
return reversed(self.__ref__())
def __round__(self):
return round(self.__ref__())
def __hash__(self):
return hash(self.__ref__())
def __richcmp__(self, other, op):
r = self.__ref__()
if op == 0:
return r < other
elif op == 1:
return r <= other
elif op == 2:
return r == other
elif op == 3:
return r != other
elif op == 4:
return r > other
elif op == 5:
return r >= other
def __nonzero__(self):
return bool(self.__ref__())
def __bool__(self):
return bool(self.__ref__())
def __add__(self, other):
return self.__ref__() + other
def __sub__(self, other):
return self.__ref__() - other
def __mul__(self, other):
return self.__ref__() * other
def __div__(self, other):
return operator.div(self.__ref__(), other)
def __truediv__(self, other):
return operator.truediv(self.__ref__(), other)
def __floordiv__(self, other):
return self.__ref__() // other
def __mod__(self, other):
return self.__ref__() % other
def __divmod__(self, other):
return divmod(self.__ref__(), other)
def __pow__(self, other, modulo):
return pow(self.__ref__(), other, modulo)
def __lshift__(self, other):
return self.__ref__() << other
def __rshift__(self, other):
return self.__ref__() >> other
def __and__(self, other):
return self.__ref__() & other
def __xor__(self, other):
return self.__ref__() ^ other
def __or__(self, other):
return self.__ref__() | other
def __radd__(self, other):
return other + self.__ref__()
def __rsub__(self, other):
return other - self.__ref__()
def __rmul__(self, other):
return other * self.__ref__()
def __rdiv__(self, other):
return operator.div(other, self.__ref__())
def __rtruediv__(self, other):
return operator.truediv(other, self.__ref__())
def __rfloordiv__(self, other):
return other // self.__ref__()
def __rmod__(self, other):
return other % self.__ref__()
def __rdivmod__(self, other):
return divmod(other, self.__ref__())
def __rpow__(self, other, modulo):
return pow(other, self.__ref__(), modulo)
def __rlshift__(self, other):
return other << self.__ref__()
def __rrshift__(self, other):
return other >> self.__ref__()
def __rand__(self, other):
return other & self.__ref__()
def __rxor__(self, other):
return other ^ self.__ref__()
def __ror__(self, other):
return other | self.__ref__()
def __iadd__(self, other):
r = self.__ref__()
r += other
self.__ref = weakref.ref(r)
return self
def __isub__(self, other):
r = self.__ref__()
r -= other
self.__ref = weakref.ref(r)
return self
def __imul__(self, other):
r = self.__ref__()
r *= other
self.__ref = weakref.ref(r)
return self
def __idiv__(self, other):
r = operator.idiv(self.__ref__(), other)
self.__ref = weakref.ref(r)
return self
def __itruediv__(self, other):
r = operator.itruediv(self.__ref__(), other)
self.__ref = weakref.ref(r)
return self
def __ifloordiv__(self, other):
r = self.__ref__()
r //= other
self.__ref = weakref.ref(r)
return self
def __imod__(self, other):
r = self.__ref__()
r %= other
self.__ref = weakref.ref(r)
return self
def __ipow__(self, other):
r = self.__ref__()
r **= other
self.__ref = weakref.ref(r)
return self
def __ilshift__(self, other):
r = self.__ref__()
r <<= other
self.__ref = weakref.ref(r)
return self
def __irshift__(self, other):
r = self.__ref__()
r >>= other
self.__ref = weakref.ref(r)
return self
def __iand__(self, other):
r = self.__ref__()
r &= other
self.__ref = weakref.ref(r)
return self
def __ixor__(self, other):
r = self.__ref__()
r ^= other
self.__ref = weakref.ref(r)
return self
def __ior__(self, other):
r = self.__ref__()
r |= other
self.__ref = weakref.ref(r)
return self
def __neg__(self):
return -self.__ref__()
def __pos__(self):
return +self.__ref__()
def __abs__(self):
return abs(self.__ref__())
def __invert__(self):
return ~self.__ref__()
def __int__(self):
return int(self.__ref__())
def __long__(self):
return long(self.__ref__())
def __float__(self):
return float(self.__ref__())
def __oct__(self):
return oct(self.__ref__())
def __hex__(self):
return hex(self.__ref__())
def __index__(self):
return operator.index(self.__ref__())
def __len__(self):
return len(self.__ref__())
def __contains__(self, value):
return value in self.__ref__()
def __getitem__(self, key):
return self.__ref__()[key]
def __setitem__(self, key, value):
self.__ref__()[key] = value
def __delitem__(self, key):
del self.__ref__()[key]
def __enter__(self):
return self.__ref__().__enter__()
def __exit__(self, *args, **kwargs):
return self.__ref__().__exit__(*args, **kwargs)
def __iter__(self):
return iter(self.__ref__())
def __bytes__(self):
return bytes(self.__ref__())
def __str__(self):
return str(self.__ref__())
def __unicode__(self):
return unicode(self.__ref__())
def __repr__(self):
return b'<WeakProxy to {!r}>'.format(self.__ref__())

View File

@ -678,6 +678,7 @@ graphics_dependencies = {
sources = { sources = {
'_event.pyx': merge(base_flags, {'depends': ['properties.pxd']}), '_event.pyx': merge(base_flags, {'depends': ['properties.pxd']}),
'weakproxy.pyx': {},
'properties.pyx': merge(base_flags, {'depends': ['_event.pxd']}), 'properties.pyx': merge(base_flags, {'depends': ['_event.pxd']}),
'graphics/buffer.pyx': base_flags, 'graphics/buffer.pyx': base_flags,
'graphics/context.pyx': merge(base_flags, gl_flags), 'graphics/context.pyx': merge(base_flags, gl_flags),