@@ -1160,6 +1160,48 @@ def fun() -> Iterator[int]:
11601160 assert calls == 1
11611161
11621162
1163+ def test_synthetic_lock_lost_runs_uncached_with_original_args (
1164+ tmp_path : Path ,
1165+ restore_settings ,
1166+ ) -> None :
1167+ """
1168+ If synthetic cachew loses the write lock, it should run uncached with the original arguments.
1169+ """
1170+ settings .THROW_ON_ERROR = False
1171+
1172+ cache_path = tmp_path / 'cache'
1173+ recomputed : list [str ] = []
1174+ consumed_cached = False
1175+
1176+ @cachew (cache_path , force_file = True , synthetic_key = 'keys' )
1177+ def fun (keys : Sequence [str ], * , cachew_cached : Iterable [str ] = ()) -> Iterator [str ]:
1178+ nonlocal consumed_cached
1179+
1180+ for item in cachew_cached :
1181+ consumed_cached = True
1182+ yield item
1183+
1184+ for key in keys :
1185+ recomputed .append (key )
1186+ yield key
1187+
1188+ assert list (fun (keys = ['a' ])) == ['a' ]
1189+ assert recomputed == ['a' ]
1190+
1191+ recomputed .clear ()
1192+ backend_cls = {
1193+ 'file' : FileBackend ,
1194+ 'sqlite' : SqliteBackend ,
1195+ }[settings .DEFAULT_BACKEND ]
1196+
1197+ with backend_cls (cache_path = cache_path , logger = logger ) as backend :
1198+ assert backend .get_exclusive_write ()
1199+ assert list (fun (keys = ['a' , 'b' ])) == ['a' , 'b' ]
1200+
1201+ assert recomputed == ['a' , 'b' ]
1202+ assert consumed_cached is False
1203+
1204+
11631205@pytest .mark .parametrize ('throw' , [False , True ])
11641206def test_bad_annotation (* , tmp_path : Path , throw : bool ) -> None :
11651207 """
0 commit comments