22import os
33
44from zmq .utils import jsonapi
5- from traitlets import Instance
5+ #from traitlets import Instance
6+ #from traitlets.config.configurable import SingletonConfigurable
67
7- from asyncio import Queue
8+ from asyncio import ( Event , Queue )
89
910class DebugpyMessageQueue :
1011
@@ -26,7 +27,6 @@ def _reset_tcp_pos(self):
2627 self .message_pos = - 1
2728
2829 def _put_message (self , raw_msg ):
29- # TODO: forward to iopub if this is an event message
3030 msg = jsonapi .loads (raw_msg )
3131 if mes ['type' ] == 'event' :
3232 self .event_callback (msg )
@@ -72,23 +72,23 @@ async def get_message(self):
7272
7373class DebugpyClient :
7474
75- def __init__ (self , debugpy_socket , debugpy_stream ):
76- self .debugpy_socket = debugpy_socket
75+ def __init__ (self , debugpy_stream , event_callback ):
7776 self .debugpy_stream = debugpy_stream
77+ self .event_callback = event_callback
7878 self .message_queue = DebugpyMessageQueue (self ._forward_event )
7979 self .wait_for_attach = True
80- self .init_event = asyncio . Event ()
80+ self .init_event = Event ()
8181
8282 def _forward_event (self , msg ):
8383 if msg ['event' ] == 'initialized' :
8484 self .init_event .set ()
85- #TODO: send event to iopub
85+ self . event_callback ( msg )
8686
8787 def _send_request (self , msg ):
8888 content = jsonapi .dumps (msg )
8989 content_length = len (content )
9090 buf = DebugpyMessageQueue .HEADER + content_length + DebugpyMessageQueue .SEPARATOR + content_msg
91- self .debugpy_socket .send (buf ) # TODO: pass routing_id
91+ self .debugpy_stream .send (buf ) # TODO: pass routing_id
9292
9393 async def _wait_for_reponse (self ):
9494 # Since events are never pushed to the message_queue
@@ -115,6 +115,9 @@ async def _handle_init_sequence(self):
115115 attach_rep = await self ._wait_for_response ()
116116 return attach_rep
117117
118+ def receive_dap_frame (self , frame ):
119+ self .message_queue .put_tcp_frame (frame )
120+
118121 async def send_dap_request (self , msg ):
119122 self ._send_request (msg )
120123 if self .wait_for_attach and msg ['command' ] == 'attach' :
@@ -140,19 +143,20 @@ class Debugger:
140143 'debugInfo' , 'inspectVariables'
141144 ]
142145
143- log = Instance (logging .Logger , allow_none = True )
146+ # log = Instance(logging.Logger, allow_none=True)
144147
145- def __init__ (self ):
148+ def __init__ (self , debugpy_stream , event_callback , shell_socket , session ):
149+ self .debugpy_client = DebugpyClient (debugpy_stream , event_callback )
150+ self .shell_socket = shell_socket
151+ self .session = session
146152 self .is_started = False
147-
148- self .header = ''
149153
150154 self .started_debug_handlers = {}
151- for msg_type in started_debug_msg_types :
155+ for msg_type in Debugger . started_debug_msg_types :
152156 self .started_debug_handlers [msg_type ] = getattr (self , msg_type )
153157
154158 self .static_debug_handlers = {}
155- for msg_type in static_debug_msg_types :
159+ for msg_type in Debugger . static_debug_msg_types :
156160 self .static_debug_handlers [msg_type ] = getattr (self , msg_type )
157161
158162 self .breakpoint_list = {}
@@ -161,10 +165,27 @@ def __init__(self):
161165 async def _forward_message (self , msg ):
162166 return await self .debugpy_client .send_dap_request (msg )
163167
168+ @property
169+ def tcp_client (self ):
170+ return self .debugpy_client
171+
164172 def start (self ):
173+ endpoint = self .debugpy_client .debugpy_stream .socket .getsockopt (zmq .LAST_ENDPOINT )
174+ index = endpoit .rfind (':' )
175+ port = endpoint [index + 1 :]
176+ code = 'import debugpy;'
177+ code += 'debugpy.listen(("127.0.0.1",' + port + '))'
178+ content = {
179+ 'code' : code ,
180+ 'slient' : True
181+ }
182+ self .session .send (self .shell_socket , 'execute_request' , content ,
183+ None , (self .shell_socket .getsockopt (zmq .ROUTING_ID )))
184+
165185 return False
166186
167187 def stop (self ):
188+ # TODO
168189 pass
169190
170191 def dumpCell (self , message ):
@@ -198,7 +219,7 @@ def source(self, message):
198219
199220 async def stackTrace (self , message ):
200221 reply = await self ._forward_message (message )
201- reply ['body' ]['stackFrames' ] =
222+ reply ['body' ]['stackFrames' ] = \
202223 [frame for frame in reply ['body' ]['stackFrames' ] if frame ['source' ]['path' ] != '<string>' ]
203224 return reply
204225
@@ -215,7 +236,7 @@ async def attach(self, message):
215236 message ['arguments' ]['logToFile' ] = True
216237 return await self ._forward_message (message )
217238
218- def configurationDone (self , message ):
239+ async def configurationDone (self , message ):
219240 reply = {
220241 'seq' : message ['seq' ],
221242 'type' : 'response' ,
@@ -225,7 +246,13 @@ def configurationDone(self, message):
225246 }
226247 return reply ;
227248
228- def debugInfo (self , message ):
249+ async def debugInfo (self , message ):
250+ breakpoint_list = []
251+ for key , value in self .breakpoint_list .items ():
252+ breakpoint_list .append ({
253+ 'source' : key ,
254+ 'breakpoints' : value
255+ })
229256 reply = {
230257 'type' : 'response' ,
231258 'request_seq' : message ['seq' ],
@@ -235,18 +262,21 @@ def debugInfo(self, message):
235262 'isStarted' : self .is_started ,
236263 'hashMethod' : 'Murmur2' ,
237264 'hashSeed' : 0 ,
238- 'tmpFilePrefix' : 'coincoin ' ,
265+ 'tmpFilePrefix' : '/tmp/ipykernel_debugger ' ,
239266 'tmpFileSuffix' : '.py' ,
240- 'breakpoints' : self . breakpoint_list ,
267+ 'breakpoints' : breakpoint_list ,
241268 'stoppedThreads' : self .stopped_threads
242269 }
243270 }
271+ #self.log.info("returning reply %s", reply)
272+ print ("DEBUGGER: " , reply )
244273 return reply
245274
246275 def inspectVariables (self , message ):
276+ # TODO
247277 return {}
248278
249- async def process_request (self , header , message ):
279+ async def process_request (self , message ):
250280 reply = {}
251281
252282 if message ['command' ] == 'initialize' :
@@ -269,11 +299,10 @@ async def process_request(self, header, message):
269299 if handler is not None :
270300 reply = await handler (message )
271301 elif self .is_started :
272- self .header = header
273302 handler = self .started_debug_handlers .get (message ['command' ], None )
274303 if handler is not None :
275304 reply = await handler (message )
276- else
305+ else :
277306 reply = await self ._forward_message (message )
278307
279308 if message ['command' ] == 'disconnect' :
0 commit comments