[py-svn] py-trunk commit 2f97b1b6a2cc: introduce --confcutdir option to early-inhibit lookup of conftest files above a certain directory.

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Thu Dec 31 15:10:58 CET 2009


# HG changeset patch -- Bitbucket.org
# Project py-trunk
# URL http://bitbucket.org/hpk42/py-trunk/overview/
# User holger krekel <holger at merlinux.eu>
# Date 1262268632 -3600
# Node ID 2f97b1b6a2cc27197238679b991a8e6a289f65b1
# Parent dd3f0c0bc8a35eff3b87dea5f453836fd9e4cce3
introduce --confcutdir option to early-inhibit lookup of conftest files above a certain directory.

--- a/py/plugin/pytest_default.py
+++ b/py/plugin/pytest_default.py
@@ -73,7 +73,9 @@ def pytest_addoption(parser):
         "test process debugging and configuration")
     group.addoption('--basetemp', dest="basetemp", default=None, metavar="dir",
                help="base temporary directory for this test run.")
-
+    group.addoption('--confcutdir', dest="confcutdir", default=None, 
+        metavar="dir",
+        help="only load conftest.py's relative to specified dir.")
     if execnet:
         add_dist_options(parser)
     else:

--- a/testing/pytest/test_conftesthandle.py
+++ b/testing/pytest/test_conftesthandle.py
@@ -89,3 +89,46 @@ class TestConftestValueAccessGlobal:
         path = py.path.local(mod.__file__)
         assert path.dirpath() == basedir.join("adir", "b")
         assert path.purebasename == "conftest"
+
+def test_conftestcutdir(testdir):
+    conf = testdir.makeconftest("")
+    p = testdir.mkdir("x")
+    conftest = Conftest(confcutdir=p)
+    conftest.setinitial([testdir.tmpdir])
+    l = conftest.getconftestmodules(p)
+    assert len(l) == 0
+    l = conftest.getconftestmodules(conf.dirpath())
+    assert len(l) == 0
+    assert conf not in conftest._conftestpath2mod
+    # but we can still import a conftest directly 
+    conftest.importconftest(conf)
+    l = conftest.getconftestmodules(conf.dirpath())
+    assert l[0].__file__.startswith(str(conf))
+    # and all sub paths get updated properly
+    l = conftest.getconftestmodules(p)
+    assert len(l) == 1
+    assert l[0].__file__.startswith(str(conf))
+
+def test_conftestcutdir_inplace_considered(testdir):
+    conf = testdir.makeconftest("")
+    conftest = Conftest(confcutdir=conf.dirpath())
+    conftest.setinitial([conf.dirpath()])
+    l = conftest.getconftestmodules(conf.dirpath())
+    assert len(l) == 1
+    assert l[0].__file__.startswith(str(conf))
+
+def test_setinitial_confcut(testdir):
+    conf = testdir.makeconftest("")
+    sub = testdir.mkdir("sub")
+    sub.chdir()
+    for opts in (["--confcutdir=%s" % sub, sub],
+                [sub, "--confcutdir=%s" % sub],
+                ["--confcutdir=.", sub],
+                [sub, "--confcutdir", sub],
+                [str(sub), "--confcutdir", "."],
+    ):
+        conftest = Conftest()
+        conftest.setinitial(opts)
+        assert conftest._confcutdir == sub
+        assert conftest.getconftestmodules(sub) == []
+        assert conftest.getconftestmodules(conf.dirpath()) == []

--- a/testing/plugin/test_pytest_default.py
+++ b/testing/plugin/test_pytest_default.py
@@ -92,3 +92,14 @@ def test_pytest_report_iteminfo():
 
     res = pytest_report_iteminfo(FakeItem())
     assert res == "-reportinfo-"
+
+
+def test_conftest_confcutdir(testdir):
+    testdir.makeconftest("assert 0")
+    x = testdir.mkdir("x")
+    x.join("conftest.py").write(py.code.Source("""
+        def pytest_addoption(parser):
+            parser.addoption("--xyz", action="store_true")
+    """))
+    result = testdir.runpytest("-h", "--confcutdir=%s" % x, x)
+    assert result.stdout.fnmatch_lines(["*--xyz*"])

--- a/py/impl/test/conftesthandle.py
+++ b/py/impl/test/conftesthandle.py
@@ -8,10 +8,11 @@ class Conftest(object):
         Note that triggering Conftest instances to import 
         conftest.py files may result in added cmdline options. 
     """ 
-    def __init__(self, onimport=None):
+    def __init__(self, onimport=None, confcutdir=None):
         self._path2confmods = {}
         self._onimport = onimport
         self._conftestpath2mod = {}
+        self._confcutdir = confcutdir
 
     def setinitial(self, args):
         """ try to find a first anchor path for looking up global values
@@ -23,6 +24,17 @@ class Conftest(object):
             bootstrapped ... 
         """
         current = py.path.local()
+        opt = '--confcutdir'
+        for i in range(len(args)):
+            opt1 = str(args[i])
+            if opt1.startswith(opt):
+                if opt1 == opt:
+                    if len(args) > i:
+                        p = current.join(args[i+1], abs=True)
+                elif opt1.startswith(opt + "="):
+                    p = current.join(opt1[len(opt)+1:], abs=1)
+                self._confcutdir = p 
+                break
         for arg in args + [current]:
             anchor = current.join(arg, abs=1)
             if anchor.check(): # we found some file object 
@@ -37,16 +49,20 @@ class Conftest(object):
             clist = self._path2confmods[path]
         except KeyError:
             if path is None:
-                raise ValueError("missing default conftest.")
+                raise ValueError("missing default confest.")
             dp = path.dirpath()
             if dp == path:
-                clist = self._path2confmods[path] = []
+                clist = []
             else:
+                cutdir = self._confcutdir
                 clist = self.getconftestmodules(dp)
-                conftestpath = path.join("conftest.py")
-                if conftestpath.check(file=1):
-                    clist.append(self.importconftest(conftestpath))
-                self._path2confmods[path] = clist
+                if cutdir and path != cutdir and not path.relto(cutdir):
+                    pass
+                else:
+                    conftestpath = path.join("conftest.py")
+                    if conftestpath.check(file=1):
+                        clist.append(self.importconftest(conftestpath))
+            self._path2confmods[path] = clist
         # be defensive: avoid changes from caller side to
         # affect us by always returning a copy of the actual list 
         return clist[:]
@@ -77,8 +93,14 @@ class Conftest(object):
                 mod = conftestpath.pyimport(modname=modname)
             else:
                 mod = conftestpath.pyimport()
+            self._conftestpath2mod[conftestpath] = mod
+            dirpath = conftestpath.dirpath()
+            if dirpath in self._path2confmods:
+                for path, mods in self._path2confmods.items():
+                    if path and path.relto(dirpath) or path == dirpath:
+                        assert mod not in mods
+                        mods.append(mod)
             self._postimport(mod)
-            self._conftestpath2mod[conftestpath] = mod
             return mod
 
     def _postimport(self, mod):

--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,9 @@ Changes between 1.X and 1.1.1
 - new option: --ignore will prevent specified path from collection. 
   Can be specified multiple times. 
 
+- new option: --confcutdir=dir will make py.test only consider conftest 
+  files that are relative to the specified dir.  
+
 - install 'py.test' and `py.which` with a ``-$VERSION`` suffix to
   disambiguate between Python3, python2.X, Jython and PyPy installed versions.



More information about the pytest-commit mailing list