I encountered some problems while trying to make a synchronous function that calls asynchronous functions.(python 3.6.9, cocotb 1.4.0)
As shown in the following example code. The read_cb function will call read function(in FakeDriver class).
After running, I get the error
yield self._fake_lock() RuntimeError: Task got bad yield: <cocotb.decorators.RunningCoroutine object at 0x7f7fecdbfe10> What I want is
init FakerDriver locking... locking done read... addr: 0x01 unlocking... unlocking done read done import cocotb import asyncio from cocotb.decorators import coroutine from cocotb.triggers import Event class FakeDriver(): def __init__(self): print("init FakeDriver") self.busy_event = Event("driver_busy") self.busy = False @coroutine def read(self, addr): print("read...") yield self._fake_lock() print("addr: ", addr) self._fake_unlock() print("read done") @coroutine def _fake_lock(self): print("locking...") if self.busy: yield self.busy_event.wait() self.busy_event.clear() self.busy = True print("locking done") def _fake_unlock(self): print("unlocking...") self.busy = False self.busy_event.set() print("unlocking done") def read_cb(): dri = FakeDriver() loop = asyncio.get_event_loop() task = loop.create_task(dri.read("0x01")) ret = loop.run_until_complete(task) loop.close() if __name__ == "__main__": read_cb()
async defsyntax instead. This will probably true for the cocotb library too. See docs.python.org/3.8/library/asyncio-task.html#asyncio.coroutine If you are trying to use an old version of python, then you should probably be doingyield fromrather thanyield.async defandawait, and python 3.3 doesn't have asyncio.yield from, there will be a error:yield from self._fake_lock() TypeError: iter() returned non-iterator of type 'RunningCoroutine'yield fromfor both coroutines? Also, did you try using stuff likeasync def read(self, addr)(without @coroutine) andawait self._fake_lock()? Again, you'll need to do that for both functions.