30 from debug_tools
import getLogger
33 log = getLogger( 127-4, __name__ )
38 An object type which can have its attributes changes locked/blocked after its `lock()` 41 After locking, its string representation attribute is going to be saved as an attribute and 46 EMQUOTE_STRING =
False 50 How to handle call to __setattr__ from __init__? 51 https://stackoverflow.com/questions/3870982/how-to-handle-call-to-setattr-from-init 65 self.
_hash = get_unique_hash()
73 Block attributes from being changed after it is activated. 74 https://stackoverflow.com/questions/17020115/how-to-use-setattr-correctly-avoiding-infinite-recursion 78 raise AttributeError(
"Attributes cannot be changed after `locked` is set to True! %s" % self.
__repr__() )
85 Determines whether this object is equal to another one based on their hashes. 88 if isinstance( self, LockableType )
is isinstance( other, LockableType ):
89 return hash( self ) == hash( other )
91 raise TypeError(
"'=' not supported between instances of '%s' and '%s'" % (
92 self.__class__.__name__, other.__class__.__name__ ) )
96 Return the hash of this object based on its string representation. 102 See `__repr__()` for details. 104 return get_representation( self, ignore={
'hash'}, emquote=self.
EMQUOTE_STRING )
108 Prints a representation of this object within all its attributes. 118 Python does not allow to dynamically/monkey patch its build in functions. Then, we create 119 out own function and call it from the built-in function. 125 Caches the string representation of this object, after locking its attributes changes with `lock()` 131 return get_representation( self, ignore={
'hash'}, emquote=self.
EMQUOTE_STRING )
135 Python does not allow to dynamically/monkey patch its build in functions. Then, we create 136 out own function and call it from the built-in function. 141 raise TypeError(
"object of type '%s' has no len()" % self.__class__.__name__ )
145 Unblock the object changes allowing its attributes to be freely set. 147 Do not call it if this object is inside a hashtable as list or set, because an object 148 cannot have its hash changed while they are inside it. Otherwise, the hashmap will not 149 get updated and the new version of the object will point as non existent. 155 self.__dict__[
'locked'] =
False 162 Block further changes to this object attributes and cache its length and string 163 representation for faster access. 178 def new(self, unlocked=True):
180 Creates and return a new copy of the current a object. 182 new_copy = copy.deepcopy( self )