33
33
34
34
import pluggy
35
35
import pytest
36
+ from _pytest .fixtures import resolve_fixture_function
36
37
from _pytest .scope import Scope
37
38
from pytest import (
38
39
Config ,
60
61
from backports .asyncio .runner import Runner
61
62
62
63
_ScopeName = Literal ["session" , "package" , "module" , "class" , "function" ]
63
- _T = TypeVar ("_T" )
64
64
_R = TypeVar ("_R" , bound = Union [Awaitable [Any ], AsyncIterator [Any ]])
65
65
_P = ParamSpec ("_P" )
66
66
FixtureFunction = Callable [_P , _R ]
@@ -234,12 +234,15 @@ def pytest_report_header(config: Config) -> list[str]:
234
234
]
235
235
236
236
237
- def _fixture_synchronizer (fixturedef : FixtureDef , runner : Runner ) -> Callable :
237
+ def _fixture_synchronizer (
238
+ fixturedef : FixtureDef , runner : Runner , request : FixtureRequest
239
+ ) -> Callable :
238
240
"""Returns a synchronous function evaluating the specified fixture."""
241
+ fixture_function = resolve_fixture_function (fixturedef , request )
239
242
if inspect .isasyncgenfunction (fixturedef .func ):
240
- return _wrap_asyncgen_fixture (fixturedef . func , runner )
243
+ return _wrap_asyncgen_fixture (fixture_function , runner ) # type: ignore[arg-type]
241
244
elif inspect .iscoroutinefunction (fixturedef .func ):
242
- return _wrap_async_fixture (fixturedef . func , runner )
245
+ return _wrap_async_fixture (fixture_function , runner ) # type: ignore[arg-type]
243
246
else :
244
247
return fixturedef .func
245
248
@@ -256,22 +259,6 @@ def _add_kwargs(
256
259
return ret
257
260
258
261
259
- def _perhaps_rebind_fixture_func (func : _T , instance : Any | None ) -> _T :
260
- if instance is not None :
261
- # The fixture needs to be bound to the actual request.instance
262
- # so it is bound to the same object as the test method.
263
- unbound , cls = func , None
264
- try :
265
- unbound , cls = func .__func__ , type (func .__self__ ) # type: ignore
266
- except AttributeError :
267
- pass
268
- # Only if the fixture was bound before to an instance of
269
- # the same type.
270
- if cls is not None and isinstance (instance , cls ):
271
- func = unbound .__get__ (instance ) # type: ignore
272
- return func
273
-
274
-
275
262
AsyncGenFixtureParams = ParamSpec ("AsyncGenFixtureParams" )
276
263
AsyncGenFixtureYieldType = TypeVar ("AsyncGenFixtureYieldType" )
277
264
@@ -290,8 +277,9 @@ def _asyncgen_fixture_wrapper(
290
277
* args : AsyncGenFixtureParams .args ,
291
278
** kwargs : AsyncGenFixtureParams .kwargs ,
292
279
):
293
- func = _perhaps_rebind_fixture_func (fixture_function , request .instance )
294
- gen_obj = func (* args , ** _add_kwargs (func , kwargs , request ))
280
+ gen_obj = fixture_function (
281
+ * args , ** _add_kwargs (fixture_function , kwargs , request )
282
+ )
295
283
296
284
async def setup ():
297
285
res = await gen_obj .__anext__ () # type: ignore[union-attr]
@@ -342,10 +330,10 @@ def _async_fixture_wrapper(
342
330
* args : AsyncFixtureParams .args ,
343
331
** kwargs : AsyncFixtureParams .kwargs ,
344
332
):
345
- func = _perhaps_rebind_fixture_func (fixture_function , request .instance )
346
-
347
333
async def setup ():
348
- res = await func (* args , ** _add_kwargs (func , kwargs , request ))
334
+ res = await fixture_function (
335
+ * args , ** _add_kwargs (fixture_function , kwargs , request )
336
+ )
349
337
return res
350
338
351
339
context = contextvars .copy_context ()
@@ -746,7 +734,7 @@ def pytest_fixture_setup(fixturedef: FixtureDef, request) -> object | None:
746
734
)
747
735
runner_fixture_id = f"_{ loop_scope } _scoped_runner"
748
736
runner = request .getfixturevalue (runner_fixture_id )
749
- synchronizer = _fixture_synchronizer (fixturedef , runner )
737
+ synchronizer = _fixture_synchronizer (fixturedef , runner , request )
750
738
_make_asyncio_fixture_function (synchronizer , loop_scope )
751
739
with MonkeyPatch .context () as c :
752
740
if "request" not in fixturedef .argnames :
0 commit comments