@@ -534,6 +534,12 @@ def getfixturevalue(self, argname: str) -> Any:
534
534
f'The fixture value for "{ argname } " is not available. '
535
535
"This can happen when the fixture has already been torn down."
536
536
)
537
+
538
+ if (isinstance (fixturedef , FixtureDef )
539
+ and fixturedef is not None
540
+ and fixturedef .use_cache is False ):
541
+ self ._fixture_defs .pop (argname )
542
+
537
543
return fixturedef .cached_result [0 ]
538
544
539
545
def _iter_chain (self ) -> Iterator [SubRequest ]:
@@ -614,9 +620,15 @@ def _get_active_fixturedef(
614
620
)
615
621
616
622
# Make sure the fixture value is cached, running it if it isn't
617
- fixturedef .execute (request = subrequest )
623
+ try :
624
+ fixturedef .execute (request = subrequest )
625
+ self ._fixture_defs [argname ] = fixturedef
626
+ finally :
627
+ for arg_name in fixturedef .argnames :
628
+ arg_fixture = self ._fixture_defs .get (arg_name )
629
+ if arg_fixture is not None and arg_fixture .use_cache is not True :
630
+ self ._fixture_defs .pop (arg_name )
618
631
619
- self ._fixture_defs [argname ] = fixturedef
620
632
return fixturedef
621
633
622
634
def _check_fixturedef_without_param (self , fixturedef : FixtureDef [object ]) -> None :
@@ -957,6 +969,7 @@ def __init__(
957
969
scope : Scope | _ScopeName | Callable [[str , Config ], _ScopeName ] | None ,
958
970
params : Sequence [object ] | None ,
959
971
ids : tuple [object | None , ...] | Callable [[Any ], object | None ] | None = None ,
972
+ use_cache : bool = True ,
960
973
* ,
961
974
_ispytest : bool = False ,
962
975
) -> None :
@@ -1004,6 +1017,7 @@ def __init__(
1004
1017
# Can change if the fixture is executed with different parameters.
1005
1018
self .cached_result : _FixtureCachedResult [FixtureValue ] | None = None
1006
1019
self ._finalizers : Final [list [Callable [[], object ]]] = []
1020
+ self .use_cache = use_cache
1007
1021
1008
1022
@property
1009
1023
def scope (self ) -> _ScopeName :
@@ -1054,7 +1068,7 @@ def execute(self, request: SubRequest) -> FixtureValue:
1054
1068
requested_fixtures_that_should_finalize_us .append (fixturedef )
1055
1069
1056
1070
# Check for (and return) cached value/exception.
1057
- if self .cached_result is not None :
1071
+ if self .cached_result is not None and self . use_cache :
1058
1072
request_cache_key = self .cache_key (request )
1059
1073
cache_key = self .cached_result [1 ]
1060
1074
try :
@@ -1183,6 +1197,7 @@ class FixtureFunctionMarker:
1183
1197
autouse : bool = False
1184
1198
ids : tuple [object | None , ...] | Callable [[Any ], object | None ] | None = None
1185
1199
name : str | None = None
1200
+ cache_result : bool = True
1186
1201
1187
1202
_ispytest : dataclasses .InitVar [bool ] = False
1188
1203
@@ -1225,6 +1240,7 @@ def fixture(
1225
1240
autouse : bool = ...,
1226
1241
ids : Sequence [object | None ] | Callable [[Any ], object | None ] | None = ...,
1227
1242
name : str | None = ...,
1243
+ cache_result : bool = True ,
1228
1244
) -> FixtureFunction : ...
1229
1245
1230
1246
@@ -1237,6 +1253,7 @@ def fixture(
1237
1253
autouse : bool = ...,
1238
1254
ids : Sequence [object | None ] | Callable [[Any ], object | None ] | None = ...,
1239
1255
name : str | None = None ,
1256
+ cache_result : bool = True ,
1240
1257
) -> FixtureFunctionMarker : ...
1241
1258
1242
1259
@@ -1248,6 +1265,7 @@ def fixture(
1248
1265
autouse : bool = False ,
1249
1266
ids : Sequence [object | None ] | Callable [[Any ], object | None ] | None = None ,
1250
1267
name : str | None = None ,
1268
+ cache_result : bool = True ,
1251
1269
) -> FixtureFunctionMarker | FixtureFunction :
1252
1270
"""Decorator to mark a fixture factory function.
1253
1271
@@ -1298,6 +1316,11 @@ def fixture(
1298
1316
function arg that requests the fixture; one way to resolve this is to
1299
1317
name the decorated function ``fixture_<fixturename>`` and then use
1300
1318
``@pytest.fixture(name='<fixturename>')``.
1319
+
1320
+ :param cache_result:
1321
+ If True (the default), the fixture result is cached and the fixture
1322
+ only runs once per scope.
1323
+ If False, the fixture will run each time it is requested
1301
1324
"""
1302
1325
fixture_marker = FixtureFunctionMarker (
1303
1326
scope = scope ,
@@ -1306,6 +1329,7 @@ def fixture(
1306
1329
ids = None if ids is None else ids if callable (ids ) else tuple (ids ),
1307
1330
name = name ,
1308
1331
_ispytest = True ,
1332
+ cache_result = cache_result
1309
1333
)
1310
1334
1311
1335
# Direct decoration.
@@ -1636,6 +1660,7 @@ def _register_fixture(
1636
1660
params : Sequence [object ] | None = None ,
1637
1661
ids : tuple [object | None , ...] | Callable [[Any ], object | None ] | None = None ,
1638
1662
autouse : bool = False ,
1663
+ cache_result : bool = True ,
1639
1664
) -> None :
1640
1665
"""Register a fixture
1641
1666
@@ -1666,6 +1691,7 @@ def _register_fixture(
1666
1691
params = params ,
1667
1692
ids = ids ,
1668
1693
_ispytest = True ,
1694
+ use_cache = cache_result ,
1669
1695
)
1670
1696
1671
1697
faclist = self ._arg2fixturedefs .setdefault (name , [])
@@ -1762,6 +1788,7 @@ def parsefactories(
1762
1788
params = marker .params ,
1763
1789
ids = marker .ids ,
1764
1790
autouse = marker .autouse ,
1791
+ cache_result = marker .cache_result
1765
1792
)
1766
1793
1767
1794
def getfixturedefs (
0 commit comments