Merge pull request #6197 from asottile/fix_init_py_discovery

Fix incorrect discovery of non-test `__init__.py` files.
This commit is contained in:
Anthony Sottile 2019-11-15 13:19:48 -08:00 committed by GitHub
commit 19a15a94ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 41 deletions

View File

@ -0,0 +1 @@
Fix incorrect discovery of non-test ``__init__.py`` files.

View File

@ -0,0 +1 @@
Revert "The first test in a package (``__init__.py``) marked with ``@pytest.mark.skip`` is now correctly skipped.".

View File

@ -251,21 +251,18 @@ class PyobjMixin(PyobjContext):
@property @property
def obj(self): def obj(self):
"""Underlying Python object.""" """Underlying Python object."""
self._mount_obj_if_needed()
return self._obj
@obj.setter
def obj(self, value):
self._obj = value
def _mount_obj_if_needed(self):
obj = getattr(self, "_obj", None) obj = getattr(self, "_obj", None)
if obj is None: if obj is None:
self._obj = obj = self._getobj() self._obj = obj = self._getobj()
# XXX evil hack # XXX evil hack
# used to avoid Instance collector marker duplication # used to avoid Instance collector marker duplication
if self._ALLOW_MARKERS: if self._ALLOW_MARKERS:
self.own_markers.extend(get_unpacked_marks(obj)) self.own_markers.extend(get_unpacked_marks(self.obj))
return obj
@obj.setter
def obj(self, value):
self._obj = value
def _getobj(self): def _getobj(self):
"""Gets the underlying Python object. May be overwritten by subclasses.""" """Gets the underlying Python object. May be overwritten by subclasses."""
@ -432,14 +429,6 @@ class PyCollector(PyobjMixin, nodes.Collector):
class Module(nodes.File, PyCollector): class Module(nodes.File, PyCollector):
""" Collector for test classes and functions. """ """ Collector for test classes and functions. """
def __init__(self, fspath, parent=None, config=None, session=None, nodeid=None):
if fspath.basename == "__init__.py":
self._ALLOW_MARKERS = False
nodes.FSCollector.__init__(
self, fspath, parent=parent, config=config, session=session, nodeid=nodeid
)
def _getobj(self): def _getobj(self):
return self._importtestmodule() return self._importtestmodule()
@ -639,7 +628,6 @@ class Package(Module):
return path in self.session._initialpaths return path in self.session._initialpaths
def collect(self): def collect(self):
self._mount_obj_if_needed()
this_path = self.fspath.dirpath() this_path = self.fspath.dirpath()
init_module = this_path.join("__init__.py") init_module = this_path.join("__init__.py")
if init_module.check(file=1) and path_matches_patterns( if init_module.check(file=1) and path_matches_patterns(

View File

@ -1257,3 +1257,24 @@ def test_collector_respects_tbstyle(testdir):
"*= 1 error in *", "*= 1 error in *",
] ]
) )
def test_does_not_eagerly_collect_packages(testdir):
testdir.makepyfile("def test(): pass")
pydir = testdir.mkpydir("foopkg")
pydir.join("__init__.py").write("assert False")
result = testdir.runpytest()
assert result.ret == ExitCode.OK
def test_does_not_put_src_on_path(testdir):
# `src` is not on sys.path so it should not be importable
testdir.tmpdir.join("src/nope/__init__.py").ensure()
testdir.makepyfile(
"import pytest\n"
"def test():\n"
" with pytest.raises(ImportError):\n"
" import nope\n"
)
result = testdir.runpytest()
assert result.ret == ExitCode.OK

View File

@ -1162,26 +1162,3 @@ def test_importorskip():
match="^could not import 'doesnotexist': No module named .*", match="^could not import 'doesnotexist': No module named .*",
): ):
pytest.importorskip("doesnotexist") pytest.importorskip("doesnotexist")
def test_skip_package(testdir):
testdir.makepyfile(
__init__="""
import pytest
pytestmark = pytest.mark.skip
"""
)
testdir.makepyfile(
"""
import pytest
def test_skip1():
assert 0
def test_skip2():
assert 0
"""
)
result = testdir.inline_run()
_, skipped, _ = result.listoutcomes()
assert len(skipped) == 2