Skip to content

Commit 4c56c95

Browse files
Merge pull request #1714 from nicoddemus/deprecate-yield-tests-funcarg-prefix
Deprecate yield tests funcarg prefix
2 parents 6f68dfc + 458ecae commit 4c56c95

24 files changed

+284
-108
lines changed

CHANGELOG.rst

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
2])`` only ran once. Now a failure is raised. Fixes `#460`_. Thanks to
4141
`@nikratio`_ for bug report, `@RedBeardCode`_ and `@tomviner`_ for PR.
4242

43-
*
43+
* ``_pytest.monkeypatch.monkeypatch`` class has been renamed to ``_pytest.monkeypatch.MonkeyPatch``
44+
so it doesn't conflict with the ``monkeypatch`` fixture.
4445

4546
*
4647

@@ -185,9 +186,12 @@
185186
Before, you only got exceptions later from ``argparse`` library,
186187
giving no clue about the actual reason for double-added options.
187188

188-
*
189+
* ``yield``-based tests are considered deprecated and will be removed in pytest-4.0.
190+
Thanks `@nicoddemus`_ for the PR.
189191

190-
*
192+
* Using ``pytest_funcarg__`` prefix to declare fixtures is considered deprecated and will be
193+
removed in pytest-4.0 (`#1684`_).
194+
Thanks `@nicoddemus`_ for the PR.
191195

192196
*
193197

@@ -261,6 +265,7 @@
261265
.. _#1632: https://github.com/pytest-dev/pytest/issues/1632
262266
.. _#1633: https://github.com/pytest-dev/pytest/pull/1633
263267
.. _#1664: https://github.com/pytest-dev/pytest/pull/1664
268+
.. _#1684: https://github.com/pytest-dev/pytest/pull/1684
264269

265270
.. _@DRMacIver: https://github.com/DRMacIver
266271
.. _@RedBeardCode: https://github.com/RedBeardCode

_pytest/assertion/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import sys
77

88
from _pytest.config import hookimpl
9-
from _pytest.monkeypatch import monkeypatch
9+
from _pytest.monkeypatch import MonkeyPatch
1010
from _pytest.assertion import util
1111

1212

@@ -56,7 +56,7 @@ def pytest_load_initial_conftests(early_config, parser, args):
5656

5757
if mode != "plain":
5858
_load_modules(mode)
59-
m = monkeypatch()
59+
m = MonkeyPatch()
6060
early_config._cleanup.append(m.undo)
6161
m.setattr(py.builtin.builtins, 'AssertionError',
6262
reinterpret.AssertionError) # noqa

