1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
--- contrib/python/pytest/py3/_pytest/fixtures.py (54693a02d00937a28e5176cac9fa36e9ea9a9a4b)
+++ contrib/python/pytest/py3/_pytest/fixtures.py (d19830d8860a577c5e2a88ca771220910c8ad740)
@@ -1538,6 +1538,7 @@ class FixtureManager:
# (discovering matching fixtures for a given name/node is expensive).
parentid = parentnode.nodeid
+ parentnodesids = set(nodes.iterparentnodeids(parentid))
fixturenames_closure = list(initialnames)
arg2fixturedefs: Dict[str, Sequence[FixtureDef[Any]]] = {}
@@ -1549,7 +1550,7 @@ class FixtureManager:
continue
if argname in arg2fixturedefs:
continue
- fixturedefs = self.getfixturedefs(argname, parentid)
+ fixturedefs = self.getfixturedefs(argname, parentid, _parentnodeids=parentnodesids)
if fixturedefs:
arg2fixturedefs[argname] = fixturedefs
for arg in fixturedefs[-1].argnames:
@@ -1574,6 +1575,12 @@ class FixtureManager:
args, _ = ParameterSet._parse_parametrize_args(*mark.args, **mark.kwargs)
return args
+ parametrized_argnames = set(
+ argname
+ for mark in metafunc.definition.iter_markers("parametrize")
+ for argname in get_parametrize_mark_argnames(mark)
+ )
+
for argname in metafunc.fixturenames:
# Get the FixtureDefs for the argname.
fixture_defs = metafunc._arg2fixturedefs.get(argname)
@@ -1584,10 +1591,7 @@ class FixtureManager:
# If the test itself parametrizes using this argname, give it
# precedence.
- if any(
- argname in get_parametrize_mark_argnames(mark)
- for mark in metafunc.definition.iter_markers("parametrize")
- ):
+ if argname in parametrized_argnames:
continue
# In the common case we only look at the fixture def with the
@@ -1721,7 +1725,7 @@ class FixtureManager:
self._nodeid_autousenames.setdefault(nodeid or "", []).extend(autousenames)
def getfixturedefs(
- self, argname: str, nodeid: str
+ self, argname: str, nodeid: str, /, _parentnodeids: Optional[set[str]] = None
) -> Optional[Sequence[FixtureDef[Any]]]:
"""Get FixtureDefs for a fixture name which are applicable
to a given node.
@@ -1738,12 +1742,14 @@ class FixtureManager:
fixturedefs = self._arg2fixturedefs[argname]
except KeyError:
return None
- return tuple(self._matchfactories(fixturedefs, nodeid))
+
+ if not _parentnodeids:
+ _parentnodeids = set(nodes.iterparentnodeids(nodeid))
+ return tuple(self._matchfactories(fixturedefs, _parentnodeids))
def _matchfactories(
- self, fixturedefs: Iterable[FixtureDef[Any]], nodeid: str
+ self, fixturedefs: Iterable[FixtureDef[Any]], _parentnodeids: set[str]
) -> Iterator[FixtureDef[Any]]:
- parentnodeids = set(nodes.iterparentnodeids(nodeid))
for fixturedef in fixturedefs:
- if fixturedef.baseid in parentnodeids:
+ if fixturedef.baseid in _parentnodeids:
yield fixturedef
--- contrib/python/pytest/py3/_pytest/scope.py (54693a02d00937a28e5176cac9fa36e9ea9a9a4b)
+++ contrib/python/pytest/py3/_pytest/scope.py (d19830d8860a577c5e2a88ca771220910c8ad740)
@@ -53,8 +53,32 @@ class Scope(Enum):
return _ALL_SCOPES[index + 1]
def __lt__(self, other: "Scope") -> bool:
- self_index = _SCOPE_INDICES[self]
- other_index = _SCOPE_INDICES[other]
+ if self == other:
+ return False
+ self_index = 0
+ if self is Scope.Function:
+ self_index = 0
+ elif self is Scope.Class:
+ self_index = 1
+ elif self is Scope.Module:
+ self_index = 2
+ elif self is Scope.Package:
+ self_index = 3
+ elif self is Scope.Session:
+ self_index = 4
+
+ other_index = 0
+ if other is Scope.Function:
+ other_index = 0
+ elif other is Scope.Class:
+ other_index = 1
+ elif other is Scope.Module:
+ other_index = 2
+ elif other is Scope.Package:
+ other_index = 3
+ elif other is Scope.Session:
+ other_index = 4
+
return self_index < other_index
@classmethod
|