|
Slicer 4.2
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
|
00001 ############################################################################## 00002 # 00003 # Copyright (c) Django Software Foundation and individual contributors. 00004 # All rights reserved. 00005 # 00006 # Redistribution and use in source and binary forms, with or without modification, 00007 # are permitted provided that the following conditions are met: 00008 # 00009 # 1. Redistributions of source code must retain the above copyright notice, 00010 # this list of conditions and the following disclaimer. 00011 # 00012 # 2. Redistributions in binary form must reproduce the above copyright 00013 # notice, this list of conditions and the following disclaimer in the 00014 # documentation and/or other materials provided with the distribution. 00015 # 00016 # 3. Neither the name of Django nor the names of its contributors may be used 00017 # to endorse or promote products derived from this software without 00018 # specific prior written permission. 00019 # 00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00021 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00022 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00023 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 00024 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00025 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00026 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00027 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00029 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 # 00031 ############################################################################## 00032 00033 ############################################################################## 00034 # django.dispatch was originally forked from PyDispatcher. 00035 # 00036 # PyDispatcher License: 00037 # 00038 # Copyright (c) 2001-2003, Patrick K. O'Brien and Contributors 00039 # All rights reserved. 00040 # 00041 # Redistribution and use in source and binary forms, with or without 00042 # modification, are permitted provided that the following conditions 00043 # are met: 00044 # 00045 # Redistributions of source code must retain the above copyright 00046 # notice, this list of conditions and the following disclaimer. 00047 # 00048 # Redistributions in binary form must reproduce the above 00049 # copyright notice, this list of conditions and the following 00050 # disclaimer in the documentation and/or other materials 00051 # provided with the distribution. 00052 # 00053 # The name of Patrick K. O'Brien, or the name of any Contributor, 00054 # may not be used to endorse or promote products derived from this 00055 # software without specific prior written permission. 00056 # 00057 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00058 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00059 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00060 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00061 # COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00062 # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00063 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00064 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00065 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00066 # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00067 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 00068 # OF THE POSSIBILITY OF SUCH DAMAGE. 00069 # 00070 ############################################################################## 00071 """ 00072 "Safe weakrefs", originally from pyDispatcher. 00073 00074 Provides a way to safely weakref any function, including bound methods (which 00075 aren't handled by the core weakref module). 00076 """ 00077 00078 import traceback 00079 import weakref 00080 00081 def safeRef(target, onDelete = None): 00082 """Return a *safe* weak reference to a callable target 00083 00084 target -- the object to be weakly referenced, if it's a 00085 bound method reference, will create a BoundMethodWeakref, 00086 otherwise creates a simple weakref. 00087 onDelete -- if provided, will have a hard reference stored 00088 to the callable to be called after the safe reference 00089 goes out of scope with the reference object, (either a 00090 weakref or a BoundMethodWeakref) as argument. 00091 """ 00092 if hasattr(target, 'im_self'): 00093 if target.im_self is not None: 00094 # Turn a bound method into a BoundMethodWeakref instance. 00095 # Keep track of these instances for lookup by disconnect(). 00096 assert hasattr(target, 'im_func'), """safeRef target %r has im_self, but no im_func, don't know how to create reference"""%( target,) 00097 reference = get_bound_method_weakref( 00098 target=target, 00099 onDelete=onDelete 00100 ) 00101 return reference 00102 if callable(onDelete): 00103 return weakref.ref(target, onDelete) 00104 else: 00105 return weakref.ref( target ) 00106 00107 class BoundMethodWeakref(object): 00108 """'Safe' and reusable weak references to instance methods 00109 00110 BoundMethodWeakref objects provide a mechanism for 00111 referencing a bound method without requiring that the 00112 method object itself (which is normally a transient 00113 object) is kept alive. Instead, the BoundMethodWeakref 00114 object keeps weak references to both the object and the 00115 function which together define the instance method. 00116 00117 Attributes: 00118 key -- the identity key for the reference, calculated 00119 by the class's calculateKey method applied to the 00120 target instance method 00121 deletionMethods -- sequence of callable objects taking 00122 single argument, a reference to this object which 00123 will be called when *either* the target object or 00124 target function is garbage collected (i.e. when 00125 this object becomes invalid). These are specified 00126 as the onDelete parameters of safeRef calls. 00127 weakSelf -- weak reference to the target object 00128 weakFunc -- weak reference to the target function 00129 00130 Class Attributes: 00131 _allInstances -- class attribute pointing to all live 00132 BoundMethodWeakref objects indexed by the class's 00133 calculateKey(target) method applied to the target 00134 objects. This weak value dictionary is used to 00135 short-circuit creation so that multiple references 00136 to the same (object, function) pair produce the 00137 same BoundMethodWeakref instance. 00138 00139 """ 00140 00141 _allInstances = weakref.WeakValueDictionary() 00142 00143 def __new__( cls, target, onDelete=None, *arguments,**named ): 00144 """Create new instance or return current instance 00145 00146 Basically this method of construction allows us to 00147 short-circuit creation of references to already- 00148 referenced instance methods. The key corresponding 00149 to the target is calculated, and if there is already 00150 an existing reference, that is returned, with its 00151 deletionMethods attribute updated. Otherwise the 00152 new instance is created and registered in the table 00153 of already-referenced methods. 00154 """ 00155 key = cls.calculateKey(target) 00156 current =cls._allInstances.get(key) 00157 if current is not None: 00158 current.deletionMethods.append( onDelete) 00159 return current 00160 else: 00161 base = super( BoundMethodWeakref, cls).__new__( cls ) 00162 cls._allInstances[key] = base 00163 base.__init__( target, onDelete, *arguments,**named) 00164 return base 00165 00166 def __init__(self, target, onDelete=None): 00167 """Return a weak-reference-like instance for a bound method 00168 00169 target -- the instance-method target for the weak 00170 reference, must have im_self and im_func attributes 00171 and be reconstructable via: 00172 target.im_func.__get__( target.im_self ) 00173 which is true of built-in instance methods. 00174 onDelete -- optional callback which will be called 00175 when this weak reference ceases to be valid 00176 (i.e. either the object or the function is garbage 00177 collected). Should take a single argument, 00178 which will be passed a pointer to this object. 00179 """ 00180 def remove(weak, self=self): 00181 """Set self.isDead to true when method or instance is destroyed""" 00182 methods = self.deletionMethods[:] 00183 del self.deletionMethods[:] 00184 try: 00185 del self.__class__._allInstances[ self.key ] 00186 except KeyError: 00187 pass 00188 for function in methods: 00189 try: 00190 if callable( function ): 00191 function( self ) 00192 except Exception, e: 00193 try: 00194 traceback.print_exc() 00195 except AttributeError, err: 00196 print '''Exception during saferef %s cleanup function %s: %s'''%( 00197 self, function, e 00198 ) 00199 self.deletionMethods = [onDelete] 00200 self.key = self.calculateKey( target ) 00201 self.weakSelf = weakref.ref(target.im_self, remove) 00202 self.weakFunc = weakref.ref(target.im_func, remove) 00203 self.selfName = str(target.im_self) 00204 self.funcName = str(target.im_func.__name__) 00205 00206 def calculateKey( cls, target ): 00207 """Calculate the reference key for this reference 00208 00209 Currently this is a two-tuple of the id()'s of the 00210 target object and the target function respectively. 00211 """ 00212 return (id(target.im_self),id(target.im_func)) 00213 calculateKey = classmethod( calculateKey ) 00214 00215 def __str__(self): 00216 """Give a friendly representation of the object""" 00217 return """%s( %s.%s )"""%( 00218 self.__class__.__name__, 00219 self.selfName, 00220 self.funcName, 00221 ) 00222 00223 __repr__ = __str__ 00224 00225 def __nonzero__( self ): 00226 """Whether we are still a valid reference""" 00227 return self() is not None 00228 00229 def __cmp__( self, other ): 00230 """Compare with another reference""" 00231 if not isinstance (other,self.__class__): 00232 return cmp( self.__class__, type(other) ) 00233 return cmp( self.key, other.key) 00234 00235 def __call__(self): 00236 """Return a strong reference to the bound method 00237 00238 If the target cannot be retrieved, then will 00239 return None, otherwise returns a bound instance 00240 method for our object and function. 00241 00242 Note: 00243 You may call this method any number of times, 00244 as it does not invalidate the reference. 00245 """ 00246 target = self.weakSelf() 00247 if target is not None: 00248 function = self.weakFunc() 00249 if function is not None: 00250 return function.__get__(target) 00251 return None 00252 00253 class BoundNonDescriptorMethodWeakref(BoundMethodWeakref): 00254 """A specialized BoundMethodWeakref, for platforms where instance methods 00255 are not descriptors. 00256 00257 It assumes that the function name and the target attribute name are the 00258 same, instead of assuming that the function is a descriptor. This approach 00259 is equally fast, but not 100% reliable because functions can be stored on an 00260 attribute named differenty than the function's name such as in: 00261 00262 class A: pass 00263 def foo(self): return "foo" 00264 A.bar = foo 00265 00266 But this shouldn't be a common use case. So, on platforms where methods 00267 aren't descriptors (such as Jython) this implementation has the advantage 00268 of working in the most cases. 00269 """ 00270 def __init__(self, target, onDelete=None): 00271 """Return a weak-reference-like instance for a bound method 00272 00273 target -- the instance-method target for the weak 00274 reference, must have im_self and im_func attributes 00275 and be reconstructable via: 00276 target.im_func.__get__( target.im_self ) 00277 which is true of built-in instance methods. 00278 onDelete -- optional callback which will be called 00279 when this weak reference ceases to be valid 00280 (i.e. either the object or the function is garbage 00281 collected). Should take a single argument, 00282 which will be passed a pointer to this object. 00283 """ 00284 assert getattr(target.im_self, target.__name__) == target, \ 00285 ("method %s isn't available as the attribute %s of %s" % 00286 (target, target.__name__, target.im_self)) 00287 super(BoundNonDescriptorMethodWeakref, self).__init__(target, onDelete) 00288 00289 def __call__(self): 00290 """Return a strong reference to the bound method 00291 00292 If the target cannot be retrieved, then will 00293 return None, otherwise returns a bound instance 00294 method for our object and function. 00295 00296 Note: 00297 You may call this method any number of times, 00298 as it does not invalidate the reference. 00299 """ 00300 target = self.weakSelf() 00301 if target is not None: 00302 function = self.weakFunc() 00303 if function is not None: 00304 # Using partial() would be another option, but it erases the 00305 # "signature" of the function. That is, after a function is 00306 # curried, the inspect module can't be used to determine how 00307 # many arguments the function expects, nor what keyword 00308 # arguments it supports, and pydispatcher needs this 00309 # information. 00310 return getattr(target, function.__name__) 00311 return None 00312 00313 def get_bound_method_weakref(target, onDelete): 00314 """Instantiates the appropiate BoundMethodWeakRef, depending on the details of 00315 the underlying class method implementation""" 00316 if hasattr(target, '__get__'): 00317 # target method is a descriptor, so the default implementation works: 00318 return BoundMethodWeakref(target=target, onDelete=onDelete) 00319 else: 00320 # no luck, use the alternative implementation: 00321 return BoundNonDescriptorMethodWeakref(target=target, onDelete=onDelete)
1.7.4