1'''For debug purpose we are replacing actual builtin property by the debug property 2''' 3from _pydevd_bundle.pydevd_comm import get_global_debugger 4from _pydevd_bundle.pydevd_constants import DebugInfoHolder, IS_PY2 5import pydevd_tracing 6import traceback 7 8#======================================================================================================================= 9# replace_builtin_property 10#======================================================================================================================= 11def replace_builtin_property(new_property=None): 12 if new_property is None: 13 new_property = DebugProperty 14 original = property 15 if IS_PY2: 16 try: 17 import __builtin__ 18 __builtin__.__dict__['property'] = new_property 19 except: 20 if DebugInfoHolder.DEBUG_TRACE_LEVEL: 21 traceback.print_exc() #@Reimport 22 else: 23 try: 24 import builtins #Python 3.0 does not have the __builtin__ module @UnresolvedImport 25 builtins.__dict__['property'] = new_property 26 except: 27 if DebugInfoHolder.DEBUG_TRACE_LEVEL: 28 traceback.print_exc() #@Reimport 29 return original 30 31 32#======================================================================================================================= 33# DebugProperty 34#======================================================================================================================= 35class DebugProperty(object): 36 """A custom property which allows python property to get 37 controlled by the debugger and selectively disable/re-enable 38 the tracing. 39 """ 40 41 42 def __init__(self, fget=None, fset=None, fdel=None, doc=None): 43 self.fget = fget 44 self.fset = fset 45 self.fdel = fdel 46 self.__doc__ = doc 47 48 49 def __get__(self, obj, objtype=None): 50 if obj is None: 51 return self 52 global_debugger = get_global_debugger() 53 try: 54 if global_debugger is not None and global_debugger.disable_property_getter_trace: 55 global_debugger.disable_tracing() 56 if self.fget is None: 57 raise AttributeError("unreadable attribute") 58 return self.fget(obj) 59 finally: 60 if global_debugger is not None: 61 global_debugger.enable_tracing() 62 63 def __set__(self, obj, value): 64 global_debugger = get_global_debugger() 65 try: 66 if global_debugger is not None and global_debugger.disable_property_setter_trace: 67 global_debugger.disable_tracing() 68 if self.fset is None: 69 raise AttributeError("can't set attribute") 70 self.fset(obj, value) 71 finally: 72 if global_debugger is not None: 73 global_debugger.enable_tracing() 74 75 def __delete__(self, obj): 76 global_debugger = get_global_debugger() 77 try: 78 if global_debugger is not None and global_debugger.disable_property_deleter_trace: 79 global_debugger.disable_tracing() 80 if self.fdel is None: 81 raise AttributeError("can't delete attribute") 82 self.fdel(obj) 83 finally: 84 if global_debugger is not None: 85 global_debugger.enable_tracing() 86 87 def getter(self, fget): 88 """Overriding getter decorator for the property 89 """ 90 self.fget = fget 91 return self 92 93 94 def setter(self, fset): 95 """Overriding setter decorator for the property 96 """ 97 self.fset = fset 98 return self 99 100 101 def deleter(self, fdel): 102 """Overriding deleter decorator for the property 103 """ 104 self.fdel = fdel 105 return self 106 107