Coverage for tests/test_overrides.py: 100%

195 statements  

« prev     ^ index     » next       coverage.py v7.17.3, created at 2026-11-13 05:19 +0000

1from collections.abc import AsyncGenerator, Generator 1abcdefghijklmnopqrst

2from typing import Annotated 1abcdefghijklmnopqrst

3from unittest.mock import Mock 1abcdefghijklmnopqrst

4 

5import pytest 1abcdefghijklmnopqrst

6 

7from fast_depends import Depends, Provider, inject 1abcdefghijklmnopqrst

8 

9 

10def test_not_override(provider: Provider) -> None: 1abcdefghijklmnopqrst

11 mock = Mock() 1abcdefghijklmnopqrst

12 

13 def base_dep(): 1abcdefghijklmnopqrst

14 mock.original() 1abcdefghijklmnopqrst

15 return 1 1abcdefghijklmnopqrst

16 

17 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

18 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst

19 assert d == 1 1abcdefghijklmnopqrst

20 

21 func() 1abcdefghijklmnopqrst

22 

23 mock.original.assert_called_once() 1abcdefghijklmnopqrst

24 

25 

26def test_sync_override(provider: Provider) -> None: 1abcdefghijklmnopqrst

27 mock = Mock() 1abcdefghijklmnopqrst

28 

29 def base_dep(): 1abcdefghijklmnopqrst

30 raise NotImplementedError 

31 

32 def override_dep(): 1abcdefghijklmnopqrst

33 mock.override() 1abcdefghijklmnopqrst

34 return 2 1abcdefghijklmnopqrst

35 

36 provider.override(base_dep, override_dep) 1abcdefghijklmnopqrst

37 

38 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

39 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst

40 assert d == 2 1abcdefghijklmnopqrst

41 

42 func() 1abcdefghijklmnopqrst

43 

44 provider.clear() 1abcdefghijklmnopqrst

45 

46 

47def test_override_by_key(provider: Provider) -> None: 1abcdefghijklmnopqrst

48 mock = Mock() 1abcdefghijklmnopqrst

49 

50 def base_dep(): 1abcdefghijklmnopqrst

51 raise NotImplementedError 

52 

53 def override_dep(): 1abcdefghijklmnopqrst

54 mock.override() 1abcdefghijklmnopqrst

55 return 2 1abcdefghijklmnopqrst

56 

57 provider[base_dep] = override_dep 1abcdefghijklmnopqrst

58 

59 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

60 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst

61 assert d == 2 1abcdefghijklmnopqrst

62 

63 func() 1abcdefghijklmnopqrst

64 

65 provider.clear() 1abcdefghijklmnopqrst

66 

67 

68def test_override_context(provider: Provider) -> None: 1abcdefghijklmnopqrst

69 def base_dep(): 1abcdefghijklmnopqrst

70 return 1 1abcdefghijklmnopqrst

71 

72 def override_dep(): 1abcdefghijklmnopqrst

73 return 2 1abcdefghijklmnopqrst

74 

75 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

76 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst

77 return d 1abcdefghijklmnopqrst

78 

79 with provider.scope(base_dep, override_dep): 1abcdefghijklmnopqrst

80 assert func() == 2 1abcdefghijklmnopqrst

81 

82 assert func() == 1 1abcdefghijklmnopqrst

83 

84 

85def test_override_context_exception(provider: Provider) -> None: 1abcdefghijklmnopqrst

86 def base_dep(): 1abcdefghijklmnopqrst

87 return 1 1abcdefghijklmnopqrst

88 

89 def override_dep(): 1abcdefghijklmnopqrst

90 return 2 1abcdefghijklmnopqrst

91 

92 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

93 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst

94 return d 1abcdefghijklmnopqrst

95 

96 with pytest.raises(ValueError): 1abcdefghijklmnopqrst

97 with provider.scope(base_dep, override_dep): 1abcdefghijklmnopqrst

98 assert func() == 2 1abcdefghijklmnopqrst

99 raise ValueError 1abcdefghijklmnopqrst

100 

101 assert func() == 1 1abcdefghijklmnopqrst

102 

103 

104def test_sync_by_async_override(provider: Provider) -> None: 1abcdefghijklmnopqrst

105 def base_dep(): 1abcdefghijklmnopqrst

106 raise NotImplementedError 

107 

108 async def override_dep(): # pragma: no cover 1abcdefghijklmnopqrst

109 return 2 

110 

111 provider.override(base_dep, override_dep) 1abcdefghijklmnopqrst

112 

113 with pytest.raises(AssertionError): 1abcdefghijklmnopqrst

114 

115 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

116 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst

117 pass 

118 

119 

120def test_sync_by_async_override_in_extra(provider: Provider) -> None: 1abcdefghijklmnopqrst

