def _resolve_single_arg(self, arg: Callable, cache: FixtureCache) -> Union[Any, Fixture]: """ Get the fixture return value If the fixture has been cached, return the value from the cache. Otherwise, call the fixture function and return the value. """ if not hasattr(arg, "ward_meta"): return arg fixture = Fixture(arg) if cache.contains(fixture, fixture.scope, self.test.scope_key_from(fixture.scope)): return cache.get(fixture.key, fixture.scope, self.test.scope_key_from(fixture.scope)) children_defaults = self.get_default_args(func=arg) children_resolved = {} for name, child_fixture in children_defaults.items(): child_resolved = self._resolve_single_arg(child_fixture, cache) children_resolved[name] = child_resolved try: args_to_inject = self._unpack_resolved(children_resolved) if fixture.is_generator_fixture: fixture.gen = arg(**args_to_inject) fixture.resolved_val = next( fixture.gen) # type: ignore[arg-type] elif fixture.is_async_generator_fixture: fixture.gen = arg(**args_to_inject) awaitable = fixture.gen.__anext__() # type: ignore[union-attr] fixture.resolved_val = asyncio.get_event_loop( ).run_until_complete(awaitable) elif fixture.is_coroutine_fixture: fixture.resolved_val = asyncio.get_event_loop( ).run_until_complete(arg(**args_to_inject)) else: fixture.resolved_val = arg(**args_to_inject) except (Exception, SystemExit) as e: raise FixtureError( f"Unable to resolve fixture '{fixture.name}'") from e scope_key = self.test.scope_key_from(fixture.scope) cache.cache_fixture(fixture, scope_key) return fixture
def _(f=exception_raising_fixture): cache = FixtureCache() cache.cache_fixture(f, "test_id") assert cache.get(f.key, Scope.Test, "test_id") == f