[pytest] fix TestSuite.run wrapper (closes #280806)

_ts_wrapped_run is a modified version of the upstream unittest.suite.TestSuite.run method, but the recent (python 2.7) evolutions of this later had never been 'integrated' in lgc.

This mismatch broke tests using a tearDownModule function.

This patch is... humm, sorry...

authorDavid Douard <david.douard@logilab.fr>
changesetd7b9bf865889
branchdefault
phasepublic
hiddenno
parent revision#5944536a865c [ureports] write unicode not bytes (closes #277372)
child revision#2bcffefa1559 [testlib] remove deprecated code, #31725b8fa3f5 [coverage] Provides better tools to pause tracing
files modified by this revision
pytest.py
# HG changeset patch
# User David Douard <david.douard@logilab.fr>
# Date 1417130204 -3600
# Fri Nov 28 00:16:44 2014 +0100
# Node ID d7b9bf86588969721df23d9d19b2832e1a6e197d
# Parent 5944536a865ca62119bd3e1877f4a9330328e636
[pytest] fix TestSuite.run wrapper (closes #280806)

_ts_wrapped_run is a modified version of the upstream
unittest.suite.TestSuite.run method,
but the recent (python 2.7) evolutions of this later had never been 'integrated'
in lgc.

This mismatch broke tests using a tearDownModule function.

This patch is... humm, sorry...

diff --git a/pytest.py b/pytest.py
@@ -1080,12 +1080,18 @@
1              return []
2          testnames = super(NonStrictTestLoader, self).getTestCaseNames(
3                  testCaseClass)
4          return [testname for testname in testnames if not is_skipped(testname)]
5 
6 +
7 +# The 2 functions below are modified versions of the TestSuite.run method
8 +# that is provided with unittest2 for python 2.6, in unittest2/suite.py
9 +# It is used to monkeypatch the original implementation to support
10 +# extra runcondition and options arguments (see in testlib.py)
11 +
12  def _ts_run(self, result, runcondition=None, options=None):
13 -    self._wrapped_run(result,runcondition=runcondition, options=options)
14 +    self._wrapped_run(result, runcondition=runcondition, options=options)
15      self._tearDownPreviousClass(None, result)
16      self._handleModuleTearDown(result)
17      return result
18 
19  def _ts_wrapped_run(self, result, debug=False, runcondition=None, options=None):
@@ -1095,14 +1101,21 @@
20          if unittest_suite._isnotsuite(test):
21              self._tearDownPreviousClass(test, result)
22              self._handleModuleFixture(test, result)
23              self._handleClassSetUp(test, result)
24              result._previousTestClass = test.__class__
25 -            if (getattr(test.__class__, '_classSetupFailed', False) or 
26 +            if (getattr(test.__class__, '_classSetupFailed', False) or
27                  getattr(result, '_moduleSetUpFailed', False)):
28                  continue
29 
30 +        # --- modifications to deal with _wrapped_run ---
31 +        # original code is:
32 +        #
33 +        # if not debug:
34 +        #     test(result)
35 +        # else:
36 +        #     test.debug()
37          if hasattr(test, '_wrapped_run'):
38              try:
39                  test._wrapped_run(result, debug, runcondition=runcondition, options=options)
40              except TypeError:
41                  test._wrapped_run(result, debug)
@@ -1111,10 +1124,29 @@
42                  test(result, runcondition, options)
43              except TypeError:
44                  test(result)
45          else:
46              test.debug()
47 +        # --- end of modifications to deal with _wrapped_run ---
48 +    return result
49 +
50 +if sys.version_info >= (2, 7):
51 +    # The function below implements a modified version of the
52 +    # TestSuite.run method that is provided with python 2.7, in
53 +    # unittest/suite.py
54 +    def _ts_run(self, result, debug=False, runcondition=None, options=None):
55 +        topLevel = False
56 +        if getattr(result, '_testRunEntered', False) is False:
57 +            result._testRunEntered = topLevel = True
58 +
59 +        self._wrapped_run(result, debug, runcondition, options)
60 +
61 +        if topLevel:
62 +            self._tearDownPreviousClass(None, result)
63 +            self._handleModuleTearDown(result)
64 +            result._testRunEntered = False
65 +        return result
66 
67 
68  def enable_dbc(*args):
69      """
70      Without arguments, return True if contracts can be enabled and should be