def decorator(func): chain = DecoratorChain.get(func) padding = 3 def logger(self, *args): if len(arg_names) != len(args): e = 'Number of prototypes doesn\'t match number of args' raise Exception(e) log_lines = ['%s(' % func.__name__] last_arg_idx = len(args) - 1 for idx, arg in enumerate(args): wrapper = isinstance(arg, DataWrapper) lines = arg.debug_repr() if wrapper else \ '\'' + str(arg) + '\'' if isinstance(arg, str) else str(arg) lines = lines.splitlines() log = '%s%s = %s' % (' ' * padding, arg_names[idx], lines[0]) log_lines.append(log) for line in lines[1:]: log_lines.append(' ' * padding + line) if idx != last_arg_idx: log_lines[-1] += ',' log_lines.append(')') # Ставим блокировку на время записи в лог, чтобы сообщения от разных # потоков не перемешивались self.log_lock.acquire() try: log = self.app.log for line in log_lines: log.debug(line) finally: self.log_lock.release() retval = chain.call(self, *args) self.log_lock.acquire() try: log.debug('%s(): %s ' % (func.__name__, retval)) finally: self.log_lock.release() return retval chain.append(logger) return chain.caller
def decorator(func): chain = DecoratorChain.get(func) def converter(self, *call_args): if len(proto_args) != len(call_args): e = 'Number of prototypes doesn\'t match number of args' raise Exception(e) call_args = list(call_args) for idx, proto in enumerate(proto_args): if proto is not None: arg = call_args[idx] arg = proto(arg) call_args[idx] = arg return chain.call(self, *call_args) chain.append(converter) return chain.caller
def debug(func): chain = DecoratorChain.get(func) func = chain.get_func() def debugger(*args, **kwargs): # Если включен режим принудительной отладки if module.mode == True: # Если функция в списке функций, для которых отладка задействована if module.catch_funcs[func.__name__]: # Останавливаем выполнение кода force_breakpoint() return chain.call(*args, **kwargs) # Если функции ещё нет в списке перехватываемых функций if func.__name__ not in module.catch_funcs: # то вносим в список и включаем перехват enable(func.__name__) #chain.append(wrapper) # Вставляем наш декоратор первым в цепочку, в таком случае он будет # декорировать саму функцию и будет вызван последним изо всех декораторов chain.insert(0, debugger) return chain.caller