Merge pytest-2.7 for issue660 fix
This commit is contained in:
commit
09dff73607
14
CHANGELOG
14
CHANGELOG
|
@ -2,6 +2,20 @@
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
|
|
||||||
|
2.7.1.dev (compared to 2.7.0)
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
- fix issue660: properly report scope-mismatch-access errors
|
||||||
|
independently from ordering of fixture arguments. Also
|
||||||
|
avoid the pytest internal traceback which does not provide
|
||||||
|
information to the user. Thanks Holger Krekel.
|
||||||
|
|
||||||
|
- streamlined and documented release process. Also all versions
|
||||||
|
(in setup.py and documentation generation) are now read
|
||||||
|
from _pytest/__init__.py. Thanks Holger Krekel.
|
||||||
|
|
||||||
|
- fixed docs to remove the notion that yield-fixtures are experimental.
|
||||||
|
They are here to stay :) Thanks Bruno Oliveira.
|
||||||
|
|
||||||
- Support building wheels by using environment markers for the
|
- Support building wheels by using environment markers for the
|
||||||
requirements. Thanks Ionel Maries Cristian.
|
requirements. Thanks Ionel Maries Cristian.
|
||||||
|
|
|
@ -1356,12 +1356,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
||||||
try:
|
try:
|
||||||
val = cache[cachekey]
|
val = cache[cachekey]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
__tracebackhide__ = True
|
self._check_scope(self.fixturename, self.scope, scope)
|
||||||
if scopemismatch(self.scope, scope):
|
|
||||||
raise ScopeMismatchError("You tried to access a %r scoped "
|
|
||||||
"resource with a %r scoped request object" %(
|
|
||||||
(scope, self.scope)))
|
|
||||||
__tracebackhide__ = False
|
|
||||||
val = setup()
|
val = setup()
|
||||||
cache[cachekey] = val
|
cache[cachekey] = val
|
||||||
if teardown is not None:
|
if teardown is not None:
|
||||||
|
@ -1392,6 +1387,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
||||||
if argname == "request":
|
if argname == "request":
|
||||||
class PseudoFixtureDef:
|
class PseudoFixtureDef:
|
||||||
cached_result = (self, [0], None)
|
cached_result = (self, [0], None)
|
||||||
|
scope = "function"
|
||||||
return PseudoFixtureDef
|
return PseudoFixtureDef
|
||||||
raise
|
raise
|
||||||
# remove indent to prevent the python3 exception
|
# remove indent to prevent the python3 exception
|
||||||
|
@ -1435,16 +1431,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
||||||
subrequest = SubRequest(self, scope, param, param_index, fixturedef)
|
subrequest = SubRequest(self, scope, param, param_index, fixturedef)
|
||||||
|
|
||||||
# check if a higher-level scoped fixture accesses a lower level one
|
# check if a higher-level scoped fixture accesses a lower level one
|
||||||
if scope is not None:
|
subrequest._check_scope(argname, self.scope, scope)
|
||||||
__tracebackhide__ = True
|
|
||||||
if scopemismatch(self.scope, scope):
|
|
||||||
# try to report something helpful
|
|
||||||
lines = subrequest._factorytraceback()
|
|
||||||
raise ScopeMismatchError("You tried to access the %r scoped "
|
|
||||||
"fixture %r with a %r scoped request object, "
|
|
||||||
"involved factories\n%s" %(
|
|
||||||
(scope, argname, self.scope, "\n".join(lines))))
|
|
||||||
__tracebackhide__ = False
|
|
||||||
|
|
||||||
# clear sys.exc_info before invoking the fixture (python bug?)
|
# clear sys.exc_info before invoking the fixture (python bug?)
|
||||||
# if its not explicitly cleared it will leak into the call
|
# if its not explicitly cleared it will leak into the call
|
||||||
|
@ -1458,6 +1445,18 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
||||||
subrequest.node)
|
subrequest.node)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
def _check_scope(self, argname, invoking_scope, requested_scope):
|
||||||
|
if argname == "request":
|
||||||
|
return
|
||||||
|
if scopemismatch(invoking_scope, requested_scope):
|
||||||
|
# try to report something helpful
|
||||||
|
lines = self._factorytraceback()
|
||||||
|
pytest.fail("ScopeMismatch: you tried to access the %r scoped "
|
||||||
|
"fixture %r with a %r scoped request object, "
|
||||||
|
"involved factories\n%s" %(
|
||||||
|
(requested_scope, argname, invoking_scope, "\n".join(lines))),
|
||||||
|
pytrace=False)
|
||||||
|
|
||||||
def _factorytraceback(self):
|
def _factorytraceback(self):
|
||||||
lines = []
|
lines = []
|
||||||
for fixturedef in self._get_fixturestack():
|
for fixturedef in self._get_fixturestack():
|
||||||
|
@ -1518,6 +1517,7 @@ scopenum_function = scopes.index("function")
|
||||||
def scopemismatch(currentscope, newscope):
|
def scopemismatch(currentscope, newscope):
|
||||||
return scopes.index(newscope) > scopes.index(currentscope)
|
return scopes.index(newscope) > scopes.index(currentscope)
|
||||||
|
|
||||||
|
|
||||||
class FixtureLookupError(LookupError):
|
class FixtureLookupError(LookupError):
|
||||||
""" could not return a requested Fixture (missing or invalid). """
|
""" could not return a requested Fixture (missing or invalid). """
|
||||||
def __init__(self, argname, request, msg=None):
|
def __init__(self, argname, request, msg=None):
|
||||||
|
@ -1867,6 +1867,7 @@ class FixtureDef:
|
||||||
for argname in self.argnames:
|
for argname in self.argnames:
|
||||||
fixturedef = request._get_active_fixturedef(argname)
|
fixturedef = request._get_active_fixturedef(argname)
|
||||||
result, arg_cache_key, exc = fixturedef.cached_result
|
result, arg_cache_key, exc = fixturedef.cached_result
|
||||||
|
request._check_scope(argname, request.scope, fixturedef.scope)
|
||||||
kwargs[argname] = result
|
kwargs[argname] = result
|
||||||
if argname != "request":
|
if argname != "request":
|
||||||
fixturedef.addfinalizer(self.finish)
|
fixturedef.addfinalizer(self.finish)
|
||||||
|
|
|
@ -906,6 +906,27 @@ class TestFixtureUsages:
|
||||||
"*1 error*"
|
"*1 error*"
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def test_receives_funcargs_scope_mismatch_issue660(self, testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import pytest
|
||||||
|
@pytest.fixture(scope="function")
|
||||||
|
def arg1():
|
||||||
|
return 1
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def arg2(arg1):
|
||||||
|
return arg1 + 1
|
||||||
|
|
||||||
|
def test_add(arg1, arg2):
|
||||||
|
assert arg2 == 2
|
||||||
|
""")
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stdout.fnmatch_lines([
|
||||||
|
"*ScopeMismatch*involved factories*",
|
||||||
|
"* def arg2*",
|
||||||
|
"*1 error*"
|
||||||
|
])
|
||||||
|
|
||||||
def test_funcarg_parametrized_and_used_twice(self, testdir):
|
def test_funcarg_parametrized_and_used_twice(self, testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
import pytest
|
import pytest
|
||||||
|
|
Loading…
Reference in New Issue