Skip to content

Commit da52b43

Browse files
committed
bdb: Add initial micropython support.
Requires micropython to be compiled with MICROPY_PY_SYS_SETTRACE. Also requires micropython/micropython#8767
1 parent ab4929d commit da52b43

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

python-stdlib/bdb/bdb.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
"""Debugger basics"""
22

3+
# This is originally from cpython 3.10: https://raw.githubusercontent.com/python/cpython/3.10/Lib/bdb.py
4+
# Patches for micropython have been commented as such.
5+
36
import fnmatch
47
import sys
58
import os
6-
from inspect import CO_GENERATOR, CO_COROUTINE, CO_ASYNC_GENERATOR
9+
10+
## MPY: no inspect module avaialble
11+
# from inspect import CO_GENERATOR, CO_COROUTINE, CO_ASYNC_GENERATOR
712

813
__all__ = ["BdbQuit", "Bdb", "Breakpoint"]
914

10-
GENERATOR_AND_COROUTINE_FLAGS = CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR
15+
## MPY: These flags currently don't exist
16+
# GENERATOR_AND_COROUTINE_FLAGS = CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR
1117

1218

1319
class BdbQuit(Exception):
@@ -115,6 +121,12 @@ def dispatch_line(self, frame):
115121
if self.quitting: raise BdbQuit
116122
return self.trace_dispatch
117123

124+
def is_coroutine(self, frame):
125+
## MPY: co_flags attrib not available, compatible method of detecting coroutine TBD
126+
# return frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS
127+
return False
128+
129+
118130
def dispatch_call(self, frame, arg):
119131
"""Invoke user function and return trace function for call event.
120132
@@ -131,7 +143,7 @@ def dispatch_call(self, frame, arg):
131143
# No need to trace this function
132144
return # None
133145
# Ignore call events in generator except when stepping.
134-
if self.stopframe and frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS:
146+
if self.stopframe and self.is_coroutine(frame):
135147
return self.trace_dispatch
136148
self.user_call(frame, arg)
137149
if self.quitting: raise BdbQuit
@@ -146,7 +158,7 @@ def dispatch_return(self, frame, arg):
146158
"""
147159
if self.stop_here(frame) or frame == self.returnframe:
148160
# Ignore return events in generator except when stepping.
149-
if self.stopframe and frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS:
161+
if self.stopframe and self.is_coroutine(frame):
150162
return self.trace_dispatch
151163
try:
152164
self.frame_returning = frame
@@ -170,7 +182,7 @@ def dispatch_exception(self, frame, arg):
170182
# When stepping with next/until/return in a generator frame, skip
171183
# the internal StopIteration exception (with no traceback)
172184
# triggered by a subiterator run with the 'yield from' statement.
173-
if not (frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS
185+
if not (self.is_coroutine(frame)
174186
and arg[0] is StopIteration and arg[2] is None):
175187
self.user_exception(frame, arg)
176188
if self.quitting: raise BdbQuit
@@ -179,7 +191,7 @@ def dispatch_exception(self, frame, arg):
179191
# next/until command at the last statement in the generator before the
180192
# exception.
181193
elif (self.stopframe and frame is not self.stopframe
182-
and self.stopframe.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS
194+
and self.is_coroutine(self.stopframe)
183195
and arg[0] in (StopIteration, GeneratorExit)):
184196
self.user_exception(frame, arg)
185197
if self.quitting: raise BdbQuit
@@ -315,7 +327,7 @@ def set_next(self, frame):
315327

316328
def set_return(self, frame):
317329
"""Stop when returning from the given frame."""
318-
if frame.f_code.co_flags & GENERATOR_AND_COROUTINE_FLAGS:
330+
if self.is_coroutine(frame):
319331
self._set_stopinfo(frame, None, -1)
320332
else:
321333
self._set_stopinfo(frame.f_back, frame)
@@ -557,7 +569,8 @@ def format_stack_entry(self, frame_lineno, lprefix=': '):
557569
line of code (if it exists).
558570
559571
"""
560-
import linecache, reprlib
572+
## MPY: reprlib not yet available
573+
import linecache #, reprlib
561574
frame, lineno = frame_lineno
562575
filename = self.canonic(frame.f_code.co_filename)
563576
s = '%s(%r)' % (filename, lineno)
@@ -569,7 +582,7 @@ def format_stack_entry(self, frame_lineno, lprefix=': '):
569582
if '__return__' in frame.f_locals:
570583
rv = frame.f_locals['__return__']
571584
s += '->'
572-
s += reprlib.repr(rv)
585+
s += repr(rv)
573586
line = linecache.getline(filename, lineno, frame.f_globals)
574587
if line:
575588
s += lprefix + line.strip()
@@ -628,7 +641,7 @@ def runctx(self, cmd, globals, locals):
628641

629642
# This method is more useful to debug a single function call.
630643

631-
def runcall(self, func, /, *args, **kwds):
644+
def runcall(self, func, *args, **kwds):
632645
"""Debug a single function call.
633646
634647
Return the result of the function call.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy