Revert "Move common code between Session and Package to FSCollector"

This reverts commit f10ab021e2.

The commit was good in that it removed a non-trivial amount of code
duplication. However it was done in the wrong layer (nodes.py) and split
up a major part of the collection (the filesystem traversal) to a
separate class making it harder to understand.

We should try to reduce the duplication, but in a more appropriate
manner.
This commit is contained in:
Ran Benita 2020-08-14 14:05:00 +03:00
parent 32edc4655c
commit 4b8e1a1771
3 changed files with 74 additions and 39 deletions

View File

@ -523,6 +523,43 @@ class Session(nodes.FSCollector):
proxy = self.config.hook proxy = self.config.hook
return proxy return proxy
def _recurse(self, direntry: "os.DirEntry[str]") -> bool:
if direntry.name == "__pycache__":
return False
path = py.path.local(direntry.path)
ihook = self.gethookproxy(path.dirpath())
if ihook.pytest_ignore_collect(path=path, config=self.config):
return False
norecursepatterns = self.config.getini("norecursedirs")
for pat in norecursepatterns:
if path.check(fnmatch=pat):
return False
return True
def _collectfile(
self, path: py.path.local, handle_dupes: bool = True
) -> Sequence[nodes.Collector]:
assert (
path.isfile()
), "{!r} is not a file (isdir={!r}, exists={!r}, islink={!r})".format(
path, path.isdir(), path.exists(), path.islink()
)
ihook = self.gethookproxy(path)
if not self.isinitpath(path):
if ihook.pytest_ignore_collect(path=path, config=self.config):
return ()
if handle_dupes:
keepduplicates = self.config.getoption("keepduplicates")
if not keepduplicates:
duplicate_paths = self.config.pluginmanager._duplicatepaths
if path in duplicate_paths:
return ()
else:
duplicate_paths.add(path)
return ihook.pytest_collect_file(path=path, parent=self) # type: ignore[no-any-return]
@overload @overload
def perform_collect( def perform_collect(
self, args: Optional[Sequence[str]] = ..., genitems: "Literal[True]" = ... self, args: Optional[Sequence[str]] = ..., genitems: "Literal[True]" = ...

View File

@ -8,7 +8,6 @@ from typing import Iterable
from typing import Iterator from typing import Iterator
from typing import List from typing import List
from typing import Optional from typing import Optional
from typing import Sequence
from typing import Set from typing import Set
from typing import Tuple from typing import Tuple
from typing import TypeVar from typing import TypeVar
@ -528,8 +527,6 @@ class FSCollector(Collector):
super().__init__(name, parent, config, session, nodeid=nodeid, fspath=fspath) super().__init__(name, parent, config, session, nodeid=nodeid, fspath=fspath)
self._norecursepatterns = self.config.getini("norecursedirs")
@classmethod @classmethod
def from_parent(cls, parent, *, fspath, **kw): def from_parent(cls, parent, *, fspath, **kw):
"""The public constructor.""" """The public constructor."""
@ -543,42 +540,6 @@ class FSCollector(Collector):
warnings.warn(FSCOLLECTOR_GETHOOKPROXY_ISINITPATH, stacklevel=2) warnings.warn(FSCOLLECTOR_GETHOOKPROXY_ISINITPATH, stacklevel=2)
return self.session.isinitpath(path) return self.session.isinitpath(path)
def _recurse(self, direntry: "os.DirEntry[str]") -> bool:
if direntry.name == "__pycache__":
return False
path = py.path.local(direntry.path)
ihook = self.session.gethookproxy(path.dirpath())
if ihook.pytest_ignore_collect(path=path, config=self.config):
return False
for pat in self._norecursepatterns:
if path.check(fnmatch=pat):
return False
return True
def _collectfile(
self, path: py.path.local, handle_dupes: bool = True
) -> Sequence[Collector]:
assert (
path.isfile()
), "{!r} is not a file (isdir={!r}, exists={!r}, islink={!r})".format(
path, path.isdir(), path.exists(), path.islink()
)
ihook = self.session.gethookproxy(path)
if not self.session.isinitpath(path):
if ihook.pytest_ignore_collect(path=path, config=self.config):
return ()
if handle_dupes:
keepduplicates = self.config.getoption("keepduplicates")
if not keepduplicates:
duplicate_paths = self.config.pluginmanager._duplicatepaths
if path in duplicate_paths:
return ()
else:
duplicate_paths.add(path)
return ihook.pytest_collect_file(path=path, parent=self) # type: ignore[no-any-return]
class File(FSCollector): class File(FSCollector):
"""Base class for collecting tests from a file.""" """Base class for collecting tests from a file."""

View File

@ -634,6 +634,43 @@ class Package(Module):
warnings.warn(FSCOLLECTOR_GETHOOKPROXY_ISINITPATH, stacklevel=2) warnings.warn(FSCOLLECTOR_GETHOOKPROXY_ISINITPATH, stacklevel=2)
return self.session.isinitpath(path) return self.session.isinitpath(path)
def _recurse(self, direntry: "os.DirEntry[str]") -> bool:
if direntry.name == "__pycache__":
return False
path = py.path.local(direntry.path)
ihook = self.session.gethookproxy(path.dirpath())
if ihook.pytest_ignore_collect(path=path, config=self.config):
return False
norecursepatterns = self.config.getini("norecursedirs")
for pat in norecursepatterns:
if path.check(fnmatch=pat):
return False
return True
def _collectfile(
self, path: py.path.local, handle_dupes: bool = True
) -> typing.Sequence[nodes.Collector]:
assert (
path.isfile()
), "{!r} is not a file (isdir={!r}, exists={!r}, islink={!r})".format(
path, path.isdir(), path.exists(), path.islink()
)
ihook = self.session.gethookproxy(path)
if not self.session.isinitpath(path):
if ihook.pytest_ignore_collect(path=path, config=self.config):
return ()
if handle_dupes:
keepduplicates = self.config.getoption("keepduplicates")
if not keepduplicates:
duplicate_paths = self.config.pluginmanager._duplicatepaths
if path in duplicate_paths:
return ()
else:
duplicate_paths.add(path)
return ihook.pytest_collect_file(path=path, parent=self) # type: ignore[no-any-return]
def collect(self) -> Iterable[Union[nodes.Item, nodes.Collector]]: def collect(self) -> Iterable[Union[nodes.Item, nodes.Collector]]:
this_path = self.fspath.dirpath() this_path = self.fspath.dirpath()
init_module = this_path.join("__init__.py") init_module = this_path.join("__init__.py")