forked from adamlwgriffiths/PyGLy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathweak_method_reference.py
More file actions
executable file
·134 lines (112 loc) · 4.21 KB
/
weak_method_reference.py
File metadata and controls
executable file
·134 lines (112 loc) · 4.21 KB
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
133
'''
Provides an implementation of a WeakMethodReference
for weak references to functions and methods.
The standard weakref module in Python cannot store
references to non-bound functions and should not
be used to perform this task.
Code borrowed from the following places:
http://code.activestate.com/recipes/81253/
http://stackoverflow.com/questions/3942303/how-does-a-python-set-check-if-two-objects-are-equal-what-methods-does-an-o
'''
import weakref
import new
class WeakMethodReference( object ):
"""Provides the ability to store a weak pointer to
class members on top of the existing weakref functionality
provided by python.
This class also provides comparison operators to
allow proper usage in containers such as set([]).
The ability to change the weak reference is not
supported to prevent mutability. This is important
for container support as the object hash would
change after storing it.
"""
def __init__(self, function = None ):
"""Initialises the weak reference with
a function or class method.
Args:
function: The object to store a weak reference to.
This can be a class, object, method or function.
"""
super( WeakMethodReference, self ).__init__()
try:
if function.__self__ is not None:
# bound method
self._obj = weakref.ref( function.__self__ )
else:
# unbound method
self._obj = None
self._func = function.__func__
self._class = function.__self__.__class__
except AttributeError:
# not a method
self._obj = None
self._func = function
self._class = None
def __call__( self ):
"""
Returns:
Returns a new bound-method like the original, or
the original function if refers just to a function or
unbound method.
Returns None if the original object doesn't exist
"""
if self.is_dead():
return None
if self._obj is not None:
# we have an instance: return a bound method
return new.instancemethod(
self._func,
self._obj(),
self._class
)
else:
# we don't have an instance: return just the
# function
return self._func
def is_dead( self ):
"""Check if the referenced object is invalid.
Returns:
True if the referenced callable was a bound method and
the instance no longer exists. Otherwise, return False.
"""
if self._obj is None and self._func is not None:
return False
if self._obj is not None and self._obj() is None:
return True
return False
def is_alive( self ):
"""Check if the referenced object is valid.
The equivalent to 'not is_dead()'
Make a positive method call because double negatives suck
"""
return not self.is_dead()
def __eq__( self, other ):
"""Provides an 'equal' operator.
.. note::
Enables comparison between different weak
pointer objects that point to the same
object based on the contents instead of the
object pointer.
"""
return (
isinstance(other, self.__class__ ) \
and self.__dict__ == other.__dict__
)
def __ne__( self, other ):
"""Provides a 'not-equal' operator.
.. note::
Enables comparison between different weak
pointer objects that point to the same
object based on the contents instead of the
object pointer.
"""
return not self.__eq__(other)
def __hash__( self ):
"""Generates a hash value for the stored reference.
.. note::
This method is provided to allow comparison of
references inside of containers like set([])
http://stackoverflow.com/questions/3942303/how-does-a-python-set-check-if-two-objects-are-equal-what-methods-does-an-o
"""
return hash( (self._obj, self._func, self._class) )