Fixed race condition with SkipTest when module not in sys.modules on collection.
This commit is contained in:
		
							parent
							
								
									f5b992f68a
								
							
						
					
					
						commit
						94b1ce65c6
					
				| 
						 | 
					@ -408,10 +408,6 @@ class Collector(Node):
 | 
				
			||||||
        and thus iteratively build a tree.
 | 
					        and thus iteratively build a tree.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # the set of exceptions to interpret as "Skip the whole module" during
 | 
					 | 
				
			||||||
    # collection
 | 
					 | 
				
			||||||
    skip_exceptions = (Skipped,)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class CollectError(Exception):
 | 
					    class CollectError(Exception):
 | 
				
			||||||
        """ an error during collection, contains a custom message. """
 | 
					        """ an error during collection, contains a custom message. """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,32 @@
 | 
				
			||||||
""" run test suites written for nose. """
 | 
					""" run test suites written for nose. """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import pytest, py
 | 
					 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import py
 | 
				
			||||||
 | 
					import pytest
 | 
				
			||||||
from _pytest import unittest
 | 
					from _pytest import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_skip_exceptions():
 | 
				
			||||||
 | 
					    skip_classes = set()
 | 
				
			||||||
 | 
					    for module_name in ('unittest', 'unittest2', 'nose'):
 | 
				
			||||||
 | 
					        mod = sys.modules.get(module_name)
 | 
				
			||||||
 | 
					        if hasattr(mod, 'SkipTest'):
 | 
				
			||||||
 | 
					            skip_classes.add(mod.SkipTest)
 | 
				
			||||||
 | 
					    return tuple(skip_classes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_runtest_makereport(__multicall__, item, call):
 | 
					def pytest_runtest_makereport(__multicall__, item, call):
 | 
				
			||||||
    SkipTest = getattr(sys.modules.get('nose', None), 'SkipTest', None)
 | 
					    if not call.excinfo:
 | 
				
			||||||
    if SkipTest:
 | 
					        return
 | 
				
			||||||
        if call.excinfo and call.excinfo.errisinstance(SkipTest):
 | 
					
 | 
				
			||||||
 | 
					    for skip_exc in get_skip_exceptions():
 | 
				
			||||||
 | 
					        if call.excinfo.errisinstance(skip_exc):
 | 
				
			||||||
            # let's substitute the excinfo with a pytest.skip one
 | 
					            # let's substitute the excinfo with a pytest.skip one
 | 
				
			||||||
            call2 = call.__class__(lambda:
 | 
					            call2 = call.__class__(lambda:
 | 
				
			||||||
                        pytest.skip(str(call.excinfo.value)), call.when)
 | 
					                        pytest.skip(str(call.excinfo.value)), call.when)
 | 
				
			||||||
            call.excinfo = call2.excinfo
 | 
					            call.excinfo = call2.excinfo
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.mark.trylast
 | 
					@pytest.mark.trylast
 | 
				
			||||||
| 
						 | 
					@ -38,13 +53,8 @@ def teardown_nose(item):
 | 
				
			||||||
        #    #call_optional(item._nosegensetup, 'teardown')
 | 
					        #    #call_optional(item._nosegensetup, 'teardown')
 | 
				
			||||||
        #    del item.parent._nosegensetup
 | 
					        #    del item.parent._nosegensetup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_make_collect_report(collector):
 | 
					def pytest_make_collect_report(collector):
 | 
				
			||||||
    SkipTest = getattr(sys.modules.get('unittest', None), 'SkipTest', None)
 | 
					 | 
				
			||||||
    if SkipTest is not None:
 | 
					 | 
				
			||||||
        collector.skip_exceptions += (SkipTest,)
 | 
					 | 
				
			||||||
    SkipTest = getattr(sys.modules.get('nose', None), 'SkipTest', None)
 | 
					 | 
				
			||||||
    if SkipTest is not None:
 | 
					 | 
				
			||||||
        collector.skip_exceptions += (SkipTest,)
 | 
					 | 
				
			||||||
    if isinstance(collector, pytest.Generator):
 | 
					    if isinstance(collector, pytest.Generator):
 | 
				
			||||||
        call_optional(collector.obj, 'setup')
 | 
					        call_optional(collector.obj, 'setup')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -267,7 +267,9 @@ def pytest_make_collect_report(collector):
 | 
				
			||||||
    if not call.excinfo:
 | 
					    if not call.excinfo:
 | 
				
			||||||
        outcome = "passed"
 | 
					        outcome = "passed"
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        if call.excinfo.errisinstance(collector.skip_exceptions):
 | 
					        from _pytest import nose
 | 
				
			||||||
 | 
					        skip_exceptions = (Skipped,) + nose.get_skip_exceptions()
 | 
				
			||||||
 | 
					        if call.excinfo.errisinstance(skip_exceptions):
 | 
				
			||||||
            outcome = "skipped"
 | 
					            outcome = "skipped"
 | 
				
			||||||
            r = collector._repr_failure_py(call.excinfo, "line").reprcrash
 | 
					            r = collector._repr_failure_py(call.excinfo, "line").reprcrash
 | 
				
			||||||
            longrepr = (str(r.path), r.lineno, r.message)
 | 
					            longrepr = (str(r.path), r.lineno, r.message)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -330,12 +330,26 @@ def test_setup_teardown_linking_issue265(testdir):
 | 
				
			||||||
    reprec = testdir.inline_run()
 | 
					    reprec = testdir.inline_run()
 | 
				
			||||||
    reprec.assertoutcome(passed=1, skipped=1)
 | 
					    reprec.assertoutcome(passed=1, skipped=1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_SkipTest_during_collection(testdir):
 | 
					def test_SkipTest_during_collection(testdir):
 | 
				
			||||||
    testdir.makepyfile("""
 | 
					    p = testdir.makepyfile("""
 | 
				
			||||||
        import nose
 | 
					        import nose
 | 
				
			||||||
        raise nose.SkipTest("during collection")
 | 
					        raise nose.SkipTest("during collection")
 | 
				
			||||||
        def test_failing():
 | 
					        def test_failing():
 | 
				
			||||||
            assert False
 | 
					            assert False
 | 
				
			||||||
        """)
 | 
					        """)
 | 
				
			||||||
 | 
					    result = testdir.runpytest(p)
 | 
				
			||||||
 | 
					    outcome = result.parseoutcomes()
 | 
				
			||||||
 | 
					    outcome.pop('seconds')
 | 
				
			||||||
 | 
					    assert outcome == dict(skipped=1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_SkipTest_in_test(testdir):
 | 
				
			||||||
 | 
					    testdir.makepyfile("""
 | 
				
			||||||
 | 
					        import nose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def test_skipping():
 | 
				
			||||||
 | 
					            raise nose.SkipTest("in test")
 | 
				
			||||||
 | 
					        """)
 | 
				
			||||||
    reprec = testdir.inline_run()
 | 
					    reprec = testdir.inline_run()
 | 
				
			||||||
    reprec.assertoutcome(skipped=1)
 | 
					    reprec.assertoutcome(skipped=1)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue