Merge pull request #4420 from blueyed/merge-master
Merge master into features
This commit is contained in:
commit
6e85febf20
|
@ -0,0 +1 @@
|
|||
Rearrange warning handling for the yield test errors so the opt-out in 4.0.x correctly works.
|
|
@ -0,0 +1 @@
|
|||
Fix collection of testpaths with ``--pyargs``.
|
|
@ -0,0 +1 @@
|
|||
Fix assertion rewriting involving ``Starred`` + side-effects.
|
10
setup.py
10
setup.py
|
@ -29,6 +29,16 @@ def main():
|
|||
use_scm_version={"write_to": "src/_pytest/_version.py"},
|
||||
setup_requires=["setuptools-scm", "setuptools>=40.0"],
|
||||
package_dir={"": "src"},
|
||||
# fmt: off
|
||||
extras_require={
|
||||
"testing": [
|
||||
"hypothesis>=3.56",
|
||||
"nose",
|
||||
"requests",
|
||||
"mock;python_version=='2.7'",
|
||||
],
|
||||
},
|
||||
# fmt: on
|
||||
install_requires=INSTALL_REQUIRES,
|
||||
)
|
||||
|
||||
|
|
|
@ -946,7 +946,8 @@ class AssertionRewriter(ast.NodeVisitor):
|
|||
def visit_Starred(self, starred):
|
||||
# From Python 3.5, a Starred node can appear in a function call
|
||||
res, expl = self.visit(starred.value)
|
||||
return starred, "*" + expl
|
||||
new_starred = ast.Starred(res, starred.ctx)
|
||||
return new_starred, "*" + expl
|
||||
|
||||
def visit_Call_legacy(self, call):
|
||||
"""
|
||||
|
|
|
@ -852,10 +852,7 @@ class Config(object):
|
|||
)
|
||||
if not args:
|
||||
if self.invocation_dir == self.rootdir:
|
||||
args = [
|
||||
str(self.invocation_dir.join(x, abs=True))
|
||||
for x in self.getini("testpaths")
|
||||
]
|
||||
args = self.getini("testpaths")
|
||||
if not args:
|
||||
args = [str(self.invocation_dir)]
|
||||
self.args = args
|
||||
|
|
|
@ -518,6 +518,9 @@ class Testdir(object):
|
|||
def __repr__(self):
|
||||
return "<Testdir %r>" % (self.tmpdir,)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.tmpdir)
|
||||
|
||||
def finalize(self):
|
||||
"""Clean up global state artifacts.
|
||||
|
||||
|
|
|
@ -741,16 +741,20 @@ class FunctionMixin(PyobjMixin):
|
|||
|
||||
class Generator(FunctionMixin, PyCollector):
|
||||
def collect(self):
|
||||
|
||||
# test generators are seen as collectors but they also
|
||||
# invoke setup/teardown on popular request
|
||||
# (induced by the common "test_*" naming shared with normal tests)
|
||||
from _pytest import deprecated
|
||||
|
||||
self.warn(deprecated.YIELD_TESTS)
|
||||
|
||||
self.session._setupstate.prepare(self)
|
||||
# see FunctionMixin.setup and test_setupstate_is_preserved_134
|
||||
self._preservedparent = self.parent.obj
|
||||
values = []
|
||||
seen = {}
|
||||
_Function = self._getcustomclass("Function")
|
||||
for i, x in enumerate(self.obj()):
|
||||
name, call, args = self.getcallargs(x)
|
||||
if not callable(call):
|
||||
|
@ -764,11 +768,7 @@ class Generator(FunctionMixin, PyCollector):
|
|||
"%r generated tests with non-unique name %r" % (self, name)
|
||||
)
|
||||
seen[name] = True
|
||||
with warnings.catch_warnings():
|
||||
# ignore our own deprecation warning
|
||||
function_class = self.Function
|
||||
values.append(function_class(name, self, args=args, callobj=call))
|
||||
self.warn(deprecated.YIELD_TESTS)
|
||||
values.append(_Function(name, self, args=args, callobj=call))
|
||||
return values
|
||||
|
||||
def getcallargs(self, obj):
|
||||
|
|
|
@ -413,6 +413,19 @@ class TestAssertionRewrite(object):
|
|||
)
|
||||
testdir.runpytest().assert_outcomes(passed=1)
|
||||
|
||||
@pytest.mark.skipif("sys.version_info < (3,5)")
|
||||
def test_starred_with_side_effect(self, testdir):
|
||||
"""See #4412"""
|
||||
testdir.makepyfile(
|
||||
"""\
|
||||
def test():
|
||||
f = lambda x: x
|
||||
x = iter([1, 2, 3])
|
||||
assert 2 * next(x) == f(*[next(x)])
|
||||
"""
|
||||
)
|
||||
testdir.runpytest().assert_outcomes(passed=1)
|
||||
|
||||
def test_call(self):
|
||||
def g(a=42, *args, **kwargs):
|
||||
return False
|
||||
|
|
|
@ -1086,6 +1086,28 @@ def test_collect_with_chdir_during_import(testdir):
|
|||
result.stdout.fnmatch_lines(["collected 1 item"])
|
||||
|
||||
|
||||
def test_collect_pyargs_with_testpaths(testdir, monkeypatch):
|
||||
testmod = testdir.mkdir("testmod")
|
||||
# NOTE: __init__.py is not collected since it does not match python_files.
|
||||
testmod.ensure("__init__.py").write("def test_func(): pass")
|
||||
testmod.ensure("test_file.py").write("def test_func(): pass")
|
||||
|
||||
root = testdir.mkdir("root")
|
||||
root.ensure("pytest.ini").write(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
[pytest]
|
||||
addopts = --pyargs
|
||||
testpaths = testmod
|
||||
"""
|
||||
)
|
||||
)
|
||||
monkeypatch.setenv("PYTHONPATH", str(testdir.tmpdir))
|
||||
with root.as_cwd():
|
||||
result = testdir.runpytest_subprocess()
|
||||
result.stdout.fnmatch_lines(["*1 passed in*"])
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not hasattr(py.path.local, "mksymlinkto"),
|
||||
reason="symlink not available on this platform",
|
||||
|
|
|
@ -4,6 +4,7 @@ from __future__ import print_function
|
|||
|
||||
import pytest
|
||||
from _pytest.main import EXIT_NOTESTSCOLLECTED
|
||||
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
|
||||
|
||||
|
||||
class SessionTests(object):
|
||||
|
@ -77,7 +78,8 @@ class SessionTests(object):
|
|||
"""
|
||||
def test_1():
|
||||
yield None
|
||||
"""
|
||||
""",
|
||||
SHOW_PYTEST_WARNINGS_ARG,
|
||||
)
|
||||
failures = reprec.getfailedcollections()
|
||||
out = failures[0].longrepr.reprcrash.message
|
||||
|
|
20
tox.ini
20
tox.ini
|
@ -28,11 +28,8 @@ setenv =
|
|||
coverage: _PYTEST_TOX_EXTRA_DEP=coverage-enable-subprocess
|
||||
coverage: COVERAGE_FILE={toxinidir}/.coverage
|
||||
coverage: COVERAGE_PROCESS_START={toxinidir}/.coveragerc
|
||||
extras = testing
|
||||
deps =
|
||||
hypothesis>=3.56
|
||||
nose
|
||||
{py27,pypy}: mock
|
||||
requests
|
||||
{env:_PYTEST_TOX_EXTRA_DEP:}
|
||||
|
||||
[testenv:py27-subprocess]
|
||||
|
@ -51,22 +48,18 @@ deps = pre-commit>=1.11.0
|
|||
commands = pre-commit run --all-files --show-diff-on-failure
|
||||
|
||||
[testenv:py27-xdist]
|
||||
extras = testing
|
||||
deps =
|
||||
pytest-xdist>=1.13
|
||||
{py27,pypy}: mock
|
||||
nose
|
||||
hypothesis>=3.56
|
||||
{env:_PYTEST_TOX_EXTRA_DEP:}
|
||||
commands =
|
||||
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest -n auto {posargs}
|
||||
|
||||
[testenv:py37-xdist]
|
||||
# NOTE: copied from above due to https://github.com/tox-dev/tox/issues/706.
|
||||
extras = testing
|
||||
deps =
|
||||
pytest-xdist>=1.13
|
||||
{py27,pypy}: mock
|
||||
nose
|
||||
hypothesis>=3.56
|
||||
{env:_PYTEST_TOX_EXTRA_DEP:}
|
||||
commands = {[testenv:py27-xdist]commands}
|
||||
|
||||
|
@ -76,7 +69,7 @@ deps =
|
|||
pexpect
|
||||
{env:_PYTEST_TOX_EXTRA_DEP:}
|
||||
commands =
|
||||
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest testing/test_pdb.py testing/test_terminal.py testing/test_unittest.py {posargs}
|
||||
{env:_PYTEST_TOX_COVERAGE_RUN:} pytest {posargs:testing/test_pdb.py testing/test_terminal.py testing/test_unittest.py}
|
||||
|
||||
[testenv:py37-pexpect]
|
||||
platform = {[testenv:py27-pexpect]platform}
|
||||
|
@ -84,10 +77,9 @@ deps = {[testenv:py27-pexpect]deps}
|
|||
commands = {[testenv:py27-pexpect]commands}
|
||||
|
||||
[testenv:py27-nobyte]
|
||||
extras = testing
|
||||
deps =
|
||||
pytest-xdist>=1.13
|
||||
hypothesis>=3.56
|
||||
py27: mock
|
||||
{env:_PYTEST_TOX_EXTRA_DEP:}
|
||||
distribute = true
|
||||
setenv =
|
||||
|
@ -219,6 +211,8 @@ filterwarnings =
|
|||
ignore:.*inspect.getargspec.*deprecated, use inspect.signature.*:DeprecationWarning
|
||||
# pytest's own futurewarnings
|
||||
ignore::pytest.PytestExperimentalApiWarning
|
||||
# Do not cause SyntaxError for invalid escape sequences in py37.
|
||||
default:invalid escape sequence:DeprecationWarning
|
||||
pytester_example_dir = testing/example_scripts
|
||||
[flake8]
|
||||
max-line-length = 120
|
||||
|
|
Loading…
Reference in New Issue