Merge pull request #6197 from asottile/fix_init_py_discovery
Fix incorrect discovery of non-test `__init__.py` files.
This commit is contained in:
		
						commit
						19a15a94ee
					
				| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Fix incorrect discovery of non-test ``__init__.py`` files.
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Revert "The first test in a package (``__init__.py``) marked with ``@pytest.mark.skip`` is now correctly skipped.".
 | 
				
			||||||
| 
						 | 
					@ -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(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue