Hello community, here is the log from the commit of package python-pytest-timeout for openSUSE:Factory checked in at 2018-07-18 22:55:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pytest-timeout (Old) and /work/SRC/openSUSE:Factory/.python-pytest-timeout.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest-timeout" Wed Jul 18 22:55:47 2018 rev:4 rq:623445 version:1.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pytest-timeout/python-pytest-timeout.changes 2017-12-08 12:58:38.778958512 +0100 +++ /work/SRC/openSUSE:Factory/.python-pytest-timeout.new/python-pytest-timeout.changes 2018-07-18 22:56:17.602492615 +0200 @@ -1,0 +2,7 @@ +Tue Jul 17 12:55:33 UTC 2018 - scarab...@opensuse.org + +- Version update to 1.3.0: + * Fixes for python3.7 + * Various small fixes + +------------------------------------------------------------------- Old: ---- pytest-timeout-1.2.1.tar.gz New: ---- pytest-timeout-1.3.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pytest-timeout.spec ++++++ --- /var/tmp/diff_new_pack.EMjBPA/_old 2018-07-18 22:56:18.382490028 +0200 +++ /var/tmp/diff_new_pack.EMjBPA/_new 2018-07-18 22:56:18.382490028 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-pytest-timeout # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,26 +19,24 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %bcond_without test Name: python-pytest-timeout -Version: 1.2.1 +Version: 1.3.0 Release: 0 Summary: Pytest plugin to abort hanging tests License: MIT Group: Development/Languages/Python -Url: http://bitbucket.org/pytest-dev/pytest-timeout/ +URL: http://bitbucket.org/pytest-dev/pytest-timeout/ Source: https://files.pythonhosted.org/packages/source/p/pytest-timeout/pytest-timeout-%{version}.tar.gz BuildRequires: %{python_module devel} BuildRequires: %{python_module setuptools} +BuildRequires: fdupes BuildRequires: python-rpm-macros +Requires: python-pexpect +Requires: python-pytest >= 3.6.0 +BuildArch: noarch %if %{with test} BuildRequires: %{python_module pexpect} -BuildRequires: %{python_module pytest >= 2.8.0} -BuildRequires: python3-tox +BuildRequires: %{python_module pytest >= 3.6.0} %endif -BuildRequires: fdupes -Requires: python-pexpect -Requires: python-pytest >= 2.8.0 -BuildArch: noarch - %python_subpackages %description @@ -81,8 +79,8 @@ %endif %files %{python_files} -%defattr(-,root,root,-) -%doc LICENSE README +%license LICENSE +%doc README %{python_sitelib}/pytest_timeout-%{version}-py*.egg-info %{python_sitelib}/pytest_timeout.py* %pycache_only %{python_sitelib}/__pycache__/pytest_timeout*.py* ++++++ pytest-timeout-1.2.1.tar.gz -> pytest-timeout-1.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-timeout-1.2.1/PKG-INFO new/pytest-timeout-1.3.0/PKG-INFO --- old/pytest-timeout-1.2.1/PKG-INFO 2017-11-28 22:24:20.000000000 +0100 +++ new/pytest-timeout-1.3.0/PKG-INFO 2018-06-13 23:10:37.000000000 +0200 @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: pytest-timeout -Version: 1.2.1 +Version: 1.3.0 Summary: py.test plugin to abort hanging tests Home-page: http://bitbucket.org/pytest-dev/pytest-timeout/ Author: Floris Bruynooghe Author-email: f...@devork.be License: MIT -Description-Content-Type: UNKNOWN Description: ============== pytest-timeout ============== @@ -186,6 +185,14 @@ Changelog ========= + 1.3.0 + ----- + + - Make it possible to only run the timeout timer on the test function + and not the whole fixture setup + test + teardown duration. Thanks + Pedro Algarvio for the work! + - Use the new pytest marker API, Thanks Pedro Algarvio for the work! + 1.2.1 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-timeout-1.2.1/README new/pytest-timeout-1.3.0/README --- old/pytest-timeout-1.2.1/README 2017-11-28 22:19:48.000000000 +0100 +++ new/pytest-timeout-1.3.0/README 2018-06-13 21:56:21.000000000 +0200 @@ -177,6 +177,14 @@ Changelog ========= +1.3.0 +----- + +- Make it possible to only run the timeout timer on the test function + and not the whole fixture setup + test + teardown duration. Thanks + Pedro Algarvio for the work! +- Use the new pytest marker API, Thanks Pedro Algarvio for the work! + 1.2.1 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-timeout-1.2.1/pytest_timeout.egg-info/PKG-INFO new/pytest-timeout-1.3.0/pytest_timeout.egg-info/PKG-INFO --- old/pytest-timeout-1.2.1/pytest_timeout.egg-info/PKG-INFO 2017-11-28 22:24:20.000000000 +0100 +++ new/pytest-timeout-1.3.0/pytest_timeout.egg-info/PKG-INFO 2018-06-13 23:10:37.000000000 +0200 @@ -1,12 +1,11 @@ Metadata-Version: 1.1 Name: pytest-timeout -Version: 1.2.1 +Version: 1.3.0 Summary: py.test plugin to abort hanging tests Home-page: http://bitbucket.org/pytest-dev/pytest-timeout/ Author: Floris Bruynooghe Author-email: f...@devork.be License: MIT -Description-Content-Type: UNKNOWN Description: ============== pytest-timeout ============== @@ -186,6 +185,14 @@ Changelog ========= + 1.3.0 + ----- + + - Make it possible to only run the timeout timer on the test function + and not the whole fixture setup + test + teardown duration. Thanks + Pedro Algarvio for the work! + - Use the new pytest marker API, Thanks Pedro Algarvio for the work! + 1.2.1 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-timeout-1.2.1/pytest_timeout.egg-info/requires.txt new/pytest-timeout-1.3.0/pytest_timeout.egg-info/requires.txt --- old/pytest-timeout-1.2.1/pytest_timeout.egg-info/requires.txt 2017-11-28 22:24:20.000000000 +0100 +++ new/pytest-timeout-1.3.0/pytest_timeout.egg-info/requires.txt 2018-06-13 23:10:37.000000000 +0200 @@ -1 +1 @@ -pytest>=2.8.0 +pytest>=3.6.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-timeout-1.2.1/pytest_timeout.py new/pytest-timeout-1.3.0/pytest_timeout.py --- old/pytest-timeout-1.2.1/pytest_timeout.py 2017-11-28 22:03:25.000000000 +0100 +++ new/pytest-timeout-1.3.0/pytest_timeout.py 2018-06-13 23:10:18.000000000 +0200 @@ -12,6 +12,7 @@ import sys import threading import traceback +from collections import namedtuple import py import pytest @@ -31,6 +32,13 @@ 'thread' uses a timer thread. The default is to use 'signal' and fall back to 'thread'. """.strip() +FUNC_ONLY_DESC = """ +When set to True, defers the timeout evaluation to only the test +function body, ignoring the time it takes when evaluating any fixtures +used in the test. +""".strip() + +Settings = namedtuple('Settings', ['timeout', 'method', 'func_only']) @pytest.hookimpl @@ -46,7 +54,7 @@ type='choice', action='store', choices=['signal', 'thread'], - help='Depreacted, use --timeout-method') + help='Deprecated, use --timeout-method') group.addoption('--timeout-method', dest='timeout_method', type='choice', @@ -55,6 +63,7 @@ help=METHOD_DESC) parser.addini('timeout', TIMEOUT_DESC) parser.addini('timeout_method', METHOD_DESC) + parser.addini('timeout_func_only', FUNC_ONLY_DESC, type='bool') @pytest.hookimpl @@ -62,26 +71,48 @@ # Register the marker so it shows up in --markers output. config.addinivalue_line( 'markers', - 'timeout(timeout, method=None): Set a timeout and timeout method on ' - 'just one test item. The first argument, *timeout*, is the timeout ' - 'in seconds while the keyword, *method*, takes the same values as the ' - '--timeout_method option.') - - config._env_timeout, config._env_timeout_method = get_env_timeout_and_method(config) + 'timeout(timeout, method=None, func_only=False): Set a timeout, timeout ' + 'method and func_only evaluation on just one test item. The first ' + 'argument, *timeout*, is the timeout in seconds while the keyword, ' + '*method*, takes the same values as the --timeout_method option. The ' + '*func_only* keyword, when set to True, defers the timeout evaluation ' + 'to only the test function body, ignoring the time it takes when ' + 'evaluating any fixrures used in the test.') + + settings = get_env_settings(config) + config._env_timeout = settings.timeout + config._env_timeout_method = settings.method + config._env_timeout_func_only = settings.func_only @pytest.hookimpl(hookwrapper=True) def pytest_runtest_protocol(item): - timeout_setup(item) + func_only = get_func_only_setting(item) + if func_only is False: + timeout_setup(item) + outcome = yield + if func_only is False: + timeout_teardown(item) + + +@pytest.hookimpl(hookwrapper=True) +def pytest_runtest_call(item): + func_only = get_func_only_setting(item) + if func_only is True: + timeout_setup(item) outcome = yield - timeout_teardown(item) + if func_only is True: + timeout_teardown(item) + @pytest.hookimpl(tryfirst=True) def pytest_report_header(config): if config._env_timeout: - return ["timeout: %ss method: %s" % - (config._env_timeout, config._env_timeout_method)] + return ["timeout: %ss\ntimeout method: %s\ntimeout func_only: %s" % + (config._env_timeout, + config._env_timeout_method, + config._env_timeout_func_only)] @pytest.hookimpl(tryfirst=True) @@ -101,21 +132,22 @@ def timeout_setup(item): """Setup up a timeout trigger and handler""" - timeout, method = get_params(item) - if timeout is None or timeout <= 0: + params = get_params(item) + if params.timeout is None or params.timeout <= 0: return - if method == 'signal': + if params.method == 'signal': def handler(signum, frame): __tracebackhide__ = True - timeout_sigalrm(item, timeout) + timeout_sigalrm(item, params.timeout) def cancel(): signal.setitimer(signal.ITIMER_REAL, 0) signal.signal(signal.SIGALRM, signal.SIG_DFL) item.cancel_timeout = cancel signal.signal(signal.SIGALRM, handler) - signal.setitimer(signal.ITIMER_REAL, timeout) - elif method == 'thread': - timer = threading.Timer(timeout, timeout_timer, (item, timeout)) + signal.setitimer(signal.ITIMER_REAL, params.timeout) + elif params.method == 'thread': + timer = threading.Timer(params.timeout, timeout_timer, + (item, params.timeout)) def cancel(): timer.cancel() timer.join() @@ -134,7 +166,7 @@ cancel() -def get_env_timeout_and_method(config): +def get_env_settings(config): timeout = config.getvalue('timeout') if timeout is None: timeout = _validate_timeout( @@ -152,21 +184,47 @@ method = _validate_method(ini, 'config file') if method is None: method = DEFAULT_METHOD - return timeout, method + + func_only = config.getini('timeout_func_only') + if func_only == []: + # No value set + func_only = None + if func_only is not None: + func_only = _validate_func_only(func_only, 'config file') + return Settings(timeout, method, func_only or False) + + +def get_func_only_setting(item): + """Return the func_only setting for an item""" + func_only = None + marker = item.get_closest_marker('timeout') + if marker: + settings = get_params(item, marker=marker) + func_only = _validate_func_only(settings.func_only, 'marker') + if func_only is None: + func_only = item.config._env_timeout_func_only + if func_only is None: + func_only = False + return func_only -def get_params(item): +def get_params(item, marker=None): """Return (timeout, method) for an item""" - timeout = method = None - if 'timeout' in item.keywords: - timeout, method = _parse_marker(item.keywords['timeout']) - timeout = _validate_timeout(timeout, 'marker') - method = _validate_method(method, 'marker') + timeout = method = func_only = None + if not marker: + marker = item.get_closest_marker('timeout') + if marker is not None: + settings = _parse_marker(item.get_closest_marker(name='timeout')) + timeout = _validate_timeout(settings.timeout, 'marker') + method = _validate_method(settings.method, 'marker') + func_only = _validate_func_only(settings.func_only, 'marker') if timeout is None: timeout = item.config._env_timeout if method is None: method = item.config._env_timeout_method - return timeout, method + if func_only is None: + func_only = item.config._env_timeout_func_only + return Settings(timeout, method, func_only) def _parse_marker(marker): @@ -177,12 +235,14 @@ """ if not marker.args and not marker.kwargs: raise TypeError('Timeout marker must have at least one argument') - timeout = method = NOTSET = object() + timeout = method = func_only = NOTSET = object() for kw, val in marker.kwargs.items(): if kw == 'timeout': timeout = val elif kw == 'method': method = val + elif kw == 'func_only': + func_only = val else: raise TypeError( 'Invalid keyword argument for timeout marker: %s' % kw) @@ -202,7 +262,9 @@ timeout = None if method is NOTSET: method = None - return timeout, method + if func_only is NOTSET: + func_only = None + return Settings(timeout, method, func_only) def _validate_timeout(timeout, where): @@ -224,6 +286,15 @@ return method +def _validate_func_only(func_only, where): + """Helper for get_params()""" + if func_only is None: + return False + if not isinstance(func_only, bool): + raise ValueError('Invalid func_only value %s from %s' % (func_only, where)) + return func_only + + def timeout_sigalrm(item, timeout): """Dump stack of threads and raise an exception diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-timeout-1.2.1/setup.py new/pytest-timeout-1.3.0/setup.py --- old/pytest-timeout-1.2.1/setup.py 2017-11-28 22:06:44.000000000 +0100 +++ new/pytest-timeout-1.3.0/setup.py 2018-06-13 20:36:29.000000000 +0200 @@ -5,14 +5,14 @@ name='pytest-timeout', description='py.test plugin to abort hanging tests', long_description=open("README").read(), - version='1.2.1', + version='1.3.0', author='Floris Bruynooghe', author_email='f...@devork.be', url='http://bitbucket.org/pytest-dev/pytest-timeout/', license='MIT', py_modules=['pytest_timeout'], entry_points={'pytest11': ['timeout = pytest_timeout']}, - install_requires=['pytest>=2.8.0'], + install_requires=['pytest>=3.6.0'], classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-timeout-1.2.1/test_pytest_timeout.py new/pytest-timeout-1.3.0/test_pytest_timeout.py --- old/pytest-timeout-1.2.1/test_pytest_timeout.py 2017-11-28 22:03:25.000000000 +0100 +++ new/pytest-timeout-1.3.0/test_pytest_timeout.py 2018-06-13 20:35:43.000000000 +0200 @@ -26,7 +26,9 @@ """) result = testdir.runpytest('--timeout=1') result.stdout.fnmatch_lines([ - 'timeout: 1.0s method:*' + 'timeout: 1.0s', + 'timeout method:*', + 'timeout func_only:*' ]) @@ -51,7 +53,7 @@ def test_foo(): time.sleep(2) """) - result = testdir.runpytest('--timeout=1', '--timeout_method=thread') + result = testdir.runpytest('--timeout=1', '--timeout-method=thread') result.stderr.fnmatch_lines([ '*++ Timeout ++*', '*~~ Stack of MainThread* ~~*', @@ -86,7 +88,7 @@ # pass # """) # result = testdir.runpytest('--timeout=1', -# '--timeout_method={0}'.format(meth)) +# '--timeout-method={0}'.format(meth)) # assert result.ret > 0 # assert 'Timeout' in result.stdout.str() + result.stderr.str() @@ -107,11 +109,30 @@ pass """.format(scope=scope)) result = testdir.runpytest('--timeout=1', - '--timeout_method={0}'.format(meth)) + '--timeout-method={0}'.format(meth)) assert result.ret > 0 assert 'Timeout' in result.stdout.str() + result.stderr.str() +def test_fix_setup_func_only(testdir): + testdir.makepyfile(""" + import time, pytest + + class TestFoo: + + @pytest.fixture + def fix(self): + time.sleep(2) + + @pytest.mark.timeout(func_only=True) + def test_foo(self, fix): + pass + """) + result = testdir.runpytest('--timeout=1') + assert result.ret == 0 + assert 'Timeout' not in result.stdout.str() + result.stderr.str() + + @pytest.mark.parametrize('meth', [have_sigalrm('signal'), 'thread']) @pytest.mark.parametrize('scope', ['function', 'class', 'module', 'session']) def test_fix_finalizer(meth, scope, testdir): @@ -120,7 +141,7 @@ class TestFoo: - @pytest.fixture(scope='{scope}') + @pytest.fixture def fix(self, request): print('fix setup') def fin(): @@ -130,13 +151,36 @@ def test_foo(self, fix): pass - """.format(scope=scope)) + """) result = testdir.runpytest('--timeout=1', '-s', - '--timeout_method={0}'.format(meth)) + '--timeout-method={0}'.format(meth)) assert result.ret > 0 assert 'Timeout' in result.stdout.str() + result.stderr.str() +def test_fix_finalizer_func_only(testdir): + testdir.makepyfile(""" + import time, pytest + + class TestFoo: + + @pytest.fixture + def fix(self, request): + print('fix setup') + def fin(): + print('fix finaliser') + time.sleep(2) + request.addfinalizer(fin) + + @pytest.mark.timeout(func_only=True) + def test_foo(self, fix): + pass + """) + result = testdir.runpytest('--timeout=1', '-s') + assert result.ret == 0 + assert 'Timeout' not in result.stdout.str() + result.stderr.str() + + @have_sigalrm def test_timeout_mark_sigalrm(testdir): testdir.makepyfile(""" @@ -159,7 +203,7 @@ def test_foo(): time.sleep(2) """) - result = testdir.runpytest('--timeout_method=thread') + result = testdir.runpytest('--timeout-method=thread') result.stderr.fnmatch_lines(['*++ Timeout ++*']) @@ -171,7 +215,7 @@ def test_foo(): time.sleep(1) """) - result = testdir.runpytest('--timeout_method=thread') + result = testdir.runpytest('--timeout-method=thread') result.stderr.fnmatch_lines(['*++ Timeout ++*']) @@ -238,6 +282,26 @@ assert result.ret +def test_ini_timeout_func_only(testdir): + testdir.makepyfile(""" + import time, pytest + + @pytest.fixture + def slow(): + time.sleep(2) + + def test_foo(slow): + pass + """) + testdir.makeini(""" + [pytest] + timeout = 1.5 + timeout_func_only = true + """) + result = testdir.runpytest() + assert result.ret == 0 + + def test_ini_method(testdir): testdir.makepyfile(""" import time @@ -254,6 +318,26 @@ assert '=== 1 failed in ' not in result.outlines[-1] +def test_timeout_marker_inheritance(testdir): + testdir.makepyfile(""" + import time, pytest + + @pytest.mark.timeout(timeout=2) + class TestFoo: + + @pytest.mark.timeout(timeout=3) + def test_foo_2(self): + time.sleep(2) + + @pytest.mark.timeout(timeout=3) + def test_foo_1(self): + time.sleep(1) + """) + result = testdir.runpytest('--timeout=1', '-s') + assert result.ret == 0 + assert 'Timeout' not in result.stdout.str() + result.stderr.str() + + def test_marker_help(testdir): result = testdir.runpytest('--markers') result.stdout.fnmatch_lines(['@pytest.mark.timeout(*'])