fixtures: fix quadratic behavior in the number of autouse fixtures

It turns out all autouse fixtures are kept in a global list, and thinned
out for a particular node using a linear scan of the entire list each
time.

Change the list to a dict, and only take the nodes we need.
This commit is contained in:
Ran Benita 2020-10-24 00:22:13 +03:00
parent d6becfa177
commit 470ea504e2
2 changed files with 9 additions and 7 deletions

View File

@ -0,0 +1 @@
Fixed quadratic behavior and improved performance of collection of items using autouse fixtures and xunit fixtures.

View File

@ -1412,9 +1412,10 @@ class FixtureManager:
self.config: Config = session.config
self._arg2fixturedefs: Dict[str, List[FixtureDef[Any]]] = {}
self._holderobjseen: Set[object] = set()
self._nodeid_and_autousenames: List[Tuple[str, List[str]]] = [
("", self.config.getini("usefixtures"))
]
# A mapping from a nodeid to a list of autouse fixtures it defines.
self._nodeid_autousenames: Dict[str, List[str]] = {
"": self.config.getini("usefixtures"),
}
session.config.pluginmanager.register(self, "funcmanage")
def _get_direct_parametrize_args(self, node: nodes.Node) -> List[str]:
@ -1478,9 +1479,9 @@ class FixtureManager:
def _getautousenames(self, nodeid: str) -> Iterator[str]:
"""Return the names of autouse fixtures applicable to nodeid."""
parentnodeids = set(nodes.iterparentnodeids(nodeid))
for baseid, basenames in self._nodeid_and_autousenames:
if baseid in parentnodeids:
for parentnodeid in nodes.iterparentnodeids(nodeid):
basenames = self._nodeid_autousenames.get(parentnodeid)
if basenames:
yield from basenames
def getfixtureclosure(
@ -1642,7 +1643,7 @@ class FixtureManager:
autousenames.append(name)
if autousenames:
self._nodeid_and_autousenames.append((nodeid or "", autousenames))
self._nodeid_autousenames.setdefault(nodeid or "", []).extend(autousenames)
def getfixturedefs(
self, argname: str, nodeid: str