Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python debuggers not stepping into a coroutine?

In the example below:

import asyncio
import ipdb

class EchoServerProtocol:
    def connection_made(self, transport):
        self.transport = transport

    def datagram_received(self, data, addr):
        message = data.decode()
        print('Received %r from %s' % (message, addr))
        print('Send %r to %s' % (message, addr))
        self.transport.sendto(data, addr)

loop = asyncio.get_event_loop()
ipdb.set_trace(context=21)
print("Starting UDP server")
# One protocol instance will be created to serve all client requests
listen = loop.create_datagram_endpoint(    EchoServerProtocol, local_addr=('127.0.0.1', 9999))
transport, protocol = loop.run_until_complete(listen)

try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

transport.close()
loop.close()

I'm trying to step into the

loop.create_datagram_endpoint( EchoServerProtocol, local_addr=('127.0.0.1', 9999))

to understand how it behaves internally. However when I try to step into the coroutine, the debugger just jumps over it as if n has been pressed instead of s.

> ../async_test.py(18)<module>()
     17 # One protocol instance will be created to serve all client requests
---> 18 listen = loop.create_datagram_endpoint(    EchoServerProtocol, local_addr=('127.0.0.1', 9999))
     19 transport, protocol = loop.run_until_complete(listen)

ipdb> s
> ../async_test.py(19)<module>()
     18 listen = loop.create_datagram_endpoint(    EchoServerProtocol, local_addr=('127.0.0.1', 9999))
---> 19 transport, protocol = loop.run_until_complete(listen)
     20 

ipdb> 

The behavior is experienced with PyCharm (2016 2.3 Community) IDE.

I would expect to end here and be able to step additionally through the code.

like image 491
TheMeaningfulEngineer Avatar asked Sep 14 '16 16:09

TheMeaningfulEngineer


1 Answers

It works if you call await or yield from for your coroutine like

listen = await loop.create_datagram_endpoint(EchoServerProtocol, 
                                             local_addr=('127.0.0.1', 9999))

In your example listen is not a result of coroutine execution but coroutine instance itself. Actual execution is performed by next line: loop.run_until_complete().

like image 70
Andrew Svetlov Avatar answered Nov 05 '22 19:11

Andrew Svetlov