Commit ae3a344e authored by Scott Talbert's avatar Scott Talbert

New upstream version 1.24.1

parent 51f73550
......@@ -21,24 +21,26 @@ env:
- TOXENV=py-pytest31
- TOXENV=py-pytest32
- TOXENV=py-pytest33
- TOXENV=py-pytest36
- TOXENV=py-pytest38
install: pip install tox setuptools_scm
script: tox
stages:
- linting
- baseline
- test
- name: deploy
if: repo = pytest-dev/pytest-xdist AND tag IS present
jobs:
include:
- stage: linting
- stage: baseline
python: '3.6'
script:
- tox -e linting
env: TOXENV=linting
- python: '3.6'
env: TOXENV=py36-pytestlatest
- python: '2.7'
env: TOXENV=py27-pytestlatest
- stage: test
# python x env above are already included into this stage
- python: "2.7"
......
pytest-xdist 1.24.1 (2018-11-09)
================================
Bug Fixes
---------
- `#349 <https://github.com/pytest-dev/pytest-xdist/issues/349>`_: Correctly handle warnings created with arguments that can't be serialized during the transfer from workers to master node.
pytest-xdist 1.24.0 (2018-10-18)
================================
......
Metadata-Version: 1.2
Name: pytest-xdist
Version: 1.24.0
Version: 1.24.1
Summary: pytest xdist plugin for distributed testing and loop-on-failing modes
Home-page: https://github.com/pytest-dev/pytest-xdist
Author: holger krekel and contributors
......
......@@ -5,8 +5,7 @@ environment:
- TOXENV: "py34-pytest33"
- TOXENV: "py35-pytest33"
- TOXENV: "py36-pytest33"
- TOXENV: "py36-pytest36"
- TOXENV: "py36-pytest38"
- TOXENV: "py36-pytestlatest"
- TOXENV: "py27-pytest33-pexpect"
- TOXENV: "py36-pytest33-pexpect"
......
......@@ -400,64 +400,6 @@ class TestTerminalReporting:
]
)
@pytest.mark.parametrize("n", ["-n0", "-n1"])
@pytest.mark.parametrize("warn_type", ["pytest", "builtin"])
def test_warnings(self, testdir, n, warn_type):
from pkg_resources import parse_version
if parse_version(pytest.__version__) < parse_version("3.1"):
pytest.skip("pytest warnings requires >= 3.1")
if warn_type == "builtin":
warn_code = """warnings.warn(UserWarning('this is a warning'))"""
elif warn_type == "pytest":
warn_code = """request.config.warn('', 'this is a warning',
fslocation=py.path.local())"""
else:
assert False
testdir.makepyfile(
"""
import warnings, py, pytest
@pytest.mark.filterwarnings('ignore:config.warn has been deprecated')
def test_func(request):
{warn_code}
""".format(
warn_code=warn_code
)
)
result = testdir.runpytest(n)
result.stdout.fnmatch_lines(["*this is a warning*", "*1 passed, 1 warnings*"])
@pytest.mark.parametrize("n", ["-n0", "-n1"])
def test_custom_subclass(self, testdir, n):
"""Check that warning subclasses that don't honor the args attribute don't break
pytest-xdist (#344)
"""
from pkg_resources import parse_version
if parse_version(pytest.__version__) < parse_version("3.1"):
pytest.skip("pytest warnings requires >= 3.1")
testdir.makepyfile(
"""
import warnings, py, pytest
class MyWarning(UserWarning):
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
self.args = ()
def test_func(request):
warnings.warn(MyWarning("foo", 1))
"""
)
testdir.syspathinsert()
result = testdir.runpytest(n)
result.stdout.fnmatch_lines(["*MyWarning*", "*1 passed, 1 warnings*"])
def test_logfinish_hook(self, testdir):
"""Ensure the pytest_runtest_logfinish hook is being properly handled"""
from _pytest import hookspec
......@@ -765,6 +707,83 @@ def test_sub_plugins_disabled(testdir, plugin):
result.stdout.fnmatch_lines("*1 passed*")
class TestWarnings:
@pytest.fixture(autouse=True)
def skip_if_unsupported_pytest_version(self):
"""Skip tests of this class if we are running in a pytest version which does not
support warnings yet.
"""
from pkg_resources import parse_version
if parse_version(pytest.__version__) < parse_version("3.1"):
pytest.skip("pytest warnings requires >= 3.1")
@pytest.mark.parametrize("n", ["-n0", "-n1"])
@pytest.mark.parametrize("warn_type", ["pytest", "builtin"])
def test_warnings(self, testdir, n, warn_type):
if warn_type == "builtin":
warn_code = """warnings.warn(UserWarning('this is a warning'))"""
elif warn_type == "pytest":
warn_code = """request.config.warn('', 'this is a warning',
fslocation=py.path.local())"""
else:
assert False
testdir.makepyfile(
"""
import warnings, py, pytest
@pytest.mark.filterwarnings('ignore:config.warn has been deprecated')
def test_func(request):
{warn_code}
""".format(
warn_code=warn_code
)
)
result = testdir.runpytest(n)
result.stdout.fnmatch_lines(["*this is a warning*", "*1 passed, 1 warnings*"])
@pytest.mark.parametrize("n", ["-n0", "-n1"])
def test_custom_subclass(self, testdir, n):
"""Check that warning subclasses that don't honor the args attribute don't break
pytest-xdist (#344)
"""
testdir.makepyfile(
"""
import warnings, py, pytest
class MyWarning(UserWarning):
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
self.args = ()
def test_func(request):
warnings.warn(MyWarning("foo", 1))
"""
)
testdir.syspathinsert()
result = testdir.runpytest(n)
result.stdout.fnmatch_lines(["*MyWarning*", "*1 passed, 1 warnings*"])
@pytest.mark.parametrize("n", ["-n0", "-n1"])
def test_unserializable_arguments(self, testdir, n):
"""Check that warnings with unserializable arguments are handled correctly (#349)."""
testdir.makepyfile(
"""
import warnings, pytest
def test_func(tmpdir):
fn = (tmpdir / 'foo.txt').ensure(file=1)
with fn.open('r') as f:
warnings.warn(UserWarning("foo", f))
"""
)
testdir.syspathinsert()
result = testdir.runpytest(n)
result.stdout.fnmatch_lines(["*UserWarning*foo.txt*", "*1 passed, 1 warnings*"])
class TestNodeFailure:
def test_load_single(self, testdir):
f = testdir.makepyfile(
......
......@@ -2,7 +2,7 @@
# if you change the envlist, please update .travis.yml file as well
envlist=
linting
py{27,34,35,36}-pytest{30,31,32,33,36,38}
py{27,34,35,36}-pytest{30,31,32,33,latest}
py{27,36}-pytest36-pexpect
py{27,36}-pytest{master,features}
......@@ -18,8 +18,7 @@ deps =
pytest31: pytest~=3.1.0
pytest32: pytest~=3.2.0
pytest33: pytest~=3.3.0
pytest36: pytest~=3.6.0
pytest38: pytest~=3.8.0
pytestlatest: pytest
pytestmaster: git+https://github.com/pytest-dev/pytest.git@master
pytestfeatures: git+https://github.com/pytest-dev/pytest.git@features
pexpect: pexpect
......@@ -27,8 +26,6 @@ deps =
platform=
pexpect: linux|darwin
commands=
# always clean to avoid code unmarshal mismatch on old python/pytest
py.cleanup -aq
pytest {posargs}
[testenv:linting]
......
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
version = '1.24.0'
version = '1.24.1'
......@@ -12,6 +12,7 @@ import time
import _pytest.hookspec
import pytest
from execnet.gateway_base import dumps, DumpError
class WorkerInteractor(object):
......@@ -181,8 +182,15 @@ def serialize_warning_message(warning_message):
if isinstance(warning_message.message, Warning):
message_module = type(warning_message.message).__module__
message_class_name = type(warning_message.message).__name__
message_args = warning_message.message.args
message_str = str(warning_message.message)
# check now if we can serialize the warning arguments (#349)
# if not, we will just use the exception message on the master node
try:
dumps(warning_message.message.args)
except DumpError:
message_args = None
else:
message_args = warning_message.message.args
else:
message_str = warning_message.message
message_module = None
......
from xdist.scheduler.each import EachScheduling # noqa
from xdist.scheduler.load import LoadScheduling # noqa
from xdist.scheduler.loadfile import LoadFileScheduling # noqa
from xdist.scheduler.loadscope import LoadScopeScheduling # noqa
from xdist.scheduler.filescope import LoadFileScheduling # noqa
from . import LoadScopeScheduling
from .loadscope import LoadScopeScheduling
from py.log import Producer
......
......@@ -426,9 +426,16 @@ def unserialize_warning_message(data):
if data["message_module"]:
mod = importlib.import_module(data["message_module"])
cls = getattr(mod, data["message_class_name"])
try:
message = cls(*data["message_args"])
except TypeError:
message = None
if data["message_args"] is not None:
try:
message = cls(*data["message_args"])
except TypeError:
pass
if message is None:
# could not recreate the original warning instance;
# create a generic Warning instance with the original
# message at least
message_text = "{mod}.{cls}: {msg}".format(
mod=data["message_module"],
cls=data["message_class_name"],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment