Skip to content

Commit e440b43

Browse files
authored
Merge pull request #6555 from bluetech/nodes-cache-split
Split Session._collection_node_cache to 3 mutually exclusive parts
2 parents 1586653 + f396733 commit e440b43

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

src/_pytest/main.py

+28-14
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from typing import Dict
99
from typing import FrozenSet
1010
from typing import List
11+
from typing import Sequence
1112
from typing import Tuple
1213

1314
import attr
@@ -21,13 +22,15 @@
2122
from _pytest.config import hookimpl
2223
from _pytest.config import UsageError
2324
from _pytest.fixtures import FixtureManager
24-
from _pytest.nodes import Node
2525
from _pytest.outcomes import exit
26+
from _pytest.reports import CollectReport
2627
from _pytest.runner import collect_one_node
2728
from _pytest.runner import SetupState
2829

2930

3031
if TYPE_CHECKING:
32+
from typing import Type
33+
3134
from _pytest.python import Package
3235

3336

@@ -407,7 +410,16 @@ def __init__(self, config: Config) -> None:
407410
self._initialpaths = frozenset() # type: FrozenSet[py.path.local]
408411

409412
# Keep track of any collected nodes in here, so we don't duplicate fixtures
410-
self._collection_node_cache = {} # type: Dict[str, List[Node]]
413+
self._collection_node_cache1 = (
414+
{}
415+
) # type: Dict[py.path.local, Sequence[nodes.Collector]]
416+
self._collection_node_cache2 = (
417+
{}
418+
) # type: Dict[Tuple[Type[nodes.Collector], py.path.local], nodes.Collector]
419+
self._collection_node_cache3 = (
420+
{}
421+
) # type: Dict[Tuple[Type[nodes.Collector], str], CollectReport]
422+
411423
# Dirnames of pkgs with dunder-init files.
412424
self._collection_pkg_roots = {} # type: Dict[py.path.local, Package]
413425

@@ -525,7 +537,9 @@ def collect(self):
525537
self._notfound.append((report_arg, sys.exc_info()[1]))
526538

527539
self.trace.root.indent -= 1
528-
self._collection_node_cache.clear()
540+
self._collection_node_cache1.clear()
541+
self._collection_node_cache2.clear()
542+
self._collection_node_cache3.clear()
529543
self._collection_pkg_roots.clear()
530544

531545
def _collect(self, argpath, names):
@@ -543,13 +557,13 @@ def _collect(self, argpath, names):
543557
if parent.isdir():
544558
pkginit = parent.join("__init__.py")
545559
if pkginit.isfile():
546-
if pkginit not in self._collection_node_cache:
560+
if pkginit not in self._collection_node_cache1:
547561
col = self._collectfile(pkginit, handle_dupes=False)
548562
if col:
549563
if isinstance(col[0], Package):
550564
self._collection_pkg_roots[parent] = col[0]
551565
# always store a list in the cache, matchnodes expects it
552-
self._collection_node_cache[col[0].fspath] = [col[0]]
566+
self._collection_node_cache1[col[0].fspath] = [col[0]]
553567

554568
# If it's a directory argument, recurse and look for any Subpackages.
555569
# Let the Package collector deal with subnodes, don't collect here.
@@ -576,21 +590,21 @@ def _collect(self, argpath, names):
576590

577591
for x in self._collectfile(path):
578592
key = (type(x), x.fspath)
579-
if key in self._collection_node_cache:
580-
yield self._collection_node_cache[key]
593+
if key in self._collection_node_cache2:
594+
yield self._collection_node_cache2[key]
581595
else:
582-
self._collection_node_cache[key] = x
596+
self._collection_node_cache2[key] = x
583597
yield x
584598
else:
585599
assert argpath.check(file=1)
586600

587-
if argpath in self._collection_node_cache:
588-
col = self._collection_node_cache[argpath]
601+
if argpath in self._collection_node_cache1:
602+
col = self._collection_node_cache1[argpath]
589603
else:
590604
collect_root = self._collection_pkg_roots.get(argpath.dirname, self)
591605
col = collect_root._collectfile(argpath, handle_dupes=False)
592606
if col:
593-
self._collection_node_cache[argpath] = col
607+
self._collection_node_cache1[argpath] = col
594608
m = self.matchnodes(col, names)
595609
# If __init__.py was the only file requested, then the matched node will be
596610
# the corresponding Package, and the first yielded item will be the __init__
@@ -703,11 +717,11 @@ def _matchnodes(self, matching, names):
703717
continue
704718
assert isinstance(node, nodes.Collector)
705719
key = (type(node), node.nodeid)
706-
if key in self._collection_node_cache:
707-
rep = self._collection_node_cache[key]
720+
if key in self._collection_node_cache3:
721+
rep = self._collection_node_cache3[key]
708722
else:
709723
rep = collect_one_node(node)
710-
self._collection_node_cache[key] = rep
724+
self._collection_node_cache3[key] = rep
711725
if rep.passed:
712726
has_matched = False
713727
for x in rep.result:

0 commit comments

Comments
 (0)