Skip to content

Commit

Permalink
Merge pull request #4420 from blueyed/merge-master
Browse files Browse the repository at this point in the history
Merge master into features
  • Loading branch information
blueyed authored Nov 19, 2018
2 parents 62967b3 + 2754a13 commit 6e85feb
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 24 deletions.
1 change: 1 addition & 0 deletions changelog/4400.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Rearrange warning handling for the yield test errors so the opt-out in 4.0.x correctly works.
1 change: 1 addition & 0 deletions changelog/4405.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix collection of testpaths with ``--pyargs``.
1 change: 1 addition & 0 deletions changelog/4412.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix assertion rewriting involving ``Starred`` + side-effects.
10 changes: 10 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)

Expand Down
3 changes: 2 additions & 1 deletion src/_pytest/assertion/rewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,8 @@ def visit_Call_35(self, call):
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):
"""
Expand Down
5 changes: 1 addition & 4 deletions src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -852,10 +852,7 @@ def parse(self, args, addopts=True):
)
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
Expand Down
3 changes: 3 additions & 0 deletions src/_pytest/pytester.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,9 @@ def __init__(self, request, tmpdir_factory):
def __repr__(self):
return "<Testdir %r>" % (self.tmpdir,)

def __str__(self):
return str(self.tmpdir)

def finalize(self):
"""Clean up global state artifacts.
Expand Down
10 changes: 5 additions & 5 deletions src/_pytest/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -741,16 +741,20 @@ def repr_failure(self, excinfo, outerr=None):

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):
Expand All @@ -764,11 +768,7 @@ def collect(self):
"%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):
Expand Down
13 changes: 13 additions & 0 deletions testing/test_assertrewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,19 @@ def test_multmat_operator():
)
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
Expand Down
22 changes: 22 additions & 0 deletions testing/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,28 @@ def test_1():
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",
Expand Down
4 changes: 3 additions & 1 deletion testing/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import pytest
from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG


class SessionTests(object):
Expand Down Expand Up @@ -77,7 +78,8 @@ def test_generator_yields_None(self, testdir):
"""
def test_1():
yield None
"""
""",
SHOW_PYTEST_WARNINGS_ARG,
)
failures = reprec.getfailedcollections()
out = failures[0].longrepr.reprcrash.message
Expand Down
20 changes: 7 additions & 13 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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}

Expand All @@ -76,18 +69,17 @@ 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}
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 =
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 6e85feb

Please sign in to comment.