121 def base_dep(): 1abcdefghijklmnopqrst

122 raise NotImplementedError 

123 

124 async def override_dep(): # pragma: no cover 1abcdefghijklmnopqrst

125 return 2 

126 

127 provider.override(base_dep, override_dep) 1abcdefghijklmnopqrst

128 

129 with pytest.raises(AssertionError): 1abcdefghijklmnopqrst

130 

131 @inject( 1abcdefghijklmnopqrst

132 dependency_provider=provider, 

133 extra_dependencies=(Depends(base_dep),), 

134 ) 

135 def func(): 1abcdefghijklmnopqrst

136 pass 

137 

138 

139@pytest.mark.anyio 1abcdefghijklmnopqrst

140async def test_async_override(provider: Provider) -> None: 1abcdefghijklmnopqrst

141 mock = Mock() 1abcdefghijklmnopqrst

142 

143 async def base_dep(): 1abcdefghijklmnopqrst

144 raise NotImplementedError 

145 

146 async def override_dep(): 1abcdefghijklmnopqrst

147 mock.override() 1abcdefghijklmnopqrst

148 return 2 1abcdefghijklmnopqrst

149 

150 provider.override(base_dep, override_dep) 1abcdefghijklmnopqrst

151 

152 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

153 async def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst

154 assert d == 2 1abcdefghijklmnopqrst

155 

156 await func() 1abcdefghijklmnopqrst

157 mock.override.assert_called_once() 1abcdefghijklmnopqrst

158 

159 

160@pytest.mark.anyio 1abcdefghijklmnopqrst

161async def test_async_by_sync_override(provider: Provider) -> None: 1abcdefghijklmnopqrst

162 mock = Mock() 1abcdefghijklmnopqrst

163 

164 async def base_dep(): 1abcdefghijklmnopqrst

165 raise NotImplementedError 

166 

167 def override_dep(): 1abcdefghijklmnopqrst

168 mock.override() 1abcdefghijklmnopqrst

169 return 2 1abcdefghijklmnopqrst

170 

171 provider.override(base_dep, override_dep) 1abcdefghijklmnopqrst

172 

173 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

174 async def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst

175 assert d == 2 1abcdefghijklmnopqrst

176 

177 await func() 1abcdefghijklmnopqrst

178 mock.override.assert_called_once() 1abcdefghijklmnopqrst

179 

180 

181def test_deep_overrides(provider: Provider) -> None: 1abcdefghijklmnopqrst

182 mock = Mock() 1abcdefghijklmnopqrst

183 

184 def dep1(c=Depends(mock.dep2)): 1abcdefghijklmnopqrst

185 mock.dep1() 1abcdefghijklmnopqrst

186 

187 def dep3(c=Depends(mock.dep4)): 1abcdefghijklmnopqrst

188 mock.dep3() 1abcdefghijklmnopqrst

189 

190 @inject( 1abcdefghijklmnopqrst

191 dependency_provider=provider, 

192 extra_dependencies=(Depends(dep1),), 

193 ) 

194 def func() -> None: 1abcdefghijklmnopqrst

195 return 1abcdefghijklmnopqrst

196 

197 func() 1abcdefghijklmnopqrst

198 mock.dep1.assert_called_once() 1abcdefghijklmnopqrst

199 mock.dep2.assert_called_once() 1abcdefghijklmnopqrst

200 assert not mock.dep3.called 1abcdefghijklmnopqrst

201 assert not mock.dep4.called 1abcdefghijklmnopqrst

202 mock.reset_mock() 1abcdefghijklmnopqrst

203 

204 with provider.scope(dep1, dep3): 1abcdefghijklmnopqrst

205 func() 1abcdefghijklmnopqrst

206 assert not mock.dep1.called 1abcdefghijklmnopqrst

207 assert not mock.dep2.called 1abcdefghijklmnopqrst

208 mock.dep3.assert_called_once() 1abcdefghijklmnopqrst

209 mock.dep4.assert_called_once() 1abcdefghijklmnopqrst

210 

211 

212def test_deep_overrides_with_different_signatures(provider: Provider) -> None: 1abcdefghijklmnopqrst

213 mock = Mock() 1abcdefghijklmnopqrst

214 

215 def dep1(c=Depends(mock.dep2)): 1abcdefghijklmnopqrst

216 mock.dep1() 1abcdefghijklmnopqrst

217 

218 def dep3(): 1abcdefghijklmnopqrst

219 mock.dep3() 1abcdefghijklmnopqrst

220 

221 @inject( 1abcdefghijklmnopqrst

222 dependency_provider=provider, 

223 extra_dependencies=(Depends(dep1),), 

224 ) 

225 def func(): 1abcdefghijklmnopqrst

226 return 1abcdefghijklmnopqrst

