From e2934c3f8c03c83469f4c6670c207773a6e02df4 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 14 Jan 2020 19:15:26 +0100 Subject: [PATCH] Move common code between Session and Package to FSCollector --- src/_pytest/main.py | 39 +-------------------------------------- src/_pytest/nodes.py | 41 +++++++++++++++++++++++++++++++++++++++++ src/_pytest/python.py | 27 +-------------------------- 3 files changed, 43 insertions(+), 64 deletions(-) diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 283ff29b1..066c885b8 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -348,18 +348,6 @@ def pytest_collection_modifyitems(items, config): items[:] = remaining -class FSHookProxy: - def __init__(self, fspath, pm, remove_mods): - self.fspath = fspath - self.pm = pm - self.remove_mods = remove_mods - - def __getattr__(self, name): - x = self.pm.subset_hook_caller(name, remove_plugins=self.remove_mods) - self.__dict__[name] = x - return x - - class NoMatch(Exception): """ raised if matching cannot locate a matching names. """ @@ -401,7 +389,6 @@ class Session(nodes.FSCollector): self.shouldstop = False self.shouldfail = False self.trace = config.trace.root.get("collection") - self._norecursepatterns = config.getini("norecursedirs") self.startdir = config.invocation_dir self._initialpaths = frozenset() # type: FrozenSet[py.path.local] @@ -450,18 +437,7 @@ class Session(nodes.FSCollector): return path in self._initialpaths def gethookproxy(self, fspath): - # check if we have the common case of running - # hooks with all conftest.py files - pm = self.config.pluginmanager - my_conftestmodules = pm._getconftestmodules(fspath) - remove_mods = pm._conftest_plugins.difference(my_conftestmodules) - if remove_mods: - # one or more conftests are not in use at this fspath - proxy = FSHookProxy(fspath, pm, remove_mods) - else: - # all plugins are active for this fspath - proxy = self.config.hook - return proxy + return super()._gethookproxy(fspath) def perform_collect(self, args=None, genitems=True): hook = self.config.hook @@ -625,19 +601,6 @@ class Session(nodes.FSCollector): return ihook.pytest_collect_file(path=path, parent=self) - 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 - @staticmethod def _visit_filter(f): return f.check(file=1) diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index ab976efae..f9f1f4f68 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -393,6 +393,18 @@ def _check_initialpaths_for_relpath(session, fspath): return fspath.relto(initial_path) +class FSHookProxy: + def __init__(self, fspath, pm, remove_mods): + self.fspath = fspath + self.pm = pm + self.remove_mods = remove_mods + + def __getattr__(self, name): + x = self.pm.subset_hook_caller(name, remove_plugins=self.remove_mods) + self.__dict__[name] = x + return x + + class FSCollector(Collector): def __init__( self, fspath: py.path.local, parent=None, config=None, session=None, nodeid=None @@ -417,6 +429,35 @@ class FSCollector(Collector): super().__init__(name, parent, config, session, nodeid=nodeid, fspath=fspath) + self._norecursepatterns = self.config.getini("norecursedirs") + + def _gethookproxy(self, fspath): + # check if we have the common case of running + # hooks with all conftest.py files + pm = self.config.pluginmanager + my_conftestmodules = pm._getconftestmodules(fspath) + remove_mods = pm._conftest_plugins.difference(my_conftestmodules) + if remove_mods: + # one or more conftests are not in use at this fspath + proxy = FSHookProxy(fspath, pm, remove_mods) + else: + # all plugins are active for this fspath + proxy = self.config.hook + return proxy + + 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 + class File(FSCollector): """ base class for collecting tests from a file. """ diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 916ef7bd5..23a67d023 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -35,7 +35,6 @@ from _pytest.compat import safe_isclass from _pytest.compat import STRING_TYPES from _pytest.config import hookimpl from _pytest.deprecated import FUNCARGNAMES -from _pytest.main import FSHookProxy from _pytest.mark import MARK_GEN from _pytest.mark.structures import get_unpacked_marks from _pytest.mark.structures import normalize_mark_list @@ -579,32 +578,8 @@ class Package(Module): func = partial(_call_with_optional_argument, teardown_module, self.obj) self.addfinalizer(func) - 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 gethookproxy(self, fspath): - # check if we have the common case of running - # hooks with all conftest.py files - pm = self.config.pluginmanager - my_conftestmodules = pm._getconftestmodules(fspath) - remove_mods = pm._conftest_plugins.difference(my_conftestmodules) - if remove_mods: - # one or more conftests are not in use at this fspath - proxy = FSHookProxy(fspath, pm, remove_mods) - else: - # all plugins are active for this fspath - proxy = self.config.hook - return proxy + return super()._gethookproxy(fspath) def _collectfile(self, path, handle_dupes=True): assert (