77import sys
88from typing import Dict
99from typing import FrozenSet
10- from typing import List
10+ from typing import Sequence
11+ from typing import Tuple
1112
1213import attr
1314import py
1920from _pytest .config import hookimpl
2021from _pytest .config import UsageError
2122from _pytest .fixtures import FixtureManager
22- from _pytest .nodes import Node
2323from _pytest .outcomes import exit
24+ from _pytest .reports import CollectReport
2425from _pytest .runner import collect_one_node
2526from _pytest .runner import SetupState
2627
2728
2829if TYPE_CHECKING :
30+ from typing import Type
31+
2932 from _pytest .python import Package
3033
3134
@@ -405,7 +408,16 @@ def __init__(self, config) -> None:
405408 self ._initialpaths = frozenset () # type: FrozenSet[py.path.local]
406409
407410 # Keep track of any collected nodes in here, so we don't duplicate fixtures
408- self ._collection_node_cache = {} # type: Dict[str, List[Node]]
411+ self ._collection_node_cache1 = (
412+ {}
413+ ) # type: Dict[py.path.local, Sequence[nodes.Collector]]
414+ self ._collection_node_cache2 = (
415+ {}
416+ ) # type: Dict[Tuple[Type[nodes.Collector], py.path.local], nodes.Collector]
417+ self ._collection_node_cache3 = (
418+ {}
419+ ) # type: Dict[Tuple[Type[nodes.Collector], str], CollectReport]
420+
409421 # Dirnames of pkgs with dunder-init files.
410422 self ._collection_pkg_roots = {} # type: Dict[py.path.local, Package]
411423
@@ -523,7 +535,9 @@ def collect(self):
523535 self ._notfound .append ((report_arg , sys .exc_info ()[1 ]))
524536
525537 self .trace .root .indent -= 1
526- self ._collection_node_cache .clear ()
538+ self ._collection_node_cache1 .clear ()
539+ self ._collection_node_cache2 .clear ()
540+ self ._collection_node_cache3 .clear ()
527541 self ._collection_pkg_roots .clear ()
528542
529543 def _collect (self , arg ):
@@ -544,13 +558,13 @@ def _collect(self, arg):
544558 if parent .isdir ():
545559 pkginit = parent .join ("__init__.py" )
546560 if pkginit .isfile ():
547- if pkginit not in self ._collection_node_cache :
561+ if pkginit not in self ._collection_node_cache1 :
548562 col = self ._collectfile (pkginit , handle_dupes = False )
549563 if col :
550564 if isinstance (col [0 ], Package ):
551565 self ._collection_pkg_roots [parent ] = col [0 ]
552566 # always store a list in the cache, matchnodes expects it
553- self ._collection_node_cache [col [0 ].fspath ] = [col [0 ]]
567+ self ._collection_node_cache1 [col [0 ].fspath ] = [col [0 ]]
554568
555569 # If it's a directory argument, recurse and look for any Subpackages.
556570 # Let the Package collector deal with subnodes, don't collect here.
@@ -577,21 +591,21 @@ def _collect(self, arg):
577591
578592 for x in self ._collectfile (path ):
579593 key = (type (x ), x .fspath )
580- if key in self ._collection_node_cache :
581- yield self ._collection_node_cache [key ]
594+ if key in self ._collection_node_cache2 :
595+ yield self ._collection_node_cache2 [key ]
582596 else :
583- self ._collection_node_cache [key ] = x
597+ self ._collection_node_cache2 [key ] = x
584598 yield x
585599 else :
586600 assert argpath .check (file = 1 )
587601
588- if argpath in self ._collection_node_cache :
589- col = self ._collection_node_cache [argpath ]
602+ if argpath in self ._collection_node_cache1 :
603+ col = self ._collection_node_cache1 [argpath ]
590604 else :
591605 collect_root = self ._collection_pkg_roots .get (argpath .dirname , self )
592606 col = collect_root ._collectfile (argpath , handle_dupes = False )
593607 if col :
594- self ._collection_node_cache [argpath ] = col
608+ self ._collection_node_cache1 [argpath ] = col
595609 m = self .matchnodes (col , names )
596610 # If __init__.py was the only file requested, then the matched node will be
597611 # the corresponding Package, and the first yielded item will be the __init__
@@ -704,11 +718,11 @@ def _matchnodes(self, matching, names):
704718 continue
705719 assert isinstance (node , nodes .Collector )
706720 key = (type (node ), node .nodeid )
707- if key in self ._collection_node_cache :
708- rep = self ._collection_node_cache [key ]
721+ if key in self ._collection_node_cache3 :
722+ rep = self ._collection_node_cache3 [key ]
709723 else :
710724 rep = collect_one_node (node )
711- self ._collection_node_cache [key ] = rep
725+ self ._collection_node_cache3 [key ] = rep
712726 if rep .passed :
713727 has_matched = False
714728 for x in rep .result :
0 commit comments