227 

228 func() 1abcdefghijklmnopqrst

229 mock.dep1.assert_called_once() 1abcdefghijklmnopqrst

230 mock.dep2.assert_called_once() 1abcdefghijklmnopqrst

231 assert not mock.dep3.called 1abcdefghijklmnopqrst

232 mock.reset_mock() 1abcdefghijklmnopqrst

233 

234 with provider.scope(dep1, dep3): 1abcdefghijklmnopqrst

235 func() 1abcdefghijklmnopqrst

236 assert not mock.dep1.called 1abcdefghijklmnopqrst

237 assert not mock.dep2.called 1abcdefghijklmnopqrst

238 mock.dep3.assert_called_once() 1abcdefghijklmnopqrst

239 

240 

241def test_override_context_with_generator(provider: Provider) -> None: 1abcdefghijklmnopqrst

242 def base_dep() -> Generator[int, None, None]: 1abcdefghijklmnopqrst

243 raise NotImplementedError 

244 

245 def override_dep() -> Generator[int, None, None]: 1abcdefghijklmnopqrst

246 yield 2 1abcdefghijklmnopqrst

247 

248 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

249 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst

250 return d 1abcdefghijklmnopqrst

251 

252 with provider.scope(base_dep, override_dep): 1abcdefghijklmnopqrst

253 assert func() == 2 1abcdefghijklmnopqrst

254 

255 

256def test_override_context_with_undefined_generator(provider: Provider) -> None: 1abcdefghijklmnopqrst

257 def base_dep() -> Generator[int, None, None]: 1abcdefghijklmnopqrst

258 raise NotImplementedError 

259 

260 def override_dep() -> Generator[int, None, None]: 1abcdefghijklmnopqrst

261 yield 2 1abcdefghijklmnopqrst

262 

263 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

264 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst

265 return d 1abcdefghijklmnopqrst

266 

267 with provider.scope(base_dep, override_dep): 1abcdefghijklmnopqrst

268 assert func() == 2 1abcdefghijklmnopqrst

269 

270 

271@pytest.mark.anyio 1abcdefghijklmnopqrst

272async def test_async_override_context_with_generator(provider: Provider) -> None: 1abcdefghijklmnopqrst

273 async def base_dep() -> AsyncGenerator[int, None]: 1abcdefghijklmnopqrst

274 raise NotImplementedError 

275 

276 async def override_dep() -> AsyncGenerator[int, None]: 1abcdefghijklmnopqrst

277 yield 2 1abcdefghijklmnopqrst

278 

279 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

280 async def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst

281 return d 1abcdefghijklmnopqrst

282 

283 with provider.scope(base_dep, override_dep): 1abcdefghijklmnopqrst

284 assert await func() == 2 1abcdefghijklmnopqrst

285 

286 

287@pytest.mark.anyio 1abcdefghijklmnopqrst

288async def test_async_override_context_with_undefined_generator( 1abcdefghijklmnopqrst

289 provider: Provider, 

290) -> None: 

291 async def base_dep() -> AsyncGenerator[int, None]: 1abcdefghijklmnopqrst

292 raise NotImplementedError 

293 

294 async def override_dep() -> AsyncGenerator[int, None]: 1abcdefghijklmnopqrst

295 yield 2 1abcdefghijklmnopqrst

296 

297 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

298 async def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst

299 return d 1abcdefghijklmnopqrst

300 

301 with provider.scope(base_dep, override_dep): 1abcdefghijklmnopqrst

302 assert await func() == 2 1abcdefghijklmnopqrst

303 

304 

305def test_clear_overrides(provider: Provider) -> None: 1abcdefghijklmnopqrst

306 def base_dep() -> int: 1abcdefghijklmnopqrst

307 return 1 1abcdefghijklmnopqrst

308 

309 def override_dep() -> int: 1abcdefghijklmnopqrst

310 return 2 1abcdefghijklmnopqrst

311 

312 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst

313 def func(d: Annotated[int, Depends(base_dep)]) -> int: 1abcdefghijklmnopqrst

314 return d 1abcdefghijklmnopqrst

315 

316 provider.override(base_dep, override_dep) 1abcdefghijklmnopqrst

317 

318 assert len(provider.overrides) == 1 1abcdefghijklmnopqrst

319 assert len(provider.dependencies) == 1 1abcdefghijklmnopqrst

320 assert func() == 2 # override dependency called 1abcdefghijklmnopqrst

321 

322 provider.clear() 1abcdefghijklmnopqrst

323 

324 assert len(provider.overrides) == 0 1abcdefghijklmnopqrst

325 assert len(provider.dependencies) == 1 1abcdefghijklmnopqrst

326 assert func() == 1 # original dep called 1abcdefghijklmnopqrst