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):
104107 with fp :
105108 for lineno , line in enumerate (fp , start = 1 ):
106109 if 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
108113 return None
109114
110115def getsourcelines (obj ):
@@ -117,11 +122,12 @@ def getsourcelines(obj):
117122 return 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
125131 return 0
126132
127133
@@ -131,40 +137,39 @@ def __repr__(self):
131137 return 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
144148 def check (self ):
145- if not os .path .exists (self ):
149+ if not os .path .exists (self . path ):
146150 print ('Error:' , self .orig , 'does not exist' )
147151 sys .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
153157 def filename (self ):
154- return self
158+ return self . path
155159
156160 @property
157161 def namespace (self ):
158162 return dict (
159163 __name__ = '__main__' ,
160- __file__ = self ,
164+ __file__ = self . path ,
161165 __builtins__ = __builtins__ ,
162166 )
163167
164168 @property
165169 def 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):
175180 traceback .print_exc ()
176181 sys .exit (1 )
177182
178- @functools .cached_property
183+ # @functools.cached_property
179184 def _details (self ):
180185 import runpy
181186 return runpy ._get_module_details (self )
@@ -219,9 +224,9 @@ class Pdb(bdb.Bdb, cmd.Cmd):
219224
220225 def __init__ (self , completekey = 'tab' , stdin = None , stdout = None , skip = None ,
221226 nosigint = False , readrc = True ):
222- bdb .Bdb .__init__ (self , skip = skip )
227+ bdb .Bdb .__init__ (self , skip )
223228 cmd .Cmd .__init__ (self , completekey , stdin , stdout )
224- sys .audit ("pdb.Pdb" )
229+ # sys.audit("pdb.Pdb")
225230 if stdout :
226231 self .use_rawinput = 0
227232 self .prompt = '(Pdb) '
@@ -422,7 +427,7 @@ def interaction(self, frame, traceback):
422427 if Pdb ._previous_sigint_handler :
423428 try :
424429 signal .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
426431 pass
427432 else :
428433 Pdb ._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 )
577584 if '.' 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):
11371144 try :
11381145 Pdb ._previous_sigint_handler = \
11391146 signal .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 )
14791488 code .interact ("*interactive*" , local = ns )
14801489
14811490 def 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.
16421651 import __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
16461660 self .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():
17811795 sys .exit (1 )
17821796 except :
17831797 traceback .print_exc ()
1798+ t = sys .exc_info ()[2 ]
1799+ if t is None :
1800+ break
17841801 print ("Uncaught exception. Entering post mortem debugging" )
17851802 print ("Running 'cont' or 'step' will restart the program" )
1786- t = sys .exc_info ()[2 ]
17871803 pdb .interaction (None , t )
17881804 print ("Post mortem debugger finished. The " + target +
17891805 " will be restarted" )
0 commit comments