Q:

In Python, yielding from lock in DatagramProtocol.datagram_received makes the function never called

I want to synchronize data from between coroutines and I end up with a method not being called whenever there is "yield" inside it. 
To be more precise, when I implement a DatagramProtocol class with the method datagram_received as per the doc (inspired from this), everything works fine, I receive the data.  As soon as I add a "yield" inside the method datagram_received, the method is never called anymore.  Here is an example:
loop = asyncio.get_event_loop()
lock = asyncio. Lock(loop=loop)

class MyProtocol(asyncio. DatagramProtocol):
    def datagram_received(self, data, addr):
        global my_data, lock
        print("here")
        # uncomment the following lines and datagram_received is 
        # not called at all (never see the "here" on the console)
        #yield from lock
        #try:
        #    my_data = float(data.decode())
        #finally:
        #    lock.release()

loop.run_until_complete(loop.create_datagram_endpoint(MyProtocol, sock=create_socket(10000)))

loop.run_forever()

How can a method suddenly get not being called depending on the content of the method? 
What am I missing?  How the synchronization should be done? 

A:

What am I missing? 
Documentation that inspired you also states:

Coroutines can be scheduled in a protocol method using ensure_future(), but there is no guarantee made about the execution order.  Protocols are not aware of coroutines created in protocol methods and so will not wait for them. 
To have a reliable execution order, use stream objects in a coroutine with yield from.  For example, the StreamWriter.drain() coroutine can be used to wait until the write buffer is flushed. 

You cannot yield from/await inside datagram_received, you may:
class MyProtocol(asyncio. DatagramProtocol):
    def datagram_received(self, data, addr):
        global my_data, lock
        print("here")
        loop.ensure_future(some_function())
        
    @asyncio.coroutine
    def some_function(self):
        yield from lock
        try:
            my_data = float(data.decode())
        finally:
            lock.release()

How can a method suddenly get not being called depending on the content of the method? 
Use of yield or yield from in a function, makes it a generator.  So datagram_received returns generator object.  To actually execute the code (till yield) you should use next, asyncio does it with (generator-based) coroutines (but again datagram_received isn`t one)
>>> def test():
...     print('test')
...     yield from 'A'
... 
>>> test()
<generator object test at 0x7f4165d42fc0>
>>> next(test())
test
'A'

More about generators: https://jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/