_pytest/fixtures.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,10 @@ def yield_fixture(scope="function", params=None, autouse=False, ids=None, name=N
865865
return FixtureFunctionMarker(scope, params, autouse, ids=ids, name=name)
866866

867867
defaultfuncargprefixmarker = fixture()
868+
funcarg_prefix_warning = '{name}: declaring fixtures using "pytest_funcarg__" prefix is deprecated ' \
869+
'and scheduled to be removed in pytest 4.0.\n' \
870+
'remove the prefix and use the @pytest.fixture decorator instead'
871+
868872

869873

870874
@fixture(scope="session")
@@ -1042,6 +1046,7 @@ def parsefactories(self, node_or_obj, nodeid=NOTSET, unittest=False):
10421046
if not callable(obj):
10431047
continue
10441048
marker = defaultfuncargprefixmarker
1049+
self.config.warn('C1', funcarg_prefix_warning.format(name=name))
10451050
name = name[len(self._argprefix):]
10461051
elif not isinstance(marker, FixtureFunctionMarker):
10471052
# magic globals with __getattr__ might have got us a wrong
@@ -1050,7 +1055,9 @@ def parsefactories(self, node_or_obj, nodeid=NOTSET, unittest=False):
10501055
else:
10511056
if marker.name:
10521057
name = marker.name
1053-
assert not name.startswith(self._argprefix), name
1058+
msg = 'fixtures cannot have "pytest_funcarg__" prefix ' \
1059+
'and be decorated with @pytest.fixture:\n%s' % name
1060+
assert not name.startswith(self._argprefix), msg
10541061
fixturedef = FixtureDef(self, nodeid, name, obj,
10551062
marker.scope, marker.params,
10561063
unittest=unittest, ids=marker.ids)

_pytest/monkeypatch.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55

66
from py.builtin import _basestring
77

8+
import pytest
9+
810
RE_IMPORT_ERROR_NAME = re.compile("^No module named (.*)$")
911

1012

11-
def pytest_funcarg__monkeypatch(request):
12-
"""The returned ``monkeypatch`` funcarg provides these
13+
@pytest.fixture
14+
def monkeypatch(request):
15+
"""The returned ``monkeypatch`` fixture provides these
1316
helper methods to modify objects, dictionaries or os.environ::
1417
1518
monkeypatch.setattr(obj, name, value, raising=True)
@@ -26,7 +29,7 @@ def pytest_funcarg__monkeypatch(request):
2629
parameter determines if a KeyError or AttributeError
2730
will be raised if the set/deletion operation has no target.
2831
"""
29-
mpatch = monkeypatch()
32+
mpatch = MonkeyPatch()
3033
request.addfinalizer(mpatch.undo)
3134
return mpatch
3235

@@ -93,7 +96,7 @@ def __repr__(self):
9396
notset = Notset()
9497

9598

96-
class monkeypatch:
99+
class MonkeyPatch:
97100
""" Object keeping a record of setattr/item/env/syspath changes. """
98101

99102
def __init__(self):

_pytest/pytester.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,8 @@ def linecomp(request):
321321
return LineComp()
322322

323323

324-
def pytest_funcarg__LineMatcher(request):
324+
@pytest.fixture(name='LineMatcher')
325+
def LineMatcher_fixture(request):
325326
return LineMatcher
326327

327328

_pytest/python.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,8 @@ def collect(self):
589589
raise ValueError("%r generated tests with non-unique name %r" %(self, name))
590590
seen[name] = True
591591
l.append(self.Function(name, self, args=args, callobj=call))
592+
msg = 'yield tests are deprecated, and scheduled to be removed in pytest 4.0'
593+
self.config.warn('C1', msg, fslocation=self.fspath)
592594
return l
593595

594596
def getcallargs(self, obj):
@@ -611,8 +613,6 @@ def hasinit(obj):
611613
return True
612614

613615

614-
615-
616616
class CallSpec2(object):
617617
def __init__(self, metafunc):
618618
self.metafunc = metafunc

_pytest/tmpdir.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import pytest
55
import py
6-
from _pytest.monkeypatch import monkeypatch
6+
from _pytest.monkeypatch import MonkeyPatch
77

88

99
class TempdirFactory:
@@ -92,7 +92,7 @@ def pytest_configure(config):
9292
available at pytest_configure time, but ideally should be moved entirely
9393
to the tmpdir_factory session fixture.
9494
"""
95-
mp = monkeypatch()
95+
mp = MonkeyPatch()
9696
t = TempdirFactory(config)
9797
config._cleanup.extend([mp.undo, t.finish])
9898
mp.setattr(config, '_tmpdirhandler', t, raising=False)

testing/acceptance_test.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,3 +762,34 @@ def test_setup_function(self, testdir):
762762
* setup *test_1*
763763
* call *test_1*
764764
""")
765+
766+
767+
def test_yield_tests_deprecation(testdir):
768+
testdir.makepyfile("""
769+
def func1(arg, arg2):
770+
assert arg == arg2
771+
def test_gen():
772+
yield "m1", func1, 15, 3*5
773+
yield "m2", func1, 42, 6*7
774+
""")
775+
result = testdir.runpytest('-ra')
776+
result.stdout.fnmatch_lines([
777+
'*yield tests are deprecated, and scheduled to be removed in pytest 4.0*',
778+
'*2 passed*',
779+
])
780+
781+
782+
def test_funcarg_prefix_deprecation(testdir):
783+
testdir.makepyfile("""
784+
def pytest_funcarg__value():
785+
return 10
786+
787+
def test_funcarg_prefix(value):
788+
assert value == 10
789+
""")
790+
result = testdir.runpytest('-ra')
791+
result.stdout.fnmatch_lines([
792+
'*declaring fixtures using "pytest_funcarg__" prefix is deprecated and scheduled to be removed in pytest 4.0*',
793+
'*remove the prefix and use the @pytest.fixture decorator instead*',
794+
'*1 passed*',
795+
])

testing/code/test_excinfo.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,9 @@ def test_division_zero():
381381
])
382382

383383
class TestFormattedExcinfo:
384-
def pytest_funcarg__importasmod(self, request):
384+
385+
@pytest.fixture
386+
def importasmod(self, request):
385387
def importasmod(source):
386388
source = _pytest._code.Source(source)
387389
tmpdir = request.getfixturevalue("tmpdir")

testing/code/test_source.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,14 @@ def test_compile_and_getsource(self):
285285
#print "block", str(block)
286286
assert str(stmt).strip().startswith('assert')
287287

288-
def test_compilefuncs_and_path_sanity(self):
288+
@pytest.mark.parametrize('name', ['', None, 'my'])
289+
def test_compilefuncs_and_path_sanity(self, name):
289290
def check(comp, name):
290291
co = comp(self.source, name)
291292
if not name:
292-
expected = "codegen %s:%d>" %(mypath, mylineno+2+1)
293+
expected = "codegen %s:%d>" %(mypath, mylineno+2+2)
293294
else:
294-
expected = "codegen %r %s:%d>" % (name, mypath, mylineno+2+1)
295+
expected = "codegen %r %s:%d>" % (name, mypath, mylineno+2+2)
295296
fn = co.co_filename
296297
assert fn.endswith(expected)
297298

@@ -300,8 +301,7 @@ def check(comp, name):
300301
mypath = mycode.path
301302

302303
for comp in _pytest._code.compile, _pytest._code.Source.compile:
303-
for name in '', None, 'my':
304-
yield check, comp, name
304+
check(comp, name)
305305

306306
def test_offsetless_synerr(self):
307307
pytest.raises(SyntaxError, _pytest._code.compile, "lambda a,a: 0", mode='eval')

0 commit comments

Comments
 (0)