17db96d56Sopenharmony_ciimport functools 27db96d56Sopenharmony_ciimport inspect 37db96d56Sopenharmony_ciimport reprlib 47db96d56Sopenharmony_ciimport sys 57db96d56Sopenharmony_ciimport traceback 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_cifrom . import constants 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_cidef _get_function_source(func): 117db96d56Sopenharmony_ci func = inspect.unwrap(func) 127db96d56Sopenharmony_ci if inspect.isfunction(func): 137db96d56Sopenharmony_ci code = func.__code__ 147db96d56Sopenharmony_ci return (code.co_filename, code.co_firstlineno) 157db96d56Sopenharmony_ci if isinstance(func, functools.partial): 167db96d56Sopenharmony_ci return _get_function_source(func.func) 177db96d56Sopenharmony_ci if isinstance(func, functools.partialmethod): 187db96d56Sopenharmony_ci return _get_function_source(func.func) 197db96d56Sopenharmony_ci return None 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci 227db96d56Sopenharmony_cidef _format_callback_source(func, args): 237db96d56Sopenharmony_ci func_repr = _format_callback(func, args, None) 247db96d56Sopenharmony_ci source = _get_function_source(func) 257db96d56Sopenharmony_ci if source: 267db96d56Sopenharmony_ci func_repr += f' at {source[0]}:{source[1]}' 277db96d56Sopenharmony_ci return func_repr 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_cidef _format_args_and_kwargs(args, kwargs): 317db96d56Sopenharmony_ci """Format function arguments and keyword arguments. 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci Special case for a single parameter: ('hello',) is formatted as ('hello'). 347db96d56Sopenharmony_ci """ 357db96d56Sopenharmony_ci # use reprlib to limit the length of the output 367db96d56Sopenharmony_ci items = [] 377db96d56Sopenharmony_ci if args: 387db96d56Sopenharmony_ci items.extend(reprlib.repr(arg) for arg in args) 397db96d56Sopenharmony_ci if kwargs: 407db96d56Sopenharmony_ci items.extend(f'{k}={reprlib.repr(v)}' for k, v in kwargs.items()) 417db96d56Sopenharmony_ci return '({})'.format(', '.join(items)) 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_cidef _format_callback(func, args, kwargs, suffix=''): 457db96d56Sopenharmony_ci if isinstance(func, functools.partial): 467db96d56Sopenharmony_ci suffix = _format_args_and_kwargs(args, kwargs) + suffix 477db96d56Sopenharmony_ci return _format_callback(func.func, func.args, func.keywords, suffix) 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci if hasattr(func, '__qualname__') and func.__qualname__: 507db96d56Sopenharmony_ci func_repr = func.__qualname__ 517db96d56Sopenharmony_ci elif hasattr(func, '__name__') and func.__name__: 527db96d56Sopenharmony_ci func_repr = func.__name__ 537db96d56Sopenharmony_ci else: 547db96d56Sopenharmony_ci func_repr = repr(func) 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_ci func_repr += _format_args_and_kwargs(args, kwargs) 577db96d56Sopenharmony_ci if suffix: 587db96d56Sopenharmony_ci func_repr += suffix 597db96d56Sopenharmony_ci return func_repr 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_cidef extract_stack(f=None, limit=None): 637db96d56Sopenharmony_ci """Replacement for traceback.extract_stack() that only does the 647db96d56Sopenharmony_ci necessary work for asyncio debug mode. 657db96d56Sopenharmony_ci """ 667db96d56Sopenharmony_ci if f is None: 677db96d56Sopenharmony_ci f = sys._getframe().f_back 687db96d56Sopenharmony_ci if limit is None: 697db96d56Sopenharmony_ci # Limit the amount of work to a reasonable amount, as extract_stack() 707db96d56Sopenharmony_ci # can be called for each coroutine and future in debug mode. 717db96d56Sopenharmony_ci limit = constants.DEBUG_STACK_DEPTH 727db96d56Sopenharmony_ci stack = traceback.StackSummary.extract(traceback.walk_stack(f), 737db96d56Sopenharmony_ci limit=limit, 747db96d56Sopenharmony_ci lookup_lines=False) 757db96d56Sopenharmony_ci stack.reverse() 767db96d56Sopenharmony_ci return stack 77