Cache exception raised in fixtures according to their scope

Without this if a session scoped fixture fails it's setup it will
be re-tried each time it is requested.  Especially in case of
skip or failure exceptions this can be undesirable, but caching
makes sense for all exceptions.
This commit is contained in:
Floris Bruynooghe
2014-04-15 22:22:41 -04:00
parent 65a145e2a7
commit c46e2cbbc7
3 changed files with 35 additions and 18 deletions

View File

@@ -1337,7 +1337,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
except FixtureLookupError:
if argname == "request":
class PseudoFixtureDef:
cached_result = (self, [0])
cached_result = (self, [0], None)
return PseudoFixtureDef
raise
result = self._getfuncargvalue(fixturedef)
@@ -1810,7 +1810,7 @@ class FixtureDef:
kwargs = {}
for argname in self.argnames:
fixturedef = request._get_active_fixturedef(argname)
result, arg_cache_key = fixturedef.cached_result
result, arg_cache_key, exc = fixturedef.cached_result
kwargs[argname] = result
if argname != "request":
fixturedef.addfinalizer(self.finish)
@@ -1818,13 +1818,12 @@ class FixtureDef:
my_cache_key = request.param_index
cached_result = getattr(self, "cached_result", None)
if cached_result is not None:
#print argname, "Found cached_result", cached_result
#print argname, "param_index", param_index
result, cache_key = cached_result
result, cache_key, err = cached_result
if my_cache_key == cache_key:
#print request.fixturename, "CACHE HIT", repr(my_cache_key)
return result
#print request.fixturename, "CACHE MISS"
if err is not None:
py.builtin._reraise(*err)
else:
return result
# we have a previous but differently parametrized fixture instance
# so we need to tear it down before creating a new one
self.finish()
@@ -1841,9 +1840,13 @@ class FixtureDef:
fixturefunc = getimfunc(self.func)
if fixturefunc != self.func:
fixturefunc = fixturefunc.__get__(request.instance)
result = call_fixture_func(fixturefunc, request, kwargs,
self.yieldctx)
self.cached_result = (result, my_cache_key)
try:
result = call_fixture_func(fixturefunc, request, kwargs,
self.yieldctx)
except Exception:
self.cached_result = (None, my_cache_key, sys.exc_info())
raise
self.cached_result = (result, my_cache_key, None)
return result
def __repr__(self):