Skip to content

Commit d0e8b71

Browse files
committed
main: inline _collect() into collect()
This removes an unhelpful level of indirection and enables some upcoming upcoming simplifications.
1 parent eec13ba commit d0e8b71

File tree

1 file changed

+90
-91
lines changed

1 file changed

+90
-91
lines changed

src/_pytest/main.py

Lines changed: 90 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -637,104 +637,103 @@ def perform_collect( # noqa: F811
637637
return items
638638

639639
def collect(self) -> Iterator[Union[nodes.Item, nodes.Collector]]:
640-
for fspath, parts in self._initial_parts:
641-
self.trace("processing argument", (fspath, parts))
642-
self.trace.root.indent += 1
643-
yield from self._collect(fspath, parts)
644-
self.trace.root.indent -= 1
645-
self._collection_node_cache1.clear()
646-
self._collection_node_cache2.clear()
647-
self._collection_matchnodes_cache.clear()
648-
self._collection_pkg_roots.clear()
649-
650-
def _collect(
651-
self, argpath: py.path.local, names: Sequence[str]
652-
) -> Iterator[Union[nodes.Item, nodes.Collector]]:
653640
from _pytest.python import Package
654641

655-
# Start with a Session root, and delve to argpath item (dir or file)
656-
# and stack all Packages found on the way.
657-
# No point in finding packages when collecting doctests.
658-
if not self.config.getoption("doctestmodules", False):
659-
pm = self.config.pluginmanager
660-
for parent in reversed(argpath.parts()):
661-
if pm._confcutdir and pm._confcutdir.relto(parent):
662-
break
663-
664-
if parent.isdir():
665-
pkginit = parent.join("__init__.py")
666-
if pkginit.isfile():
667-
if pkginit not in self._collection_node_cache1:
668-
col = self._collectfile(pkginit, handle_dupes=False)
669-
if col:
670-
if isinstance(col[0], Package):
671-
self._collection_pkg_roots[str(parent)] = col[0]
672-
self._collection_node_cache1[col[0].fspath] = [col[0]]
673-
674-
# If it's a directory argument, recurse and look for any Subpackages.
675-
# Let the Package collector deal with subnodes, don't collect here.
676-
if argpath.check(dir=1):
677-
assert not names, "invalid arg {!r}".format((argpath, names))
678-
679-
seen_dirs = set() # type: Set[py.path.local]
680-
for direntry in visit(str(argpath), self._recurse):
681-
if not direntry.is_file():
682-
continue
683-
684-
path = py.path.local(direntry.path)
685-
dirpath = path.dirpath()
642+
for argpath, names in self._initial_parts:
643+
self.trace("processing argument", (argpath, names))
644+
self.trace.root.indent += 1
686645

687-
if dirpath not in seen_dirs:
688-
# Collect packages first.
689-
seen_dirs.add(dirpath)
690-
pkginit = dirpath.join("__init__.py")
691-
if pkginit.exists():
692-
for x in self._collectfile(pkginit):
646+
# Start with a Session root, and delve to argpath item (dir or file)
647+
# and stack all Packages found on the way.
648+
# No point in finding packages when collecting doctests.
649+
if not self.config.getoption("doctestmodules", False):
650+
pm = self.config.pluginmanager
651+
for parent in reversed(argpath.parts()):
652+
if pm._confcutdir and pm._confcutdir.relto(parent):
653+
break
654+
655+
if parent.isdir():
656+
pkginit = parent.join("__init__.py")
657+
if pkginit.isfile():
658+
if pkginit not in self._collection_node_cache1:
659+
col = self._collectfile(pkginit, handle_dupes=False)
660+
if col:
661+
if isinstance(col[0], Package):
662+
self._collection_pkg_roots[str(parent)] = col[0]
663+
self._collection_node_cache1[col[0].fspath] = [
664+
col[0]
665+
]
666+
667+
# If it's a directory argument, recurse and look for any Subpackages.
668+
# Let the Package collector deal with subnodes, don't collect here.
669+
if argpath.check(dir=1):
670+
assert not names, "invalid arg {!r}".format((argpath, names))
671+
672+
seen_dirs = set() # type: Set[py.path.local]
673+
for direntry in visit(str(argpath), self._recurse):
674+
if not direntry.is_file():
675+
continue
676+
677+
path = py.path.local(direntry.path)
678+
dirpath = path.dirpath()
679+
680+
if dirpath not in seen_dirs:
681+
# Collect packages first.
682+
seen_dirs.add(dirpath)
683+
pkginit = dirpath.join("__init__.py")
684+
if pkginit.exists():
685+
for x in self._collectfile(pkginit):
686+
yield x
687+
if isinstance(x, Package):
688+
self._collection_pkg_roots[str(dirpath)] = x
689+
if str(dirpath) in self._collection_pkg_roots:
690+
# Do not collect packages here.
691+
continue
692+
693+
for x in self._collectfile(path):
694+
key = (type(x), x.fspath)
695+
if key in self._collection_node_cache2:
696+
yield self._collection_node_cache2[key]
697+
else:
698+
self._collection_node_cache2[key] = x
693699
yield x
694-
if isinstance(x, Package):
695-
self._collection_pkg_roots[str(dirpath)] = x
696-
if str(dirpath) in self._collection_pkg_roots:
697-
# Do not collect packages here.
700+
else:
701+
assert argpath.check(file=1)
702+
703+
if argpath in self._collection_node_cache1:
704+
col = self._collection_node_cache1[argpath]
705+
else:
706+
collect_root = self._collection_pkg_roots.get(argpath.dirname, self)
707+
col = collect_root._collectfile(argpath, handle_dupes=False)
708+
if col:
709+
self._collection_node_cache1[argpath] = col
710+
m = self.matchnodes(col, names)
711+
if not m:
712+
report_arg = "::".join((str(argpath), *names))
713+
self._notfound.append((report_arg, col))
698714
continue
699715

700-
for x in self._collectfile(path):
701-
key = (type(x), x.fspath)
702-
if key in self._collection_node_cache2:
703-
yield self._collection_node_cache2[key]
704-
else:
705-
self._collection_node_cache2[key] = x
706-
yield x
707-
else:
708-
assert argpath.check(file=1)
716+
# If __init__.py was the only file requested, then the matched node will be
717+
# the corresponding Package, and the first yielded item will be the __init__
718+
# Module itself, so just use that. If this special case isn't taken, then all
719+
# the files in the package will be yielded.
720+
if argpath.basename == "__init__.py":
721+
assert isinstance(m[0], nodes.Collector)
722+
try:
723+
yield next(iter(m[0].collect()))
724+
except StopIteration:
725+
# The package collects nothing with only an __init__.py
726+
# file in it, which gets ignored by the default
727+
# "python_files" option.
728+
pass
729+
continue
730+
yield from m
709731

710-
if argpath in self._collection_node_cache1:
711-
col = self._collection_node_cache1[argpath]
712-
else:
713-
collect_root = self._collection_pkg_roots.get(argpath.dirname, self)
714-
col = collect_root._collectfile(argpath, handle_dupes=False)
715-
if col:
716-
self._collection_node_cache1[argpath] = col
717-
m = self.matchnodes(col, names)
718-
if not m:
719-
report_arg = "::".join((str(argpath), *names))
720-
self._notfound.append((report_arg, col))
721-
return
722-
723-
# If __init__.py was the only file requested, then the matched node will be
724-
# the corresponding Package, and the first yielded item will be the __init__
725-
# Module itself, so just use that. If this special case isn't taken, then all
726-
# the files in the package will be yielded.
727-
if argpath.basename == "__init__.py":
728-
assert isinstance(m[0], nodes.Collector)
729-
try:
730-
yield next(iter(m[0].collect()))
731-
except StopIteration:
732-
# The package collects nothing with only an __init__.py
733-
# file in it, which gets ignored by the default
734-
# "python_files" option.
735-
pass
736-
return
737-
yield from m
732+
self.trace.root.indent -= 1
733+
self._collection_node_cache1.clear()
734+
self._collection_node_cache2.clear()
735+
self._collection_matchnodes_cache.clear()
736+
self._collection_pkg_roots.clear()
738737

739738
def matchnodes(
740739
self,

0 commit comments

Comments
 (0)