aiodine icon indicating copy to clipboard operation
aiodine copied to clipboard

Async gen function scoped provider returnes async gen object instead of a yielded value

Open sergey0xff opened this issue 5 years ago • 9 comments

Expected behavior When a value is yielded from async generator function scoped provider it's expected to be the value that will be injected to consumers

Actual behavior Async gen object injected instead

To Reproduce

import asyncio

import aiodine

store = aiodine.Store()

DB_CONNECTION = 'db connection'


@store.provider(name='db', scope='function')
async def setup_db():
    print('acquiring connection')
    yield DB_CONNECTION
    print('releasing connection')


@store.consumer
async def worker(db):
     # expected a DB_CONNECTION, got async gen object instead
    assert db == DB_CONNECTION, f'expected {DB_CONNECTION!r}, got {db!r} instead'


async def main():
    store.freeze()

    async with store.session():
        await worker()


if __name__ == '__main__':
    asyncio.run(main())

Desktop (please complete the following information):

  • OS: Ubuntu 19.04
  • Python version: 3.7.4
  • aiodine version: 1.2.7

sergey0xff avatar Sep 10 '19 14:09 sergey0xff

Thanks for reporting @sergey-tikhonov! I’ll try to reproduce soon.

As a workaround, I believe you can do:

db = await db.__anext__()

florimondmanca avatar Sep 10 '19 15:09 florimondmanca

@sergey-tikhonov I was able to reproduce the issue, and pinned it to an issue in store.freeze(). Investigating now. :) It's been a while I've worked on aiodine and may need to refactor things out a bit for simplicity first.

florimondmanca avatar Sep 11 '19 16:09 florimondmanca

@sergey-tikhonov This is still a bug so I’ll reopen so that other users can see it and the proposed workaround. :)

florimondmanca avatar Sep 17 '19 10:09 florimondmanca

Due to recent changes in API design the task is no more relevant to me. Thanks for your response!

sergey0xff avatar Sep 17 '19 14:09 sergey0xff

Sure thing!

By the way, out of curiosity — are you using aiodine in a Bocadillo project or as a standalone library?

florimondmanca avatar Sep 17 '19 15:09 florimondmanca

I was going to use aiodine in my pet projects first and then consider using it in my production code. But with the new API it is not what I need.

sergey0xff avatar Sep 17 '19 21:09 sergey0xff

Ah, so I understand you won't be using aiodine because of the new API? Is there any particular API difference or missing feature that has made the new API not fit for your purpose? Keep in mind, nothing has been released yet — if there's some critical bit of functionality that was in the previous API but is not there anymore, we can still arrange things. Thanks!

florimondmanca avatar Sep 17 '19 22:09 florimondmanca

Well I need a simple dependency injection library that supports all asyncio features like coroutines, async generators and context managers. The killer feature is dependencies provided by names. The reason why I need name-based dependencies is multiple implementations/configurations of the same dependency. E.g. for production and testing I used different configurations and even implementations for db pools and some other resources like connections to other services.

sergey0xff avatar Sep 23 '19 15:09 sergey0xff

Thanks for pitching in about this. Actually I can see how the proposed new API does not allow overriding providers as easily — you’d have to add conditions inside the provider or dynamically define it depending on the conditions of interest. Definitely worth thinking about that. Thanks!

florimondmanca avatar Sep 24 '19 19:09 florimondmanca