6666"""
6767# NOTE: the actual command documentation is collected from docstrings of the
6868# commands and is appended to __doc__ after the class has been defined.
69-
69+ import builtins as __builtins__
7070import os
7171import io
7272import re
7373import sys
7474import cmd
7575import bdb
76- import dis
76+ # import dis # MPY: dis not currently available
7777import code
7878import glob
7979import pprint
80- import signal
81- import inspect
80+ # import signal # MPY: signal not currently available
81+ # import inspect # MPY: inspect not currently available
8282import tokenize
83- import functools
83+ # import functools
8484import traceback
8585import linecache
8686
87- from typing import Union
87+ try :
88+ from typing import Union
89+ except ImportError :
90+ pass
8891
8992
9093class Restart (Exception ):
@@ -104,7 +107,9 @@ def find_function(funcname, filename):
104107with fp :
105108for lineno ,line in enumerate (fp ,start = 1 ):
106109if cre .match (line ):
107- return funcname ,filename ,lineno
110+ ## MPY: increment line number by 1 as we want to break on the
111+ # first line of the function, not the function def line itself
112+ return funcname ,filename ,lineno + 1
108113return None
109114
110115def getsourcelines (obj ):
@@ -117,11 +122,12 @@ def getsourcelines(obj):
117122return inspect .getblock (lines [lineno :]),lineno + 1
118123
119124def lasti2lineno (code ,lasti ):
120- linestarts = list (dis .findlinestarts (code ))
121- linestarts .reverse ()
122- for i ,lineno in linestarts :
123- if lasti >= i :
124- return lineno
125+ ## MPY: dis not currently available
126+ # linestarts = list(dis.findlinestarts(code))
127+ # linestarts.reverse()
128+ # for i, lineno in linestarts:
129+ # if lasti >= i:
130+ # return lineno
125131return 0
126132
127133
@@ -131,40 +137,39 @@ def __repr__(self):
131137return self
132138
133139
134- class ScriptTarget ( str ) :
135- def __new__ ( cls ,val ):
140+ class ScriptTarget :
141+ def __init__ ( self ,val ):
136142# Mutate self to be the "real path".
137- res = super (). __new__ ( cls , os .path .realpath (val ) )
143+ self . path = os .path .realpath (val )
138144
139145# Store the original path for error reporting.
140- res .orig = val
141-
142- return res
146+ self .orig = val
143147
144148def check (self ):
145- if not os .path .exists (self ):
149+ if not os .path .exists (self . path ):
146150print ('Error:' ,self .orig ,'does not exist' )
147151sys .exit (1 )
148152
149153# Replace pdb's dir with script's dir in front of module search path.
150- sys .path [0 ]= os .path .dirname (self )
154+ sys .path [0 ]= os .path .dirname (self . path )
151155
152156@property
153157def filename (self ):
154- return self
158+ return self . path
155159
156160@property
157161def namespace (self ):
158162return dict (
159163__name__ = '__main__' ,
160- __file__ = self ,
164+ __file__ = self . path ,
161165__builtins__ = __builtins__ ,
162166 )
163167
164168@property
165169def code (self ):
166- with io .open (self )as fp :
167- return f"exec(compile({ fp .read ()!r} ,{ self !r} , 'exec'))"
170+ with io .open (self .path )as fp :
171+ ## MPY: f-string !r syntax not supported
172+ return f"exec(compile({ repr (fp .read ())} ,{ repr (self .path )} , 'exec'))"
168173
169174
170175class ModuleTarget (str ):
@@ -175,7 +180,7 @@ def check(self):
175180traceback .print_exc ()
176181sys .exit (1 )
177182
178- @functools .cached_property
183+ # @functools.cached_property
179184def _details (self ):
180185import runpy
181186return runpy ._get_module_details (self )
@@ -219,9 +224,9 @@ class Pdb(bdb.Bdb, cmd.Cmd):
219224
220225def __init__ (self ,completekey = 'tab' ,stdin = None ,stdout = None ,skip = None ,
221226nosigint = False ,readrc = True ):
222- bdb .Bdb .__init__ (self ,skip = skip )
227+ bdb .Bdb .__init__ (self ,skip )
223228cmd .Cmd .__init__ (self ,completekey ,stdin ,stdout )
224- sys .audit ("pdb.Pdb" )
229+ # sys.audit("pdb.Pdb")
225230if stdout :
226231self .use_rawinput = 0
227232self .prompt = '(Pdb) '
@@ -422,7 +427,7 @@ def interaction(self, frame, traceback):
422427if Pdb ._previous_sigint_handler :
423428try :
424429signal .signal (signal .SIGINT ,Pdb ._previous_sigint_handler )
425- except ValueError :# ValueError: signal only works in main thread
430+ except ( ValueError , NameError ) :# ValueError: signal only works in main thread
426431pass
427432else :
428433Pdb ._previous_sigint_handler = None
@@ -573,7 +578,9 @@ def _complete_expression(self, text, line, begidx, endidx):
573578# Collect globals and locals. It is usually not really sensible to also
574579# complete builtins, and they clutter the namespace quite heavily, so we
575580# leave them out.
576- ns = {** self .curframe .f_globals ,** self .curframe_locals }
581+ ns = {}
582+ ns .update (self .curframe .f_globals )
583+ ns .update (self .curframe_locals )
577584if '.' in text :
578585# Walk an attribute chain up to the last part, similar to what
579586# rlcompleter does. This will bail if any of the parts are not
@@ -1137,7 +1144,7 @@ def do_continue(self, arg):
11371144try :
11381145Pdb ._previous_sigint_handler = \
11391146signal .signal (signal .SIGINT ,self .sigint_handler )
1140- except ValueError :
1147+ except ( ValueError , NameError ) :
11411148# ValueError happens when do_continue() is invoked from
11421149# a non-main thread in which case we just continue without
11431150# SIGINT set. Would printing a message here (once) make
@@ -1475,7 +1482,9 @@ def do_interact(self, arg):
14751482 Start an interactive interpreter whose global namespace
14761483 contains all the (global and local) names found in the current scope.
14771484 """
1478- ns = {** self .curframe .f_globals ,** self .curframe_locals }
1485+ ns = {}
1486+ ns .update (self .curframe .f_globals )
1487+ ns .update (self .curframe_locals )
14791488code .interact ("*interactive*" ,local = ns )
14801489
14811490def do_alias (self ,arg ):
@@ -1640,29 +1649,34 @@ def _run(self, target: Union[ModuleTarget, ScriptTarget]):
16401649# __main__ will break). Clear __main__ and replace with
16411650# the target namespace.
16421651import __main__
1652+ try :
1653+ __main__ .__dict__
1654+ except AttributeError :
1655+ __main__ .__dict__ = dict ()
16431656__main__ .__dict__ .clear ()
16441657__main__ .__dict__ .update (target .namespace )
1658+
16451659
16461660self .run (target .code )
16471661
16481662
16491663# Collect all command help into docstring, if not run with -OO
1664+ ## MPY: NameError: name '__doc__' isn't defined
1665+ # if __doc__ is not None:
1666+ # # unfortunately we can't guess this order from the class definition
1667+ # _help_order = [
1668+ # 'help', 'where', 'down', 'up', 'break', 'tbreak', 'clear', 'disable',
1669+ # 'enable', 'ignore', 'condition', 'commands', 'step', 'next', 'until',
1670+ # 'jump', 'return', 'retval', 'run', 'continue', 'list', 'longlist',
1671+ # 'args', 'p', 'pp', 'whatis', 'source', 'display', 'undisplay',
1672+ # 'interact', 'alias', 'unalias', 'debug', 'quit',
1673+ # ]
16501674
1651- if __doc__ is not None :
1652- # unfortunately we can't guess this order from the class definition
1653- _help_order = [
1654- 'help' ,'where' ,'down' ,'up' ,'break' ,'tbreak' ,'clear' ,'disable' ,
1655- 'enable' ,'ignore' ,'condition' ,'commands' ,'step' ,'next' ,'until' ,
1656- 'jump' ,'return' ,'retval' ,'run' ,'continue' ,'list' ,'longlist' ,
1657- 'args' ,'p' ,'pp' ,'whatis' ,'source' ,'display' ,'undisplay' ,
1658- 'interact' ,'alias' ,'unalias' ,'debug' ,'quit' ,
1659- ]
1660-
1661- for _command in _help_order :
1662- __doc__ += getattr (Pdb ,'do_' + _command ).__doc__ .strip ()+ '\n \n '
1663- __doc__ += Pdb .help_exec .__doc__
1675+ # for _command in _help_order:
1676+ # __doc__ += getattr(Pdb, 'do_' + _command).__doc__.strip() + '\n\n'
1677+ # __doc__ += Pdb.help_exec.__doc__
16641678
1665- del _help_order ,_command
1679+ # del _help_order, _command
16661680
16671681
16681682# Simplified interface
@@ -1781,9 +1795,11 @@ def main():
17811795sys .exit (1 )
17821796except :
17831797traceback .print_exc ()
1798+ t = sys .exc_info ()[2 ]
1799+ if t is None :
1800+ break
17841801print ("Uncaught exception. Entering post mortem debugging" )
17851802print ("Running 'cont' or 'step' will restart the program" )
1786- t = sys .exc_info ()[2 ]
17871803pdb .interaction (None ,t )
17881804print ("Post mortem debugger finished. The " + target +
17891805" will be restarted" )