|
106 | 106 | ) |
107 | 107 |
|
108 | 108 |
|
109 | | -@dataclasses.dataclass(frozen=True) |
110 | | -class PseudoFixtureDef(Generic[FixtureValue]): |
111 | | - cached_result: _FixtureCachedResult[FixtureValue] |
112 | | - _scope: Scope |
113 | | - |
114 | | - |
115 | 109 | def pytest_sessionstart(session: Session) -> None: |
116 | 110 | session._fixturemanager = FixtureManager(session) |
117 | 111 |
|
@@ -420,7 +414,7 @@ def scope(self) -> _ScopeName: |
420 | 414 | @abc.abstractmethod |
421 | 415 | def _check_scope( |
422 | 416 | self, |
423 | | - requested_fixturedef: FixtureDef[object]|PseudoFixtureDef[object], |
| 417 | + requested_fixturedef: FixtureDef[object], |
424 | 418 | requested_scope: Scope, |
425 | 419 | ) -> None: |
426 | 420 | raise NotImplementedError() |
@@ -559,12 +553,9 @@ def _iter_chain(self) -> Iterator[SubRequest]: |
559 | 553 | yield current |
560 | 554 | current = current._parent_request |
561 | 555 |
|
562 | | - def _get_active_fixturedef( |
563 | | - self, argname: str |
564 | | - ) -> FixtureDef[object] | PseudoFixtureDef[object]: |
| 556 | + def _get_active_fixturedef(self, argname: str) -> FixtureDef[object]: |
565 | 557 | if argname == "request": |
566 | | - cached_result = (self, [0], None) |
567 | | - return PseudoFixtureDef(cached_result, Scope.Function) |
| 558 | + return RequestFixtureDef(self) |
568 | 559 |
|
569 | 560 | # If we already finished computing a fixture by this name in this item, |
570 | 561 | # return it. |
@@ -696,7 +687,7 @@ def _scope(self) -> Scope: |
696 | 687 |
|
697 | 688 | def _check_scope( |
698 | 689 | self, |
699 | | - requested_fixturedef: FixtureDef[object]|PseudoFixtureDef[object], |
| 690 | + requested_fixturedef: FixtureDef[object], |
700 | 691 | requested_scope: Scope, |
701 | 692 | ) -> None: |
702 | 693 | # TopRequest always has function scope so always valid. |
@@ -775,11 +766,9 @@ def node(self): |
775 | 766 |
|
776 | 767 | def _check_scope( |
777 | 768 | self, |
778 | | - requested_fixturedef: FixtureDef[object]|PseudoFixtureDef[object], |
| 769 | + requested_fixturedef: FixtureDef[object], |
779 | 770 | requested_scope: Scope, |
780 | 771 | ) -> None: |
781 | | - if isinstance(requested_fixturedef, PseudoFixtureDef): |
782 | | - return |
783 | 772 | if self._scope > requested_scope: |
784 | 773 | # Try to report something helpful. |
785 | 774 | argname = requested_fixturedef.argname |
@@ -968,7 +957,6 @@ def _eval_scope_callable( |
968 | 957 | return result |
969 | 958 |
|
970 | 959 |
|
971 | | -@final |
972 | 960 | class FixtureDef(Generic[FixtureValue]): |
973 | 961 | """A container for a fixture definition. |
974 | 962 | |
@@ -1083,8 +1071,7 @@ def execute(self, request: SubRequest) -> FixtureValue: |
1083 | 1071 | # down first. This is generally handled by SetupState, but still currently |
1084 | 1072 | # needed when this fixture is not parametrized but depends on a parametrized |
1085 | 1073 | # fixture. |
1086 | | - if not isinstance(fixturedef, PseudoFixtureDef): |
1087 | | - requested_fixtures_that_should_finalize_us.append(fixturedef) |
| 1074 | + requested_fixtures_that_should_finalize_us.append(fixturedef) |
1088 | 1075 |
|
1089 | 1076 | # Check for (and return) cached value/exception. |
1090 | 1077 | if self.cached_result is not None: |
@@ -1136,6 +1123,28 @@ def __repr__(self) -> str: |
1136 | 1123 | return f"<FixtureDef argname={self.argname!r} scope={self.scope!r} baseid={self.baseid!r}>" |
1137 | 1124 |
|
1138 | 1125 |
|
| 1126 | +class RequestFixtureDef(FixtureDef[FixtureRequest]): |
| 1127 | + """A custom FixtureDef for the special "request" fixture. |
| 1128 | + |
| 1129 | + A new one is generated on-demand whenever "request" is requested. |
| 1130 | + """ |
| 1131 | + |
| 1132 | + def __init__(self, request: FixtureRequest) -> None: |
| 1133 | + super().__init__( |
| 1134 | + config=request.config, |
| 1135 | + baseid=None, |
| 1136 | + argname="request", |
| 1137 | + func=lambda: request, |
| 1138 | + scope=Scope.Function, |
| 1139 | + params=None, |
| 1140 | + _ispytest=True, |
| 1141 | + ) |
| 1142 | + self.cached_result = (request, [0], None) |
| 1143 | + |
| 1144 | + def addfinalizer(self, finalizer: Callable[[], object]) -> None: |
| 1145 | + pass |
| 1146 | + |
| 1147 | + |
1139 | 1148 | def resolve_fixture_function( |
1140 | 1149 | fixturedef: FixtureDef[FixtureValue], request: FixtureRequest |
1141 | 1150 | ) -> _FixtureFunc[FixtureValue]: |
|
0 commit comments