From 8d69d54238439a3d8e70c0a413adf325265b6886 Mon Sep 17 00:00:00 2001 From: James Ward Date: Mon, 13 Nov 2023 22:49:31 -0500 Subject: [PATCH] chore: make traceback module optional some boards don't provide traceback so we can add a minimal implementation that works _good enough_ in those cases so asyncio can still be used --- asyncio/core.py | 9 +++++-- asyncio/traceback.py | 57 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 asyncio/traceback.py diff --git a/asyncio/core.py b/asyncio/core.py index e31c1ce..5a18034 100644 --- a/asyncio/core.py +++ b/asyncio/core.py @@ -16,7 +16,12 @@ """ from adafruit_ticks import ticks_ms as ticks, ticks_diff, ticks_add -import sys, select, traceback +import sys, select + +try: + from traceback import print_exception +except: + from .traceback import print_exception # Import TaskQueue and Task, preferring built-in C code over Python code try: @@ -371,7 +376,7 @@ def default_exception_handler(loop, context): """The default exception handler that is called.""" exc = context["exception"] - traceback.print_exception(None, exc, exc.__traceback__) + print_exception(None, exc, exc.__traceback__) def call_exception_handler(context): """Call the current exception handler. The argument *context* is passed through diff --git a/asyncio/traceback.py b/asyncio/traceback.py new file mode 100644 index 0000000..eaf62ea --- /dev/null +++ b/asyncio/traceback.py @@ -0,0 +1,57 @@ +# SPDX-FileCopyrightText: 2019-2020 Damien P. George +# +# SPDX-License-Identifier: MIT +# +# MicroPython uasyncio module +# MIT license; Copyright (c) 2019-2020 Damien P. George +""" +Fallback traceback module if the system traceback is missing. +""" + +try: + from typing import List +except ImportError: + pass + +import sys + + +def _print_traceback(traceback, limit=None, file=sys.stderr) -> List[str]: + if limit is None: + if hasattr(sys, "tracebacklimit"): + limit = sys.tracebacklimit + + n = 0 + while traceback is not None: + frame = traceback.tb_frame + line_number = traceback.tb_lineno + frame_code = frame.f_code + filename = frame_code.co_filename + name = frame_code.co_name + print(' File "%s", line %d, in %s' % (filename, line_number, name), file=file) + traceback = traceback.tb_next + n = n + 1 + if limit is not None and n >= limit: + break + + +def print_exception(exception, value=None, traceback=None, limit=None, file=sys.stderr): + """ + Print exception information and stack trace to file. + """ + if traceback: + print("Traceback (most recent call last):", file=file) + _print_traceback(traceback, limit=limit, file=file) + + if isinstance(exception, BaseException): + exception_type = type(exception).__name__ + elif hasattr(exception, "__name__"): + exception_type = exception.__name__ + else: + exception_type = type(value).__name__ + + valuestr = str(value) + if value is None or not valuestr: + print(exception_type, file=file) + else: + print("%s: %s" % (str(exception_type), valuestr), file=file)