1 |
commit: 758592e4107cae1a93c936062f0bda2bc9fc6dd5 |
2 |
Author: André Erdmann <dywi <AT> mailerd <DOT> de> |
3 |
AuthorDate: Thu Aug 29 12:24:54 2013 +0000 |
4 |
Commit: André Erdmann <dywi <AT> mailerd <DOT> de> |
5 |
CommitDate: Thu Aug 29 12:24:54 2013 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=758592e4 |
7 |
|
8 |
roverlay/util/objects: more weak referencing |
9 |
|
10 |
This functionality will (primarily) be used for handling distmap/mirror |
11 |
directory file collisions. |
12 |
|
13 |
--- |
14 |
roverlay/util/objects.py | 154 +++++++++++++++++++++++++++++++++++++++++------ |
15 |
1 file changed, 135 insertions(+), 19 deletions(-) |
16 |
|
17 |
diff --git a/roverlay/util/objects.py b/roverlay/util/objects.py |
18 |
index 28cc4e8..ce4eccb 100644 |
19 |
--- a/roverlay/util/objects.py |
20 |
+++ b/roverlay/util/objects.py |
21 |
@@ -6,6 +6,85 @@ |
22 |
|
23 |
import weakref |
24 |
|
25 |
+class ObjectDisappeared ( Exception ): |
26 |
+ pass |
27 |
+# --- end of ObjectDisappeared --- |
28 |
+ |
29 |
+class SafeWeakRef ( weakref.ref ): |
30 |
+ |
31 |
+ def deref_unsafe ( self ): |
32 |
+ return super ( SafeWeakRef, self ).__call__() |
33 |
+ # --- end of deref_unsafe (...) --- |
34 |
+ |
35 |
+ def deref_safe ( self ): |
36 |
+ obj = super ( SafeWeakRef, self ).__call__() |
37 |
+ if obj is not None: |
38 |
+ return obj |
39 |
+ else: |
40 |
+ raise ObjectDisappeared() |
41 |
+ # --- end of deref_safe (...) --- |
42 |
+ |
43 |
+ __call__ = deref_safe |
44 |
+ deref = deref_safe |
45 |
+ |
46 |
+ def __bool__ ( self ): |
47 |
+ return self.deref_unsafe() is not None |
48 |
+ # --- end of __bool__ (...) --- |
49 |
+ |
50 |
+ def __repr__ ( self ): |
51 |
+ obj = self.deref_unsafe() |
52 |
+ if obj: |
53 |
+ return "<{} at 0x{:x} to {!r} at 0x{:x}>".format ( |
54 |
+ self.__class__.__name__, id ( self ), |
55 |
+ obj.__class__.__name__, id ( obj ) |
56 |
+ ) |
57 |
+ else: |
58 |
+ return "<{} at 0x{:x} to None>".format ( |
59 |
+ self.__class__.__name__, id ( self ) |
60 |
+ ) |
61 |
+ # --- end of __repr__ (...) --- |
62 |
+ |
63 |
+# --- end of SafeWeakRef --- |
64 |
+ |
65 |
+ |
66 |
+class NoneRef ( object ): |
67 |
+ |
68 |
+ def __init__ ( self, obj=None ): |
69 |
+ super ( NoneRef, self ).__init__() |
70 |
+ assert obj is None |
71 |
+ # --- end of NoneRef (...) --- |
72 |
+ |
73 |
+ def deref_unsafe ( self ): |
74 |
+ return None |
75 |
+ # --- end of deref_unsafe (...) --- |
76 |
+ |
77 |
+ def deref_safe ( self ): |
78 |
+ raise ObjectDisappeared() |
79 |
+ # --- end of deref_safe (...) --- |
80 |
+ |
81 |
+ __call__ = deref_safe |
82 |
+ deref = deref_safe |
83 |
+ |
84 |
+ def __bool__ ( self ): |
85 |
+ return False |
86 |
+ # --- end of __bool__ (...) --- |
87 |
+ |
88 |
+ def __repr__ ( self ): |
89 |
+ return "<NoneRef at 0x{:x}>".format ( id ( self ) ) |
90 |
+ # --- end of __repr__ (...) --- |
91 |
+ |
92 |
+# --- end of NoneRef --- |
93 |
+ |
94 |
+def get_object_ref ( obj ): |
95 |
+ if obj is None: |
96 |
+ return NoneRef() |
97 |
+ elif hasattr ( obj, 'get_ref' ): |
98 |
+ return obj.get_ref() |
99 |
+ else: |
100 |
+ return SafeWeakRef ( obj ) |
101 |
+# --- end of get_object_ref (...) --- |
102 |
+ |
103 |
+ |
104 |
class MethodNotImplementedError ( NotImplementedError ): |
105 |
def __init__ ( self, obj, method, msg=None ): |
106 |
if isinstance ( obj, str ): |
107 |
@@ -71,35 +150,72 @@ def not_implemented ( func=None ): |
108 |
# --- end of not_implemented (...) --- |
109 |
|
110 |
|
111 |
+class Referenceable ( object ): |
112 |
+ |
113 |
+ CACHE_REF = False |
114 |
+ |
115 |
+ def __init__ ( self, *args, **kwargs ): |
116 |
+ super ( Referenceable, self ).__init__() |
117 |
+ self._cached_selfref = None |
118 |
+ if self.CACHE_REF: |
119 |
+ self.cache_ref() |
120 |
+ # --- end of __init__ (...) --- |
121 |
+ |
122 |
+ def cache_ref ( self ): |
123 |
+ self._cached_selfref = self.get_new_ref() |
124 |
+ self.get_ref = self._get_cached_ref |
125 |
+ # --- end of cache_ref (...) --- |
126 |
+ |
127 |
+ def _get_cached_ref ( self ): |
128 |
+ return self._cached_selfref |
129 |
+ # --- end of _get_cached_ref (...) --- |
130 |
+ |
131 |
+ def get_new_ref ( self ): |
132 |
+ return SafeWeakRef ( self ) |
133 |
+ # --- end of get_new_ref (...) --- |
134 |
+ |
135 |
+ get_ref = get_new_ref |
136 |
+ |
137 |
+# --- end of Referenceable --- |
138 |
+ |
139 |
+ |
140 |
+class ReferenceTree ( Referenceable ): |
141 |
+ |
142 |
+ def __init__ ( self, parent ): |
143 |
+ super ( ReferenceTree, self ).__init__() |
144 |
+ self.parent_ref = None |
145 |
+ self.set_parent ( parent ) |
146 |
+ # --- end of __init__ (...) --- |
147 |
+ |
148 |
+ def set_parent ( self, parent ): |
149 |
+ self.parent_ref = get_object_ref ( parent ) |
150 |
+ # --- end of set_parent (...) --- |
151 |
+ |
152 |
+ def get_parent ( self ): |
153 |
+ return self.parent_ref.deref_safe() |
154 |
+ # --- end of get_parent (...) --- |
155 |
+ |
156 |
+ get_upper = get_parent |
157 |
+ |
158 |
+# --- end of ReferenceTree --- |
159 |
+ |
160 |
+ |
161 |
class ObjectView ( object ): |
162 |
|
163 |
- class ObjectDisappeared ( Exception ): |
164 |
- pass |
165 |
- # --- end of ObjectDisappeared --- |
166 |
+ ObjectDisappeared = ObjectDisappeared |
167 |
|
168 |
def __init__ ( self, obj ): |
169 |
super ( ObjectView, self ).__init__() |
170 |
- self.obj_ref = weakref.ref ( obj ) if obj is not None else None |
171 |
+ self.obj_ref = get_object_ref ( obj ) |
172 |
+ self.deref_unsafe = self.obj_ref.deref_unsafe |
173 |
+ self.deref_safe = self.obj_ref.deref_safe |
174 |
+ self.deref = self.obj_ref.deref_safe |
175 |
# --- end of __init__ (...) --- |
176 |
|
177 |
def __bool__ ( self ): |
178 |
- return ( self.obj_ref is not None and self.obj_ref() is not None ) |
179 |
+ return bool ( self.obj_ref ) |
180 |
# --- end of __bool__ (...) --- |
181 |
|
182 |
- def deref_unsafe ( self ): |
183 |
- return None if self.obj_ref is None else self.obj_ref() |
184 |
- # --- end of deref_unsafe (...) --- |
185 |
- |
186 |
- def deref_safe ( self ): |
187 |
- obj = None if self.obj_ref is None else self.obj_ref() |
188 |
- if obj is None: |
189 |
- raise self.__class__.ObjectDisappeared() |
190 |
- else: |
191 |
- return obj |
192 |
- # --- end of deref_safe (...) --- |
193 |
- |
194 |
- deref = deref_safe |
195 |
- |
196 |
@abstractmethod |
197 |
def update ( self ): |
198 |
pass |