[py-svn] pytest commit 9ff5086b4e67: introduce norecursedirs config option, remove recfilter()

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Sat Nov 6 09:57:00 CET 2010


# HG changeset patch -- Bitbucket.org
# Project pytest
# URL http://bitbucket.org/hpk42/pytest/overview
# User holger krekel <holger at merlinux.eu>
# Date 1288909286 -3600
# Node ID 9ff5086b4e67207b3caf98c5554269e1f126557d
# Parent  2dfb0db0864d075300712366a86cdf642c7c68d9
introduce norecursedirs config option, remove recfilter()

--- a/pytest/plugin/helpconfig.py
+++ b/pytest/plugin/helpconfig.py
@@ -44,8 +44,11 @@ def showhelp(config):
     tw.line("setup.cfg or tox.ini options to be put into [pytest] section:")
     tw.line()
 
-    for name, (help, type) in sorted(config._parser._inidict.items()):
-        line = "   %-15s  %s" %(name, help)
+    for name, (help, type, default) in sorted(config._parser._inidict.items()):
+        if type is None:
+            type = "string"
+        spec = "%s (%s)" % (name, type)
+        line = "  %-24s %s" %(spec, help)
         tw.line(line[:tw.fullwidth])
 
     tw.line() ; tw.line()
@@ -68,7 +71,7 @@ conftest_options = [
 def pytest_report_header(config):
     lines = []
     if config.option.debug or config.option.traceconfig:
-        lines.append("using: pytest-%s pylib-%s" % 
+        lines.append("using: pytest-%s pylib-%s" %
             (pytest.__version__,py.__version__))
             
     if config.option.traceconfig:

--- a/pytest/plugin/config.py
+++ b/pytest/plugin/config.py
@@ -10,10 +10,6 @@ def pytest_cmdline_parse(pluginmanager, 
     config.parse(args)
     return config
 
-def pytest_addoption(parser):
-    parser.addini('addopts', 'default command line arguments')
-    parser.addini('minversion', 'minimally required pytest version')
-
 class Parser:
     """ Parser for command line arguments. """
 
@@ -72,9 +68,10 @@ class Parser:
             setattr(option, name, value)
         return args
 
-    def addini(self, name, description, type=None):
+    def addini(self, name, help, type=None, default=None):
         """ add an ini-file option with the given name and description. """
-        self._inidict[name] = (description, type)
+        assert type in (None, "pathlist", "args")
+        self._inidict[name] = (help, type, default)
 
 class OptionGroup:
     def __init__(self, name, description="", parser=None):
@@ -293,13 +290,15 @@ class Config(object):
             sys.stderr.write(err)
             raise
 
+    def _initini(self, args):
+        self.inicfg = getcfg(args, ["setup.cfg", "tox.ini",])
+        self._parser.addini('addopts', 'extra command line options', 'args')
+        self._parser.addini('minversion', 'minimally required pytest version')
+
     def _preparse(self, args, addopts=True):
-        self.inicfg = {}
-        self.inicfg = getcfg(args, ["setup.cfg", "tox.ini",])
-        if self.inicfg and addopts:
-            newargs = self.inicfg.get("addopts", None)
-            if newargs:
-                args[:] = py.std.shlex.split(newargs) + args
+        self._initini(args)
+        if addopts:
+            args[:] = self.getini("addopts") + args
         self._checkversion()
         self.pluginmanager.consider_setuptools_entrypoints()
         self.pluginmanager.consider_env()
@@ -358,20 +357,25 @@ class Config(object):
         specified name hasn't been registered through a prior ``parse.addini``
         call (usually from a plugin), a ValueError is raised. """
         try:
-            description, type = self._parser._inidict[name]
+            description, type, default = self._parser._inidict[name]
         except KeyError:
             raise ValueError("unknown configuration value: %r" %(name,))
         try:
             value = self.inicfg[name]
         except KeyError:
-            return # None indicates nothing found
+            if default is not None:
+                return default
+            return {'pathlist': [], 'args': [], None: ''}.get(type)
         if type == "pathlist":
             dp = py.path.local(self.inicfg.config.path).dirpath()
             l = []
             for relpath in py.std.shlex.split(value):
                 l.append(dp.join(relpath, abs=True))
             return l
+        elif type == "args":
+            return py.std.shlex.split(value)
         else:
+            assert type is None
             return value
 
     def _getconftest_pathlist(self, name, path=None):

--- a/testing/test_collect.py
+++ b/testing/test_collect.py
@@ -99,14 +99,25 @@ class TestCollectFS:
         tmpdir.ensure(".whatever", 'test_notfound.py')
         tmpdir.ensure(".bzr", 'test_notfound.py')
         tmpdir.ensure("normal", 'test_found.py')
-        tmpdir.ensure('test_found.py')
 
-        col = testdir.getnode(testdir.parseconfig(tmpdir), tmpdir)
-        items = col.collect()
-        names = [x.name for x in items]
-        assert len(items) == 2
-        assert 'normal' in names
-        assert 'test_found.py' in names
+        result = testdir.runpytest("--collectonly")
+        s = result.stdout.str()
+        assert "test_notfound" not in s
+        assert "test_found" in s
+
+    def test_custom_norecursedirs(self, testdir):
+        testdir.makeini("""
+            [pytest]
+            norecursedirs = mydir xyz*
+        """)
+        tmpdir = testdir.tmpdir
+        tmpdir.ensure("mydir", "test_hello.py").write("def test_1(): pass")
+        tmpdir.ensure("xyz123", "test_2.py").write("def test_2(): 0/0")
+        tmpdir.ensure("xy", "test_ok.py").write("def test_3(): pass")
+        rec = testdir.inline_run()
+        rec.assertoutcome(passed=1)
+        rec = testdir.inline_run("xyz123/test_2.py")
+        rec.assertoutcome(failed=1)
 
     def test_found_certain_testfiles(self, testdir):
         p1 = testdir.makepyfile(test_found = "pass", found_test="pass")

--- a/testing/test_config.py
+++ b/testing/test_config.py
@@ -152,6 +152,23 @@ class TestConfigAPI:
         assert l[1] == p.dirpath('world/sub.py')
         py.test.raises(ValueError, config.getini, 'other')
 
+    def test_addini_args(self, testdir):
+        testdir.makeconftest("""
+            def pytest_addoption(parser):
+                parser.addini("args", "new args", type="args")
+                parser.addini("a2", "", "args", default="1 2 3".split())
+        """)
+        p = testdir.makeini("""
+            [pytest]
+            args=123 "123 hello" "this"
+        """)
+        config = testdir.parseconfig()
+        l = config.getini("args")
+        assert len(l) == 3
+        assert l == ["123", "123 hello", "this"]
+        l = config.getini("a2")
+        assert l == list("123")
+
 def test_options_on_small_file_do_not_blow_up(testdir):
     def runfiletest(opts):
         reprec = testdir.inline_run(*opts)

--- a/pytest/plugin/session.py
+++ b/pytest/plugin/session.py
@@ -16,7 +16,8 @@ EXIT_INTERNALERROR = 3
 EXIT_NOHOSTS = 4
 
 def pytest_addoption(parser):
-
+    parser.addini("norecursedirs", "directory patterns to avoid for recursion",
+        type="args", default=('.*', 'CVS', '_darcs', '{arch}'))
     group = parser.getgroup("general", "running and selection options")
     group._addoption('-x', '--exitfirst', action="store_true", default=False,
                dest="exitfirst",
@@ -107,13 +108,15 @@ def pytest_ignore_collect(path, config):
     return path in ignore_paths
 
 def pytest_collect_directory(path, parent):
-    if not parent.recfilter(path): # by default special ".cvs", ...
-        # check if cmdline specified this dir or a subdir directly
-        for arg in parent.collection._argfspaths:
-            if path == arg or arg.relto(path):
-                break
-        else:
-            return
+    # check if cmdline specified this dir or a subdir directly
+    for arg in parent.collection._argfspaths:
+        if path == arg or arg.relto(path):
+            break
+    else:
+        patterns = parent.config.getini("norecursedirs")
+        for pat in patterns or []:
+            if path.check(fnmatch=pat):
+                return
     return Directory(path, parent=parent)
 
 class Session(object):
@@ -465,10 +468,6 @@ class File(FSCollector):
     """ base class for collecting tests from a file. """
 
 class Directory(FSCollector):
-    def recfilter(self, path):
-        if path.check(dir=1, dotfile=0):
-            return path.basename not in ('CVS', '_darcs', '{arch}')
-
     def collect(self):
         l = []
         for path in self.fspath.listdir(sort=True):



More information about the pytest-commit mailing list