66
66
"""
67
67
# NOTE: the actual command documentation is collected from docstrings of the
68
68
# commands and is appended to __doc__ after the class has been defined.
69
-
69
+ import builtins as __builtins__
70
70
import os
71
71
import io
72
72
import re
73
73
import sys
74
74
import cmd
75
75
import bdb
76
- import dis
76
+ # import dis # MPY: dis not currently available
77
77
import code
78
78
import glob
79
79
import pprint
80
- import signal
81
- import inspect
80
+ # import signal # MPY: signal not currently available
81
+ # import inspect # MPY: inspect not currently available
82
82
import tokenize
83
- import functools
83
+ # import functools
84
84
import traceback
85
85
import linecache
86
86
87
- from typing import Union
87
+ try :
88
+ from typing import Union
89
+ except ImportError :
90
+ pass
88
91
89
92
90
93
class Restart (Exception ):
@@ -104,7 +107,9 @@ def find_function(funcname, filename):
104
107
with fp :
105
108
for lineno , line in enumerate (fp , start = 1 ):
106
109
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
108
113
return None
109
114
110
115
def getsourcelines (obj ):
@@ -117,11 +122,12 @@ def getsourcelines(obj):
117
122
return inspect .getblock (lines [lineno :]), lineno + 1
118
123
119
124
def 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
125
131
return 0
126
132
127
133
@@ -131,40 +137,39 @@ def __repr__(self):
131
137
return self
132
138
133
139
134
- class ScriptTarget ( str ) :
135
- def __new__ ( cls , val ):
140
+ class ScriptTarget :
141
+ def __init__ ( self , val ):
136
142
# Mutate self to be the "real path".
137
- res = super (). __new__ ( cls , os .path .realpath (val ) )
143
+ self . path = os .path .realpath (val )
138
144
139
145
# Store the original path for error reporting.
140
- res .orig = val
141
-
142
- return res
146
+ self .orig = val
143
147
144
148
def check (self ):
145
- if not os .path .exists (self ):
149
+ if not os .path .exists (self . path ):
146
150
print ('Error:' , self .orig , 'does not exist' )
147
151
sys .exit (1 )
148
152
149
153
# 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 )
151
155
152
156
@property
153
157
def filename (self ):
154
- return self
158
+ return self . path
155
159
156
160
@property
157
161
def namespace (self ):
158
162
return dict (
159
163
__name__ = '__main__' ,
160
- __file__ = self ,
164
+ __file__ = self . path ,
161
165
__builtins__ = __builtins__ ,
162
166
)
163
167
164
168
@property
165
169
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'))"
168
173
169
174
170
175
class ModuleTarget (str ):
@@ -175,7 +180,7 @@ def check(self):
175
180
traceback .print_exc ()
176
181
sys .exit (1 )
177
182
178
- @functools .cached_property
183
+ # @functools.cached_property
179
184
def _details (self ):
180
185
import runpy
181
186
return runpy ._get_module_details (self )
@@ -219,9 +224,9 @@ class Pdb(bdb.Bdb, cmd.Cmd):
219
224
220
225
def __init__ (self , completekey = 'tab' , stdin = None , stdout = None , skip = None ,
221
226
nosigint = False , readrc = True ):
222
- bdb .Bdb .__init__ (self , skip = skip )
227
+ bdb .Bdb .__init__ (self , skip )
223
228
cmd .Cmd .__init__ (self , completekey , stdin , stdout )
224
- sys .audit ("pdb.Pdb" )
229
+ # sys.audit("pdb.Pdb")
225
230
if stdout :
226
231
self .use_rawinput = 0
227
232
self .prompt = '(Pdb) '
@@ -422,7 +427,7 @@ def interaction(self, frame, traceback):
422
427
if Pdb ._previous_sigint_handler :
423
428
try :
424
429
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
426
431
pass
427
432
else :
428
433
Pdb ._previous_sigint_handler = None
@@ -573,7 +578,9 @@ def _complete_expression(self, text, line, begidx, endidx):
573
578
# Collect globals and locals. It is usually not really sensible to also
574
579
# complete builtins, and they clutter the namespace quite heavily, so we
575
580
# 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 )
577
584
if '.' in text :
578
585
# Walk an attribute chain up to the last part, similar to what
579
586
# rlcompleter does. This will bail if any of the parts are not
@@ -1137,7 +1144,7 @@ def do_continue(self, arg):
1137
1144
try :
1138
1145
Pdb ._previous_sigint_handler = \
1139
1146
signal .signal (signal .SIGINT , self .sigint_handler )
1140
- except ValueError :
1147
+ except ( ValueError , NameError ) :
1141
1148
# ValueError happens when do_continue() is invoked from
1142
1149
# a non-main thread in which case we just continue without
1143
1150
# SIGINT set. Would printing a message here (once) make
@@ -1475,7 +1482,9 @@ def do_interact(self, arg):
1475
1482
Start an interactive interpreter whose global namespace
1476
1483
contains all the (global and local) names found in the current scope.
1477
1484
"""
1478
- ns = {** self .curframe .f_globals , ** self .curframe_locals }
1485
+ ns = {}
1486
+ ns .update (self .curframe .f_globals )
1487
+ ns .update (self .curframe_locals )
1479
1488
code .interact ("*interactive*" , local = ns )
1480
1489
1481
1490
def do_alias (self , arg ):
@@ -1640,29 +1649,34 @@ def _run(self, target: Union[ModuleTarget, ScriptTarget]):
1640
1649
# __main__ will break). Clear __main__ and replace with
1641
1650
# the target namespace.
1642
1651
import __main__
1652
+ try :
1653
+ __main__ .__dict__
1654
+ except AttributeError :
1655
+ __main__ .__dict__ = dict ()
1643
1656
__main__ .__dict__ .clear ()
1644
1657
__main__ .__dict__ .update (target .namespace )
1658
+
1645
1659
1646
1660
self .run (target .code )
1647
1661
1648
1662
1649
1663
# 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
+ # ]
1650
1674
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__
1664
1678
1665
- del _help_order , _command
1679
+ # del _help_order, _command
1666
1680
1667
1681
1668
1682
# Simplified interface
@@ -1781,9 +1795,11 @@ def main():
1781
1795
sys .exit (1 )
1782
1796
except :
1783
1797
traceback .print_exc ()
1798
+ t = sys .exc_info ()[2 ]
1799
+ if t is None :
1800
+ break
1784
1801
print ("Uncaught exception. Entering post mortem debugging" )
1785
1802
print ("Running 'cont' or 'step' will restart the program" )
1786
- t = sys .exc_info ()[2 ]
1787
1803
pdb .interaction (None , t )
1788
1804
print ("Post mortem debugger finished. The " + target +
1789
1805
" will be restarted" )
0 commit comments