Merge branch 'master' into merge-master
# Conflicts: # AUTHORS # CHANGELOG.rst # _pytest/monkeypatch.py # _pytest/python.py
This commit is contained in:
@@ -157,7 +157,7 @@ error_capsysfderror = "cannot use capsys and capfd at the same time"
|
||||
|
||||
@pytest.fixture
|
||||
def capsys(request):
|
||||
"""enables capturing of writes to sys.stdout/sys.stderr and makes
|
||||
"""Enable capturing of writes to sys.stdout/sys.stderr and make
|
||||
captured output available via ``capsys.readouterr()`` method calls
|
||||
which return a ``(out, err)`` tuple.
|
||||
"""
|
||||
@@ -168,7 +168,7 @@ def capsys(request):
|
||||
|
||||
@pytest.fixture
|
||||
def capfd(request):
|
||||
"""enables capturing of writes to file descriptors 1 and 2 and makes
|
||||
"""Enable capturing of writes to file descriptors 1 and 2 and make
|
||||
captured output available via ``capfd.readouterr()`` method calls
|
||||
which return a ``(out, err)`` tuple.
|
||||
"""
|
||||
|
||||
@@ -673,8 +673,13 @@ class FixtureLookupErrorRepr(TerminalRepr):
|
||||
#tw.line("FixtureLookupError: %s" %(self.argname), red=True)
|
||||
for tbline in self.tblines:
|
||||
tw.line(tbline.rstrip())
|
||||
for line in self.errorstring.split("\n"):
|
||||
tw.line(" " + line.strip(), red=True)
|
||||
lines = self.errorstring.split("\n")
|
||||
for line in lines:
|
||||
if line == lines[0]:
|
||||
prefix = 'E '
|
||||
else:
|
||||
prefix = ' '
|
||||
tw.line(prefix + line.strip(), red=True)
|
||||
tw.line()
|
||||
tw.line("%s:%d" % (self.filename, self.firstlineno+1))
|
||||
|
||||
|
||||
@@ -186,8 +186,8 @@ class _NodeReporter(object):
|
||||
|
||||
@pytest.fixture
|
||||
def record_xml_property(request):
|
||||
"""Fixture that adds extra xml properties to the tag for the calling test.
|
||||
The fixture is callable with (name, value), with value being automatically
|
||||
"""Add extra xml properties to the tag for the calling test.
|
||||
The fixture is callable with ``(name, value)``, with value being automatically
|
||||
xml-encoded.
|
||||
"""
|
||||
request.node.warn(
|
||||
|
||||
@@ -98,6 +98,10 @@ def wrap_session(config, doit):
|
||||
raise
|
||||
except KeyboardInterrupt:
|
||||
excinfo = _pytest._code.ExceptionInfo()
|
||||
if initstate < 2 and isinstance(
|
||||
excinfo.value, pytest.exit.Exception):
|
||||
sys.stderr.write('{0}: {1}\n'.format(
|
||||
excinfo.typename, excinfo.value.msg))
|
||||
config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
|
||||
session.exitstatus = EXIT_INTERRUPTED
|
||||
except:
|
||||
|
||||
@@ -226,10 +226,10 @@ class MonkeyPatch:
|
||||
""" Undo previous changes. This call consumes the
|
||||
undo stack. Calling it a second time has no effect unless
|
||||
you do more monkeypatching after the undo call.
|
||||
|
||||
|
||||
There is generally no need to call `undo()`, since it is
|
||||
called automatically during tear-down.
|
||||
|
||||
|
||||
Note that the same `monkeypatch` fixture is used across a
|
||||
single test function invocation. If `monkeypatch` is used both by
|
||||
the test function itself and one of the test fixtures,
|
||||
|
||||
@@ -489,6 +489,10 @@ class Class(PyCollector):
|
||||
self.warn("C1", "cannot collect test class %r because it has a "
|
||||
"__init__ constructor" % self.obj.__name__)
|
||||
return []
|
||||
elif hasnew(self.obj):
|
||||
self.warn("C1", "cannot collect test class %r because it has a "
|
||||
"__new__ constructor" % self.obj.__name__)
|
||||
return []
|
||||
return [self._getcustomclass("Instance")(name="()", parent=self)]
|
||||
|
||||
def setup(self):
|
||||
@@ -506,8 +510,7 @@ class Class(PyCollector):
|
||||
|
||||
class Instance(PyCollector):
|
||||
def _getobj(self):
|
||||
obj = self.parent.obj()
|
||||
return obj
|
||||
return self.parent.obj()
|
||||
|
||||
def collect(self):
|
||||
self.session._fixturemanager.parsefactories(self)
|
||||
@@ -622,8 +625,13 @@ class Generator(FunctionMixin, PyCollector):
|
||||
def hasinit(obj):
|
||||
init = getattr(obj, '__init__', None)
|
||||
if init:
|
||||
if init != object.__init__:
|
||||
return True
|
||||
return init != object.__init__
|
||||
|
||||
|
||||
def hasnew(obj):
|
||||
new = getattr(obj, '__new__', None)
|
||||
if new:
|
||||
return new != object.__new__
|
||||
|
||||
|
||||
class CallSpec2(object):
|
||||
@@ -763,7 +771,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
|
||||
It will also override any fixture-function defined scope, allowing
|
||||
to set a dynamic scope using test context or configuration.
|
||||
"""
|
||||
|
||||
from _pytest.fixtures import scopes
|
||||
# individual parametrized argument sets can be wrapped in a series
|
||||
# of markers in which case we unwrap the values and apply the mark
|
||||
# at Function init
|
||||
@@ -794,10 +802,16 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
|
||||
newmarks = newkeywords.setdefault(0, {})
|
||||
newmarks[newmark.markname] = newmark
|
||||
|
||||
|
||||
if scope is None:
|
||||
scope = "function"
|
||||
scopenum = fixtures.scopes.index(scope)
|
||||
if self._arg2fixturedefs:
|
||||
# Takes the most narrow scope from used fixtures
|
||||
fixtures_scopes = [fixturedef[0].scope for fixturedef in self._arg2fixturedefs.values()]
|
||||
for scope in reversed(scopes):
|
||||
if scope in fixtures_scopes:
|
||||
break
|
||||
else:
|
||||
scope = 'function'
|
||||
scopenum = scopes.index(scope)
|
||||
valtypes = {}
|
||||
for arg in argnames:
|
||||
if arg not in self.fixturenames:
|
||||
|
||||
@@ -108,7 +108,7 @@ def tmpdir_factory(request):
|
||||
|
||||
@pytest.fixture
|
||||
def tmpdir(request, tmpdir_factory):
|
||||
"""return a temporary directory path object
|
||||
"""Return a temporary directory path object
|
||||
which is unique to each test function invocation,
|
||||
created as a sub directory of the base temporary
|
||||
directory. The returned object is a `py.path.local`_
|
||||
|
||||
Reference in New Issue
Block a user