def inner(*args, **kwargs): t1 = timeutils.now() t2 = None try: with lock(name, lock_file_prefix, external, lock_path, do_log=False, semaphores=semaphores, delay=delay, fair=fair): t2 = timeutils.now() LOG.debug('Lock "%(name)s" acquired by "%(function)s" :: ' 'waited %(wait_secs)0.3fs', {'name': name, 'function': reflection.get_callable_name(f), 'wait_secs': (t2 - t1)}) return f(*args, **kwargs) finally: t3 = timeutils.now() if t2 is None: held_secs = "N/A" else: held_secs = "%0.3fs" % (t3 - t2) LOG.debug('Lock "%(name)s" released by "%(function)s" :: held ' '%(held_secs)s', {'name': name, 'function': reflection.get_callable_name(f), 'held_secs': held_secs})
def _periodics_watchdog(self, callable_, activity, spacing, exc_info, traceback=None): LOG.exception("The periodic %(callable)s failed with: %(exception)s", { 'exception': ''.join(traceback_mod.format_exception(*exc_info)), 'callable': reflection.get_callable_name(callable_)}) # NOTE(milan): spawn new thread otherwise waiting would block eventlet.spawn(self.del_host)
def test_inner_class(self): obj = self.InnerCallableClass() name = reflection.get_callable_name(obj) expected_name = '.'.join((__name__, 'GetCallableNameTestExtended', 'InnerCallableClass')) self.assertEqual(expected_name, name)
def __init__(self, execute, name=None, provides=None, requires=None, auto_extract=True, rebind=None, revert=None, version=None, inject=None): if not six.callable(execute): raise ValueError("Function to use for executing must be" " callable") if revert is not None: if not six.callable(revert): raise ValueError("Function to use for reverting must" " be callable") if name is None: name = reflection.get_callable_name(execute) super(FunctorTask, self).__init__(name, provides=provides, inject=inject) self._execute = execute self._revert = revert if version is not None: self.version = version mapping = self._build_arg_mapping(execute, requires, rebind, auto_extract) self.rebind, exec_requires, self.optional = mapping if revert: revert_mapping = self._build_arg_mapping(revert, requires, rebind, auto_extract) else: revert_mapping = (self.rebind, exec_requires, self.optional) (self.revert_rebind, revert_requires, self.revert_optional) = revert_mapping self.requires = exec_requires.union(revert_requires)
def wrapper(*args, **kwargs): # NOTE(tovin07): Workaround for this issue # F823 local variable 'info' # (defined in enclosing scope on line xxx) # referenced before assignment info_ = info if "name" not in info_["function"]: # Get this once (as it should **not** be changing in # subsequent calls). info_["function"]["name"] = reflection.get_callable_name(f) if not hide_args: info_["function"]["args"] = str(args) info_["function"]["kwargs"] = str(kwargs) stop_info = None try: start(name, info=info_) result = f(*args, **kwargs) except Exception as ex: stop_info = { "etype": reflection.get_class_name(ex), "message": six.text_type(ex) } raise else: if not hide_result: stop_info = {"function": {"result": repr(result)}} return result finally: if stop_info: stop(info=stop_info) else: stop()
def wrapper(*args, **kwargs): next_interval = self.retry_interval remaining = self.max_retries while True: try: return f(*args, **kwargs) except Exception as e: with excutils.save_and_reraise_exception() as ectxt: if remaining > 0: ectxt.reraise = not self._is_exception_expected(e) else: LOG.exception(_LE('DB exceeded retry limit.')) # if it's a RetryRequest, we need to unpack it if isinstance(e, exception.RetryRequest): ectxt.type_ = type(e.inner_exc) ectxt.value = e.inner_exc LOG.debug("Performing DB retry for function %s", reflection.get_callable_name(f)) # NOTE(vsergeyev): We are using patched time module, so # this effectively yields the execution # context to another green thread. time.sleep(next_interval) if self.inc_retry_interval: next_interval = min( next_interval * 2, self.max_retry_interval ) remaining -= 1
def _delayed_process(self, func): """Runs the function using the instances executor (eventually). This adds a *nice* benefit on showing how long it took for the function to finally be executed from when the message was received to when it was finally ran (which can be a nice thing to know to determine bottle-necks...). """ func_name = reflection.get_callable_name(func) def _on_run(watch, content, message): LOG.trace("It took %s seconds to get around to running" " function/method '%s' with" " message '%s'", watch.elapsed(), func_name, ku.DelayedPretty(message)) return func(content, message) def _on_receive(content, message): LOG.debug("Submitting message '%s' for execution in the" " future to '%s'", ku.DelayedPretty(message), func_name) watch = timeutils.StopWatch() watch.start() try: self._executor.submit(_on_run, watch, content, message) except RuntimeError: LOG.error("Unable to continue processing message '%s'," " submission to instance executor (with later" " execution by '%s') was unsuccessful", ku.DelayedPretty(message), func_name, exc_info=True) return _on_receive
def __init__(self, functor, requires, name=None, provides=None, auto_extract=True, rebind=None, inject=None): if not six.callable(functor): raise ValueError("Function to use for reduce must be callable") f_args = reflection.get_callable_args(functor) if len(f_args) != 2: raise ValueError("%s arguments were provided. Reduce functor " "must take exactly 2 arguments." % len(f_args)) if not misc.is_iterable(requires): raise TypeError("%s type was provided for requires. Requires " "must be an iterable." % type(requires)) if len(requires) < 2: raise ValueError("%s elements were provided. Requires must have " "at least 2 elements." % len(requires)) if name is None: name = reflection.get_callable_name(functor) super(ReduceFunctorTask, self).__init__(name=name, provides=provides, inject=inject, requires=requires, rebind=rebind, auto_extract=auto_extract) self._functor = functor
def _run_loop(self, kind, event, idle_for_func, initial_delay=None, stop_on_exception=True): func_name = reflection.get_callable_name(self.f) func = self.f if stop_on_exception else _safe_wrapper(self.f, kind, func_name) if initial_delay: greenthread.sleep(initial_delay) try: watch = timeutils.StopWatch() while self._running: watch.restart() result = func(*self.args, **self.kw) watch.stop() if not self._running: break idle = idle_for_func(result, watch.elapsed()) LOG.trace('%(kind)s %(func_name)r sleeping ' 'for %(idle).02f seconds', {'func_name': func_name, 'idle': idle, 'kind': kind}) greenthread.sleep(idle) except LoopingCallDone as e: event.send(e.retvalue) except Exception: exc_info = sys.exc_info() try: LOG.error(_LE('%(kind)s %(func_name)r failed'), {'kind': kind, 'func_name': func_name}, exc_info=exc_info) event.send_exception(*exc_info) finally: del exc_info return else: event.send(True)
def inner(*args, **kwargs): try_count = 0 sleep_time = 0 while True: try: return f(*args, **kwargs) except exceptions as exc: with excutils.save_and_reraise_exception() as ctxt: err_code = getattr(exc, 'error_code', None) expected_err_code = (err_code in error_codes or not error_codes) should_retry = (expected_err_code and try_count < max_retry_count) ctxt.reraise = not should_retry if should_retry: try_count += 1 func_name = reflection.get_callable_name(f) LOG.debug("Got expected exception %(exc)s while " "calling function %(func_name)s. " "Retries left: %(retries_left)d. " "Retrying in %(sleep_time)s seconds.", dict(exc=exc, func_name=func_name, retries_left=( max_retry_count - try_count), sleep_time=sleep_time)) sleep_time = min(sleep_time + inc_sleep_time, max_sleep_time) time.sleep(sleep_time)
def wrapper(*args, **kwargs): next_interval = self.retry_interval remaining = self.max_retries while True: try: return f(*args, **kwargs) except Exception as e: with excutils.save_and_reraise_exception() as ectxt: if remaining > 0: ectxt.reraise = not self._is_exception_expected(e) else: LOG.exception(_LE('Function exceeded ' 'retry limit.')) LOG.debug("Performing retry for function %s", reflection.get_callable_name(f)) # NOTE(vsergeyev): We are using patched time module, so # this effectively yields the execution # context to another green thread. time.sleep(next_interval) if self.inc_retry_interval: next_interval = min( next_interval * 2, self.max_retry_interval ) remaining -= 1
def _get_id(callback): """Return a unique identifier for the callback.""" # TODO(armax): consider using something other than names # https://www.python.org/dev/peps/pep-3155/, but this # might be okay for now. parts = (reflection.get_callable_name(callback), str(hash(callback))) return '-'.join(parts)
def _idle_for(result, elapsed): delay = elapsed - interval if delay > 0: func_name = reflection.get_callable_name(self.f) LOG.warning(_LW('Function %(func_name)r run outlasted ' 'interval by %(delay).2f sec'), {'func_name': func_name, 'delay': delay}) return -delay if delay < 0 else 0
def test_static_method(self): name = reflection.get_callable_name(Class.static_method) if six.PY3: self.assertEqual('.'.join((__name__, 'Class', 'static_method')), name) else: # NOTE(imelnikov): static method are just functions, class name # is not recorded anywhere in them. self.assertEqual('.'.join((__name__, 'static_method')), name)
def wrapper(*args, **kwargs): with StopWatch() as w: result = func(*args, **kwargs) time_taken = w.elapsed() if min_duration is None or time_taken >= min_duration: logger.log(log_level, message, {'seconds': time_taken, 'func_name': reflection.get_callable_name(func)}) return result
def inner(*args, **kwargs): try_count = 0 sleep_time = 0 time_start = time.time() retry_context = dict(prevent_retry=False) if pass_retry_context: kwargs['retry_context'] = retry_context while True: try: return f(*args, **kwargs) except exceptions as exc: with excutils.save_and_reraise_exception() as ctxt: err_code = getattr(exc, 'error_code', None) expected_err_code = (err_code in error_codes or not error_codes) time_elapsed = time.time() - time_start time_left = (timeout - time_elapsed if timeout else 'undefined') tries_left = (max_retry_count - try_count if max_retry_count is not None else 'undefined') should_retry = ( not retry_context['prevent_retry'] and expected_err_code and tries_left and (time_left == 'undefined' or time_left > 0)) ctxt.reraise = not should_retry if should_retry: try_count += 1 func_name = reflection.get_callable_name(f) sleep_time = min(sleep_time + inc_sleep_time, max_sleep_time) if timeout: sleep_time = min(sleep_time, time_left) LOG.debug("Got expected exception %(exc)s while " "calling function %(func_name)s. " "Retries left: %(retries_left)s. " "Time left: %(time_left)s. " "Time elapsed: %(time_elapsed)s " "Retrying in %(sleep_time)s seconds.", dict(exc=exc, func_name=func_name, retries_left=tries_left, time_left=time_left, time_elapsed=time_elapsed, sleep_time=sleep_time)) time.sleep(sleep_time)
def _make_logger(self, level=logging.DEBUG): log = logging.getLogger(reflection.get_callable_name(self._get_test_method())) log.propagate = False for handler in reversed(log.handlers): log.removeHandler(handler) handler = test.CapturingLoggingHandler(level=level) log.addHandler(handler) log.setLevel(level) self.addCleanup(handler.reset) self.addCleanup(log.removeHandler, handler) return (log, handler)
def ins_wrap(self): if not set(dialects).issubset(ALLOWED_DIALECTS): raise ValueError( "Please use allowed dialects: %s" % ALLOWED_DIALECTS) if self.engine.name not in dialects: msg = ('The test "%s" can be run ' 'only on %s. Current engine is %s.') args = (reflection.get_callable_name(f), ' '.join(dialects), self.engine.name) self.skip(msg % args) else: return f(self)
def wrapper(*args, **kwargs): if "name" not in info["function"]: # Get this once (as it should **not** be changing in # subsequent calls). info["function"]["name"] = reflection.get_callable_name(f) if not hide_args: info["function"]["args"] = str(args) info["function"]["kwargs"] = str(kwargs) with Trace(name, info=info): return f(*args, **kwargs)
def inner(node_info, *args, **kwargs): ret = None try: ret = func(node_info, *args, **kwargs) except no_errors as exc: LOG.debug('Not processing error event for the ' 'exception: %(exc)s raised by %(func)s', {'exc': exc, 'func': reflection.get_callable_name(func)}, node_info=node_info) except errors as exc: with excutils.save_and_reraise_exception(): LOG.error('Processing the error event because of an ' 'exception %(exc_type)s: %(exc)s raised by ' '%(func)s', {'exc_type': type(exc), 'exc': exc, 'func': reflection.get_callable_name(func)}, node_info=node_info) # an error event should be possible from all states node_info.finished(istate.Events.error, error=str(exc)) return ret
def _idle_for(result, elapsed): delay = round(elapsed - interval, 2) if delay > 0: func_name = reflection.get_callable_name(self.f) LOG.warning('Function %(func_name)r run outlasted ' 'interval by %(delay).2f sec', {'func_name': func_name, 'delay': delay}) elapsed_time = time.time() - start_time if timeout > 0 and elapsed_time > timeout: raise LoopingCallTimeOut( _('Looping call timed out after %.02f seconds') % elapsed_time) return -delay if delay < 0 else 0
def test_inner_callable_function(self): def a(): def b(): pass return b name = reflection.get_callable_name(a()) expected_name = '.'.join((__name__, 'GetCallableNameTestExtended', 'test_inner_callable_function', '<locals>', 'a', '<locals>', 'b')) self.assertEqual(expected_name, name)
def wrapper(f, instance, args, kwargs): qualified, f_name = _get_qualified_name(f) if qualified: if inspect.isclass(f): prefix_pre = "Using class" thing_post = '' else: prefix_pre = "Using function/method" thing_post = '()' if not qualified: prefix_pre = "Using function/method" base_name = None if instance is None: # Decorator was used on a class if inspect.isclass(f): prefix_pre = "Using class" thing_post = '' module_name = _get_module_name(inspect.getmodule(f)) if module_name == '__main__': f_name = reflection.get_class_name( f, fully_qualified=False) else: f_name = reflection.get_class_name( f, fully_qualified=True) # Decorator was a used on a function else: thing_post = '()' module_name = _get_module_name(inspect.getmodule(f)) if module_name != '__main__': f_name = reflection.get_callable_name(f) # Decorator was used on a classmethod or instancemethod else: thing_post = '()' base_name = reflection.get_class_name(instance, fully_qualified=False) if base_name: thing_name = ".".join([base_name, f_name]) else: thing_name = f_name else: thing_name = f_name if thing_post: thing_name += thing_post prefix = prefix_pre + " '%s' is deprecated" % (thing_name) out_message = _utils.generate_message( prefix, version=version, removal_version=removal_version, message=message) _utils.deprecation(out_message, stacklevel) return f(*args, **kwargs)
def _fetch_validate_factory(flow_factory): if isinstance(flow_factory, six.string_types): factory_fun = _fetch_factory(flow_factory) factory_name = flow_factory else: factory_fun = flow_factory factory_name = reflection.get_callable_name(flow_factory) try: reimported = _fetch_factory(factory_name) assert reimported == factory_fun except (ImportError, AssertionError): raise ValueError('Flow factory %r is not reimportable by name %s' % (factory_fun, factory_name)) return (factory_name, factory_fun)
def __init__(self, volume_id): # Note here that the volume name is composed of the name of the class # along with the volume id that is being created, since a name of a # task uniquely identifies that task in storage it is important that # the name be relevant and identifiable if the task is recreated for # subsequent resumption (if applicable). # # UUIDs are *not* used as they can not be tied back to a previous tasks # state on resumption (since they are unique and will vary for each # task that is created). A name based off the volume id that is to be # created is more easily tied back to the original task so that the # volume create can be resumed/revert, and is much easier to use for # audit and tracking purposes. base_name = reflection.get_callable_name(self) super(VolumeCreator, self).__init__(name="%s-%s" % (base_name, volume_id)) self._volume_id = volume_id
def __call__(self, f): func_name = reflection.get_callable_name(f) def _func(*args, **kwargs): result = None try: if self._retry_count: LOG.debug("Invoking %(func_name)s; retry count is " "%(retry_count)d.", {'func_name': func_name, 'retry_count': self._retry_count}) result = f(*args, **kwargs) except self._exceptions: with excutils.save_and_reraise_exception() as ctxt: LOG.warn(_LW("Exception which is in the suggested list of " "exceptions occurred while invoking function:" " %s."), func_name, exc_info=True) if (self._max_retry_count != -1 and self._retry_count >= self._max_retry_count): LOG.error(_LE("Cannot retry %(func_name)s upon " "suggested exception " "since retry count (%(retry_count)d) " "reached max retry count " "(%(max_retry_count)d)."), {'retry_count': self._retry_count, 'max_retry_count': self._max_retry_count, 'func_name': func_name}) else: ctxt.reraise = False self._retry_count += 1 self._sleep_time += self._inc_sleep_time return self._sleep_time raise LoopingCallDone(result) @six.wraps(f) def func(*args, **kwargs): loop = DynamicLoopingCall(_func, *args, **kwargs) evt = loop.start(periodic_interval_max=self._max_sleep_time) LOG.debug("Waiting for function %s to return.", func_name) return evt.wait() return func
def wrapper(*args, **kwargs): sleep_time = next_interval = self.retry_interval remaining = self.max_retries while True: try: return f(*args, **kwargs) except Exception as e: with excutils.save_and_reraise_exception() as ectxt: expected = self._is_exception_expected(e) if remaining > 0: ectxt.reraise = not expected else: if expected: LOG.exception('DB exceeded retry limit.') # if it's a RetryRequest, we need to unpack it if isinstance(e, exception.RetryRequest): ectxt.type_ = type(e.inner_exc) ectxt.value = e.inner_exc LOG.debug("Performing DB retry for function %s", reflection.get_callable_name(f)) # NOTE(vsergeyev): We are using patched time module, so # this effectively yields the execution # context to another green thread. time.sleep(sleep_time) if self.inc_retry_interval: # NOTE(jiangyikun): In order to minimize the chance of # regenerating a deadlock and reduce the average sleep # time, we are using jitter by default when the # deadlock is detected. With the jitter, # sleep_time = [0, next_interval), otherwise, without # the jitter, sleep_time = next_interval. if isinstance(e, exception.DBDeadlock): jitter = True else: jitter = self.jitter sleep_time, next_interval = self._get_inc_interval( next_interval, jitter) remaining -= 1
def wrapper(*args, **kwargs): next_interval = self.retry_interval remaining = self.max_retries while True: try: return f(*args, **kwargs) except Exception as e: with excutils.save_and_reraise_exception() as ectxt: if remaining > 0: ectxt.reraise = not self._is_exception_expected(e) else: LOG.exception('Function exceeded ' 'retry limit.') LOG.debug("Performing retry for function %s", reflection.get_callable_name(f)) # NOTE(vsergeyev): We are using patched time module, so # this effectively yields the execution # context to another green thread. time.sleep(next_interval) if self.inc_retry_interval: next_interval = min(next_interval * 2, self.max_retry_interval) remaining -= 1
def __init__(self, callables, tombstone=None): if tombstone is None: self._tombstone = tu.Event() else: # Allows someone to share an event (if they so want to...) self._tombstone = tombstone almost_callables = list(callables) for cb in almost_callables: if not six.callable(cb): raise ValueError("Periodic callback must be callable") for attr_name in _PERIODIC_ATTRS: if not hasattr(cb, attr_name): raise ValueError("Periodic callback missing required" " attribute '%s'" % attr_name) self._callables = tuple((cb, reflection.get_callable_name(cb)) for cb in almost_callables) self._schedule = [] now = _now() for i, (cb, cb_name) in enumerate(self._callables): spacing = cb._periodic_spacing next_run = now + spacing heapq.heappush(self._schedule, (next_run, i)) self._immediates = self._fetch_immediates(self._callables)
def _delayed_process(self, func): """Runs the function using the instances executor (eventually). This adds a *nice* benefit on showing how long it took for the function to finally be executed from when the message was received to when it was finally ran (which can be a nice thing to know to determine bottle-necks...). """ func_name = reflection.get_callable_name(func) def _on_run(watch, content, message): LOG.trace( "It took %s seconds to get around to running" " function/method '%s' with" " message '%s'", watch.elapsed(), func_name, ku.DelayedPretty(message)) return func(content, message) def _on_receive(content, message): LOG.debug( "Submitting message '%s' for execution in the" " future to '%s'", ku.DelayedPretty(message), func_name) watch = timeutils.StopWatch() watch.start() try: self._executor.submit(_on_run, watch, content, message) except RuntimeError: LOG.error( "Unable to continue processing message '%s'," " submission to instance executor (with later" " execution by '%s') was unsuccessful", ku.DelayedPretty(message), func_name, exc_info=True) return _on_receive
def __init__(self, functor, requires, name=None, provides=None, auto_extract=True, rebind=None, inject=None): if not six.callable(functor): raise ValueError("Function to use for map must be callable") f_args = reflection.get_callable_args(functor) if len(f_args) != 1: raise ValueError("%s arguments were provided. Map functor must " "take exactly 1 argument." % len(f_args)) if not misc.is_iterable(requires): raise TypeError("%s type was provided for requires. Requires " "must be an iterable." % type(requires)) if name is None: name = reflection.get_callable_name(functor) super(MapFunctorTask, self).__init__(name=name, provides=provides, inject=inject) self._functor = functor self._build_arg_mapping(executor=self.execute, requires=requires, rebind=rebind, auto_extract=auto_extract)
def _run_loop(self, idle_for_func, initial_delay=None, stop_on_exception=True): kind = self._KIND func_name = reflection.get_callable_name(self.f) func = self.f if stop_on_exception else _safe_wrapper(self.f, kind, func_name) if initial_delay: greenthread.sleep(initial_delay) try: watch = timeutils.StopWatch() while self._running: watch.restart() result = func(*self.args, **self.kw) watch.stop() if not self._running: break idle = idle_for_func(result, watch.elapsed()) LOG.trace('%(kind)s %(func_name)r sleeping ' 'for %(idle).02f seconds', {'func_name': func_name, 'idle': idle, 'kind': kind}) greenthread.sleep(idle) except LoopingCallDone as e: self.done.send(e.retvalue) except Exception: exc_info = sys.exc_info() try: LOG.error(_LE('%(kind)s %(func_name)r failed'), {'kind': kind, 'func_name': func_name}, exc_info=exc_info) self.done.send_exception(*exc_info) finally: del exc_info return else: self.done.send(True)
def test_constructor(self): name = reflection.get_callable_name(Class) self.assertEqual('.'.join((__name__, 'Class')), name)
from oslo_utils import units from oslo_utils import reflection for n in reflection.get_members(units): print("%s: %s" % (reflection.get_callable_name(n), n)) print(units.E)
def test_mere_function(self): name = reflection.get_callable_name(mere_function) self.assertEqual('.'.join((__name__, 'mere_function')), name)
def test_instance_method(self): name = reflection.get_callable_name(Class().method) self.assertEqual('.'.join((__name__, 'Class', 'method')), name)
def test_class_method(self): name = reflection.get_callable_name(Class.class_method) self.assertEqual('.'.join((__name__, 'Class', 'class_method')), name)
def test_inner_class(self): obj = self.InnerCallableClass() name = reflection.get_callable_name(obj) expected_name = '.'.join( (__name__, 'GetCallableNameTestExtended', 'InnerCallableClass')) self.assertEqual(expected_name, name)
def test_callable_class_call(self): name = reflection.get_callable_name(CallableClass().__call__) self.assertEqual('.'.join((__name__, 'CallableClass', '__call__')), name)
def _get_id(callback): """Return a unique identifier for the callback.""" # TODO(armax): consider using something other than names # https://www.python.org/dev/peps/pep-3155/, but this # might be okay for now. return reflection.get_callable_name(callback)
def decorator(f): if inspect.isbuiltin(f): info['tracepoint_id'] = '%s/builtin:%s' % ( getpass.getuser(), reflection.get_callable_name(f)) else: source_file = inspect.getsourcefile(f) try: source_lines = inspect.getsourcelines(f)[1] except IOError: source_lines = -1 info['tracepoint_id'] = '%s%s:%d:%s' % ( getpass.getuser(), source_file, source_lines, reflection.get_callable_name(f)) manifest_file = '/opt/stack/manifest/%s' % info['tracepoint_id'] try: os.makedirs(os.path.dirname(manifest_file)) except OSError: # directory exists pass if CREATE_MANIFEST and not os.path.isfile(manifest_file): with open(manifest_file, 'w') as mf: mf.write('1') trace_times = getattr(f, "__traced__", 0) if not allow_multiple_trace and trace_times: raise ValueError("Function '%s' has already" " been traced %s times" % (f, trace_times)) # Disable tracing by setting __traced__ to -1 if trace_times < 0: return f try: f.__traced__ = trace_times + 1 except AttributeError: # Tries to work around the following: # # AttributeError: 'instancemethod' object has no # attribute '__traced__' try: f.im_func.__traced__ = trace_times + 1 except AttributeError: # nosec pass @functools.wraps(f) def wrapper(*args, **kwargs): # NOTE(tovin07): Workaround for this issue # F823 local variable 'info' # (defined in enclosing scope on line xxx) # referenced before assignment if immortal: enabled = True else: enabled = _check_enabled(manifest_file) if not enabled: return f(*args, **kwargs) info_ = info if "name" not in info_["function"]: # Get this once (as it should **not** be changing in # subsequent calls). info_["function"]["name"] = reflection.get_callable_name(f) if not hide_args: info_["function"]["args"] = str(args) info_["function"]["kwargs"] = str(kwargs) stop_info = None try: start(name, info=info_) result = f(*args, **kwargs) except Exception as ex: stop_info = { "etype": reflection.get_class_name(ex), "message": six.text_type(ex) } raise else: if not hide_result: stop_info = {"function": {"result": repr(result)}} return result finally: if stop_info: stop(info=stop_info) else: stop() return wrapper
def pformat(self, bot): base = 'args_key_is_empty_or_allowed' func_name = reflection.get_callable_name(self.allowed_extractor_func) return '%s(%r, %s)' % (base, self.args_key, func_name)
kwargs_func('0', 1, 2, 3, 4, k1=5, k2=6) class A(object): pass class B(A): pass class C(B): pass for m in [ reflection.get_callable_args, reflection.get_callable_name, reflection.accepts_kwargs ]: for n in [args_func, kwargs_func]: print("%-50s (%-20s): %s" % (reflection.get_callable_name(m), reflection.get_callable_name(n), m(n))) print(list(reflection.get_all_class_names(C()))) # Special arguments (like *args and **kwargs) are not included into output. #print(reflection.get_callable_args(args_func)) #print(reflection.get_callable_args(kwargs_func))