def _try_load_conftest( self, anchor: py.path.local, importmode: Union[str, ImportMode] ) -> None: self._getconftestmodules(anchor, importmode) # let's also consider test* subdirs if anchor.check(dir=1): for x in anchor.listdir("test*"): if x.check(dir=1): self._getconftestmodules(x, importmode)
def _recurse(self, dirpath: py.path.local) -> bool: if dirpath.basename == "__pycache__": return False ihook = self._gethookproxy(dirpath.dirpath()) if ihook.pytest_ignore_collect(path=dirpath, config=self.config): return False for pat in self._norecursepatterns: if dirpath.check(fnmatch=pat): return False ihook = self._gethookproxy(dirpath) ihook.pytest_collect_directory(path=dirpath, parent=self) return True
def _visit_filter(f: py.path.local) -> bool: # TODO: Remove type: ignore once `py` is typed. return f.check(file=1) # type: ignore
def _collect( self, argpath: py.path.local, names: List[str]) -> Iterator[Union[nodes.Item, nodes.Collector]]: from _pytest.python import Package # Start with a Session root, and delve to argpath item (dir or file) # and stack all Packages found on the way. # No point in finding packages when collecting doctests if not self.config.getoption("doctestmodules", False): pm = self.config.pluginmanager for parent in reversed(argpath.parts()): if pm._confcutdir and pm._confcutdir.relto(parent): break if parent.isdir(): pkginit = parent.join("__init__.py") if pkginit.isfile(): if pkginit not in self._collection_node_cache1: col = self._collectfile(pkginit, handle_dupes=False) if col: if isinstance(col[0], Package): self._collection_pkg_roots[parent] = col[0] # always store a list in the cache, matchnodes expects it self._collection_node_cache1[col[0].fspath] = [ col[0] ] # If it's a directory argument, recurse and look for any Subpackages. # Let the Package collector deal with subnodes, don't collect here. if argpath.check(dir=1): assert not names, "invalid arg {!r}".format((argpath, names)) seen_dirs = set() # type: Set[py.path.local] for path in argpath.visit(fil=self._visit_filter, rec=self._recurse, bf=True, sort=True): dirpath = path.dirpath() if dirpath not in seen_dirs: # Collect packages first. seen_dirs.add(dirpath) pkginit = dirpath.join("__init__.py") if pkginit.exists(): for x in self._collectfile(pkginit): yield x if isinstance(x, Package): self._collection_pkg_roots[dirpath] = x if dirpath in self._collection_pkg_roots: # Do not collect packages here. continue for x in self._collectfile(path): key = (type(x), x.fspath) if key in self._collection_node_cache2: yield self._collection_node_cache2[key] else: self._collection_node_cache2[key] = x yield x else: assert argpath.check(file=1) if argpath in self._collection_node_cache1: col = self._collection_node_cache1[argpath] else: collect_root = self._collection_pkg_roots.get( argpath.dirname, self) col = collect_root._collectfile(argpath, handle_dupes=False) if col: self._collection_node_cache1[argpath] = col m = self.matchnodes(col, names) # If __init__.py was the only file requested, then the matched node will be # the corresponding Package, and the first yielded item will be the __init__ # Module itself, so just use that. If this special case isn't taken, then all # the files in the package will be yielded. if argpath.basename == "__init__.py": assert isinstance(m[0], nodes.Collector) try: yield next(iter(m[0].collect())) except StopIteration: # The package collects nothing with only an __init__.py # file in it, which gets ignored by the default # "python_files" option. pass return yield from m