aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/pytest/py2/_pytest
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:30 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:30 +0300
commit2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch)
tree012bb94d777798f1f56ac1cec429509766d05181 /contrib/python/pytest/py2/_pytest
parent6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff)
downloadydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/python/pytest/py2/_pytest')
-rw-r--r--contrib/python/pytest/py2/_pytest/__init__.py2
-rw-r--r--contrib/python/pytest/py2/_pytest/_argcomplete.py2
-rw-r--r--contrib/python/pytest/py2/_pytest/_code/__init__.py2
-rw-r--r--contrib/python/pytest/py2/_pytest/_code/_py2traceback.py2
-rw-r--r--contrib/python/pytest/py2/_pytest/_code/code.py202
-rw-r--r--contrib/python/pytest/py2/_pytest/_code/source.py14
-rw-r--r--contrib/python/pytest/py2/_pytest/_io/saferepr.py166
-rw-r--r--contrib/python/pytest/py2/_pytest/_version.py2
-rw-r--r--contrib/python/pytest/py2/_pytest/assertion/__init__.py2
-rw-r--r--contrib/python/pytest/py2/_pytest/assertion/rewrite.py166
-rw-r--r--contrib/python/pytest/py2/_pytest/assertion/truncate.py2
-rw-r--r--contrib/python/pytest/py2/_pytest/assertion/util.py296
-rw-r--r--contrib/python/pytest/py2/_pytest/cacheprovider.py222
-rw-r--r--contrib/python/pytest/py2/_pytest/capture.py254
-rw-r--r--contrib/python/pytest/py2/_pytest/compat.py88
-rw-r--r--contrib/python/pytest/py2/_pytest/config/__init__.py568
-rw-r--r--contrib/python/pytest/py2/_pytest/config/argparsing.py26
-rw-r--r--contrib/python/pytest/py2/_pytest/config/exceptions.py2
-rw-r--r--contrib/python/pytest/py2/_pytest/config/findpaths.py64
-rw-r--r--contrib/python/pytest/py2/_pytest/debugging.py392
-rw-r--r--contrib/python/pytest/py2/_pytest/deprecated.py94
-rw-r--r--contrib/python/pytest/py2/_pytest/doctest.py138
-rw-r--r--contrib/python/pytest/py2/_pytest/fixtures.py178
-rw-r--r--contrib/python/pytest/py2/_pytest/freeze_support.py2
-rw-r--r--contrib/python/pytest/py2/_pytest/helpconfig.py88
-rw-r--r--contrib/python/pytest/py2/_pytest/hookspec.py108
-rw-r--r--contrib/python/pytest/py2/_pytest/junitxml.py378
-rw-r--r--contrib/python/pytest/py2/_pytest/logging.py306
-rw-r--r--contrib/python/pytest/py2/_pytest/main.py182
-rw-r--r--contrib/python/pytest/py2/_pytest/mark/__init__.py14
-rw-r--r--contrib/python/pytest/py2/_pytest/mark/evaluate.py2
-rw-r--r--contrib/python/pytest/py2/_pytest/mark/legacy.py12
-rw-r--r--contrib/python/pytest/py2/_pytest/mark/structures.py200
-rw-r--r--contrib/python/pytest/py2/_pytest/monkeypatch.py50
-rw-r--r--contrib/python/pytest/py2/_pytest/nodes.py38
-rw-r--r--contrib/python/pytest/py2/_pytest/nose.py14
-rw-r--r--contrib/python/pytest/py2/_pytest/outcomes.py58
-rw-r--r--contrib/python/pytest/py2/_pytest/pastebin.py4
-rw-r--r--contrib/python/pytest/py2/_pytest/pathlib.py144
-rw-r--r--contrib/python/pytest/py2/_pytest/pytester.py262
-rw-r--r--contrib/python/pytest/py2/_pytest/python.py538
-rw-r--r--contrib/python/pytest/py2/_pytest/python_api.py156
-rw-r--r--contrib/python/pytest/py2/_pytest/recwarn.py34
-rw-r--r--contrib/python/pytest/py2/_pytest/reports.py504
-rw-r--r--contrib/python/pytest/py2/_pytest/resultlog.py12
-rw-r--r--contrib/python/pytest/py2/_pytest/runner.py96
-rw-r--r--contrib/python/pytest/py2/_pytest/setuponly.py2
-rw-r--r--contrib/python/pytest/py2/_pytest/setupplan.py2
-rw-r--r--contrib/python/pytest/py2/_pytest/skipping.py8
-rw-r--r--contrib/python/pytest/py2/_pytest/stepwise.py34
-rw-r--r--contrib/python/pytest/py2/_pytest/terminal.py642
-rw-r--r--contrib/python/pytest/py2/_pytest/tmpdir.py50
-rw-r--r--contrib/python/pytest/py2/_pytest/unittest.py110
-rw-r--r--contrib/python/pytest/py2/_pytest/warning_types.py116
-rw-r--r--contrib/python/pytest/py2/_pytest/warnings.py12
55 files changed, 3531 insertions, 3531 deletions
diff --git a/contrib/python/pytest/py2/_pytest/__init__.py b/contrib/python/pytest/py2/_pytest/__init__.py
index 17cc20b615..96cc45f128 100644
--- a/contrib/python/pytest/py2/_pytest/__init__.py
+++ b/contrib/python/pytest/py2/_pytest/__init__.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
__all__ = ["__version__"]
try:
diff --git a/contrib/python/pytest/py2/_pytest/_argcomplete.py b/contrib/python/pytest/py2/_pytest/_argcomplete.py
index c6cf1d8fdd..0f1ff1b78b 100644
--- a/contrib/python/pytest/py2/_pytest/_argcomplete.py
+++ b/contrib/python/pytest/py2/_pytest/_argcomplete.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""allow bash-completion for argparse with argcomplete if installed
needs argcomplete>=0.5.6 for python 3.2/3.3 (older versions fail
to find the magic string, so _ARGCOMPLETE env. var is never set, and
diff --git a/contrib/python/pytest/py2/_pytest/_code/__init__.py b/contrib/python/pytest/py2/_pytest/_code/__init__.py
index 1394b2b10e..989743ea51 100644
--- a/contrib/python/pytest/py2/_pytest/_code/__init__.py
+++ b/contrib/python/pytest/py2/_pytest/_code/__init__.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" python inspection/code generation API """
from __future__ import absolute_import
from __future__ import division
diff --git a/contrib/python/pytest/py2/_pytest/_code/_py2traceback.py b/contrib/python/pytest/py2/_pytest/_code/_py2traceback.py
index faacc02166..cd614642b7 100644
--- a/contrib/python/pytest/py2/_pytest/_code/_py2traceback.py
+++ b/contrib/python/pytest/py2/_pytest/_code/_py2traceback.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
# copied from python-2.7.3's traceback.py
# CHANGES:
# - some_str is replaced, trying to create unicode strings
diff --git a/contrib/python/pytest/py2/_pytest/_code/code.py b/contrib/python/pytest/py2/_pytest/_code/code.py
index 175d6fda01..38ca0a5b19 100644
--- a/contrib/python/pytest/py2/_pytest/_code/code.py
+++ b/contrib/python/pytest/py2/_pytest/_code/code.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -17,8 +17,8 @@ import py
from six import text_type
import _pytest
-from _pytest._io.saferepr import safeformat
-from _pytest._io.saferepr import saferepr
+from _pytest._io.saferepr import safeformat
+from _pytest._io.saferepr import saferepr
from _pytest.compat import _PY2
from _pytest.compat import _PY3
from _pytest.compat import PY35
@@ -138,12 +138,12 @@ class Frame(object):
"""
f_locals = self.f_locals.copy()
f_locals.update(vars)
- exec(code, self.f_globals, f_locals)
+ exec(code, self.f_globals, f_locals)
def repr(self, object):
""" return a 'safe' (non-recursive, one-line) string repr for 'object'
"""
- return saferepr(object)
+ return saferepr(object)
def is_true(self, object):
return object
@@ -241,20 +241,20 @@ class TracebackEntry(object):
def ishidden(self):
""" return True if the current frame has a var __tracebackhide__
- resolving to True.
+ resolving to True.
If __tracebackhide__ is a callable, it gets called with the
ExceptionInfo instance and can decide whether to hide the traceback.
mostly for internal use
"""
- f = self.frame
- tbh = f.f_locals.get(
- "__tracebackhide__", f.f_globals.get("__tracebackhide__", False)
- )
- if tbh and callable(tbh):
+ f = self.frame
+ tbh = f.f_locals.get(
+ "__tracebackhide__", f.f_globals.get("__tracebackhide__", False)
+ )
+ if tbh and callable(tbh):
return tbh(None if self._excinfo is None else self._excinfo())
- return tbh
+ return tbh
def __str__(self):
try:
@@ -385,7 +385,7 @@ co_equal = compile(
)
-@attr.s(repr=False)
+@attr.s(repr=False)
class ExceptionInfo(object):
""" wraps sys.exc_info() objects and offers
help for navigating the traceback.
@@ -395,76 +395,76 @@ class ExceptionInfo(object):
"AssertionError(u'assert " if _PY2 else "AssertionError('assert "
)
- _excinfo = attr.ib()
- _striptext = attr.ib(default="")
- _traceback = attr.ib(default=None)
-
- @classmethod
- def from_current(cls, exprinfo=None):
- """returns an ExceptionInfo matching the current traceback
-
- .. warning::
-
- Experimental API
-
-
- :param exprinfo: a text string helping to determine if we should
- strip ``AssertionError`` from the output, defaults
- to the exception message/``__str__()``
- """
- tup = sys.exc_info()
- assert tup[0] is not None, "no current exception"
- _striptext = ""
- if exprinfo is None and isinstance(tup[1], AssertionError):
- exprinfo = getattr(tup[1], "msg", None)
- if exprinfo is None:
- exprinfo = saferepr(tup[1])
- if exprinfo and exprinfo.startswith(cls._assert_start_repr):
- _striptext = "AssertionError: "
-
- return cls(tup, _striptext)
-
- @classmethod
- def for_later(cls):
- """return an unfilled ExceptionInfo
- """
- return cls(None)
-
- @property
- def type(self):
- """the exception class"""
- return self._excinfo[0]
-
- @property
- def value(self):
- """the exception value"""
- return self._excinfo[1]
-
- @property
- def tb(self):
- """the exception raw traceback"""
- return self._excinfo[2]
-
- @property
- def typename(self):
- """the type name of the exception"""
- return self.type.__name__
-
- @property
- def traceback(self):
- """the traceback"""
- if self._traceback is None:
- self._traceback = Traceback(self.tb, excinfo=ref(self))
- return self._traceback
-
- @traceback.setter
- def traceback(self, value):
- self._traceback = value
-
+ _excinfo = attr.ib()
+ _striptext = attr.ib(default="")
+ _traceback = attr.ib(default=None)
+
+ @classmethod
+ def from_current(cls, exprinfo=None):
+ """returns an ExceptionInfo matching the current traceback
+
+ .. warning::
+
+ Experimental API
+
+
+ :param exprinfo: a text string helping to determine if we should
+ strip ``AssertionError`` from the output, defaults
+ to the exception message/``__str__()``
+ """
+ tup = sys.exc_info()
+ assert tup[0] is not None, "no current exception"
+ _striptext = ""
+ if exprinfo is None and isinstance(tup[1], AssertionError):
+ exprinfo = getattr(tup[1], "msg", None)
+ if exprinfo is None:
+ exprinfo = saferepr(tup[1])
+ if exprinfo and exprinfo.startswith(cls._assert_start_repr):
+ _striptext = "AssertionError: "
+
+ return cls(tup, _striptext)
+
+ @classmethod
+ def for_later(cls):
+ """return an unfilled ExceptionInfo
+ """
+ return cls(None)
+
+ @property
+ def type(self):
+ """the exception class"""
+ return self._excinfo[0]
+
+ @property
+ def value(self):
+ """the exception value"""
+ return self._excinfo[1]
+
+ @property
+ def tb(self):
+ """the exception raw traceback"""
+ return self._excinfo[2]
+
+ @property
+ def typename(self):
+ """the type name of the exception"""
+ return self.type.__name__
+
+ @property
+ def traceback(self):
+ """the traceback"""
+ if self._traceback is None:
+ self._traceback = Traceback(self.tb, excinfo=ref(self))
+ return self._traceback
+
+ @traceback.setter
+ def traceback(self, value):
+ self._traceback = value
+
def __repr__(self):
- if self._excinfo is None:
- return "<ExceptionInfo for raises contextmanager>"
- return "<ExceptionInfo %s tblen=%d>" % (self.typename, len(self.traceback))
+ if self._excinfo is None:
+ return "<ExceptionInfo for raises contextmanager>"
+ return "<ExceptionInfo %s tblen=%d>" % (self.typename, len(self.traceback))
def exconly(self, tryshort=False):
""" return the exception as a string
@@ -552,11 +552,11 @@ class ExceptionInfo(object):
return fmt.repr_excinfo(self)
def __str__(self):
- if self._excinfo is None:
+ if self._excinfo is None:
return repr(self)
- entry = self.traceback[-1]
- loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly())
- return str(loc)
+ entry = self.traceback[-1]
+ loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly())
+ return str(loc)
def __unicode__(self):
entry = self.traceback[-1]
@@ -565,20 +565,20 @@ class ExceptionInfo(object):
def match(self, regexp):
"""
- Check whether the regular expression 'regexp' is found in the string
- representation of the exception using ``re.search``. If it matches
- then True is returned (so that it is possible to write
- ``assert excinfo.match()``). If it doesn't match an AssertionError is
- raised.
+ Check whether the regular expression 'regexp' is found in the string
+ representation of the exception using ``re.search``. If it matches
+ then True is returned (so that it is possible to write
+ ``assert excinfo.match()``). If it doesn't match an AssertionError is
+ raised.
"""
__tracebackhide__ = True
- value = (
- text_type(self.value) if isinstance(regexp, text_type) else str(self.value)
- )
- if not re.search(regexp, value):
- raise AssertionError(
- u"Pattern {!r} not found in {!r}".format(regexp, value)
- )
+ value = (
+ text_type(self.value) if isinstance(regexp, text_type) else str(self.value)
+ )
+ if not re.search(regexp, value):
+ raise AssertionError(
+ u"Pattern {!r} not found in {!r}".format(regexp, value)
+ )
return True
@@ -624,7 +624,7 @@ class FormattedExcinfo(object):
if self.funcargs:
args = []
for argname, argvalue in entry.frame.getargs(var=True):
- args.append((argname, saferepr(argvalue)))
+ args.append((argname, saferepr(argvalue)))
return ReprFuncArgs(args)
def get_source(self, source, line_index=-1, excinfo=None, short=False):
@@ -677,9 +677,9 @@ class FormattedExcinfo(object):
# _repr() function, which is only reprlib.Repr in
# disguise, so is very configurable.
if self.truncate_locals:
- str_repr = saferepr(value)
+ str_repr = saferepr(value)
else:
- str_repr = safeformat(value)
+ str_repr = safeformat(value)
# if len(str_repr) < 70 or not isinstance(value,
# (list, tuple, dict)):
lines.append("%-10s = %s" % (name, str_repr))
diff --git a/contrib/python/pytest/py2/_pytest/_code/source.py b/contrib/python/pytest/py2/_pytest/_code/source.py
index b35e97b9ce..74e9c77600 100644
--- a/contrib/python/pytest/py2/_pytest/_code/source.py
+++ b/contrib/python/pytest/py2/_pytest/_code/source.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -128,8 +128,8 @@ class Source(object):
else:
source = str(self)
try:
- ast.parse(source)
- except (SyntaxError, ValueError, TypeError):
+ ast.parse(source)
+ except (SyntaxError, ValueError, TypeError):
return False
else:
return True
@@ -199,9 +199,9 @@ def compile_(source, filename=None, mode="exec", flags=0, dont_inherit=0):
def getfslineno(obj):
""" Return source location (path, lineno) for the given object.
- If the source cannot be determined return ("", -1).
-
- The line number is 0-based.
+ If the source cannot be determined return ("", -1).
+
+ The line number is 0-based.
"""
from .code import Code
@@ -235,7 +235,7 @@ def getfslineno(obj):
def findsource(obj):
try:
sourcelines, lineno = inspect.findsource(obj)
- except Exception:
+ except Exception:
return None, -1
source = Source()
source.lines = [line.rstrip() for line in sourcelines]
diff --git a/contrib/python/pytest/py2/_pytest/_io/saferepr.py b/contrib/python/pytest/py2/_pytest/_io/saferepr.py
index 9b412dccad..219171f9f5 100644
--- a/contrib/python/pytest/py2/_pytest/_io/saferepr.py
+++ b/contrib/python/pytest/py2/_pytest/_io/saferepr.py
@@ -1,83 +1,83 @@
-# -*- coding: utf-8 -*-
-import pprint
-
-from six.moves import reprlib
-
-
-def _call_and_format_exception(call, x, *args):
- try:
- # Try the vanilla repr and make sure that the result is a string
- return call(x, *args)
- except Exception as exc:
- exc_name = type(exc).__name__
- try:
- exc_info = str(exc)
- except Exception:
- exc_info = "unknown"
- return '<[%s("%s") raised in repr()] %s object at 0x%x>' % (
- exc_name,
- exc_info,
- x.__class__.__name__,
- id(x),
- )
-
-
-class SafeRepr(reprlib.Repr):
- """subclass of repr.Repr that limits the resulting size of repr()
- and includes information on exceptions raised during the call.
- """
-
- def repr(self, x):
- return self._callhelper(reprlib.Repr.repr, self, x)
-
- def repr_unicode(self, x, level):
- # Strictly speaking wrong on narrow builds
- def repr(u):
- if "'" not in u:
- return u"'%s'" % u
- elif '"' not in u:
- return u'"%s"' % u
- else:
- return u"'%s'" % u.replace("'", r"\'")
-
- s = repr(x[: self.maxstring])
- if len(s) > self.maxstring:
- i = max(0, (self.maxstring - 3) // 2)
- j = max(0, self.maxstring - 3 - i)
- s = repr(x[:i] + x[len(x) - j :])
- s = s[:i] + "..." + s[len(s) - j :]
- return s
-
- def repr_instance(self, x, level):
- return self._callhelper(repr, x)
-
- def _callhelper(self, call, x, *args):
- s = _call_and_format_exception(call, x, *args)
- if len(s) > self.maxsize:
- i = max(0, (self.maxsize - 3) // 2)
- j = max(0, self.maxsize - 3 - i)
- s = s[:i] + "..." + s[len(s) - j :]
- return s
-
-
-def safeformat(obj):
- """return a pretty printed string for the given object.
- Failing __repr__ functions of user instances will be represented
- with a short exception info.
- """
- return _call_and_format_exception(pprint.pformat, obj)
-
-
-def saferepr(obj, maxsize=240):
- """return a size-limited safe repr-string for the given object.
- Failing __repr__ functions of user instances will be represented
- with a short exception info and 'saferepr' generally takes
- care to never raise exceptions itself. This function is a wrapper
- around the Repr/reprlib functionality of the standard 2.6 lib.
- """
- # review exception handling
- srepr = SafeRepr()
- srepr.maxstring = maxsize
- srepr.maxsize = maxsize
- srepr.maxother = 160
- return srepr.repr(obj)
+# -*- coding: utf-8 -*-
+import pprint
+
+from six.moves import reprlib
+
+
+def _call_and_format_exception(call, x, *args):
+ try:
+ # Try the vanilla repr and make sure that the result is a string
+ return call(x, *args)
+ except Exception as exc:
+ exc_name = type(exc).__name__
+ try:
+ exc_info = str(exc)
+ except Exception:
+ exc_info = "unknown"
+ return '<[%s("%s") raised in repr()] %s object at 0x%x>' % (
+ exc_name,
+ exc_info,
+ x.__class__.__name__,
+ id(x),
+ )
+
+
+class SafeRepr(reprlib.Repr):
+ """subclass of repr.Repr that limits the resulting size of repr()
+ and includes information on exceptions raised during the call.
+ """
+
+ def repr(self, x):
+ return self._callhelper(reprlib.Repr.repr, self, x)
+
+ def repr_unicode(self, x, level):
+ # Strictly speaking wrong on narrow builds
+ def repr(u):
+ if "'" not in u:
+ return u"'%s'" % u
+ elif '"' not in u:
+ return u'"%s"' % u
+ else:
+ return u"'%s'" % u.replace("'", r"\'")
+
+ s = repr(x[: self.maxstring])
+ if len(s) > self.maxstring:
+ i = max(0, (self.maxstring - 3) // 2)
+ j = max(0, self.maxstring - 3 - i)
+ s = repr(x[:i] + x[len(x) - j :])
+ s = s[:i] + "..." + s[len(s) - j :]
+ return s
+
+ def repr_instance(self, x, level):
+ return self._callhelper(repr, x)
+
+ def _callhelper(self, call, x, *args):
+ s = _call_and_format_exception(call, x, *args)
+ if len(s) > self.maxsize:
+ i = max(0, (self.maxsize - 3) // 2)
+ j = max(0, self.maxsize - 3 - i)
+ s = s[:i] + "..." + s[len(s) - j :]
+ return s
+
+
+def safeformat(obj):
+ """return a pretty printed string for the given object.
+ Failing __repr__ functions of user instances will be represented
+ with a short exception info.
+ """
+ return _call_and_format_exception(pprint.pformat, obj)
+
+
+def saferepr(obj, maxsize=240):
+ """return a size-limited safe repr-string for the given object.
+ Failing __repr__ functions of user instances will be represented
+ with a short exception info and 'saferepr' generally takes
+ care to never raise exceptions itself. This function is a wrapper
+ around the Repr/reprlib functionality of the standard 2.6 lib.
+ """
+ # review exception handling
+ srepr = SafeRepr()
+ srepr.maxstring = maxsize
+ srepr.maxsize = maxsize
+ srepr.maxother = 160
+ return srepr.repr(obj)
diff --git a/contrib/python/pytest/py2/_pytest/_version.py b/contrib/python/pytest/py2/_pytest/_version.py
index 3d587586fc..f2cd9ffdf6 100644
--- a/contrib/python/pytest/py2/_pytest/_version.py
+++ b/contrib/python/pytest/py2/_pytest/_version.py
@@ -1,4 +1,4 @@
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
-version = '4.6.11'
+version = '4.6.11'
diff --git a/contrib/python/pytest/py2/_pytest/assertion/__init__.py b/contrib/python/pytest/py2/_pytest/assertion/__init__.py
index 6b6abb863a..f83f862cda 100644
--- a/contrib/python/pytest/py2/_pytest/assertion/__init__.py
+++ b/contrib/python/pytest/py2/_pytest/assertion/__init__.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""
support for presenting detailed information in failing assertions.
"""
diff --git a/contrib/python/pytest/py2/_pytest/assertion/rewrite.py b/contrib/python/pytest/py2/_pytest/assertion/rewrite.py
index 6cfd81a32f..0c1822b529 100644
--- a/contrib/python/pytest/py2/_pytest/assertion/rewrite.py
+++ b/contrib/python/pytest/py2/_pytest/assertion/rewrite.py
@@ -1,12 +1,12 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""Rewrite assertion AST to produce nice error messages"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-import warnings
-warnings.filterwarnings("ignore", category=DeprecationWarning, module="_pytest.assertion.rewrite")
-
+import warnings
+warnings.filterwarnings("ignore", category=DeprecationWarning, module="_pytest.assertion.rewrite")
+
import ast
import errno
import imp
@@ -23,11 +23,11 @@ import atomicwrites
import py
import six
-from _pytest._io.saferepr import saferepr
+from _pytest._io.saferepr import saferepr
from _pytest.assertion import util
-from _pytest.assertion.util import ( # noqa: F401
- format_explanation as _format_explanation,
-)
+from _pytest.assertion.util import ( # noqa: F401
+ format_explanation as _format_explanation,
+)
from _pytest.compat import spec_from_file_location
from _pytest.pathlib import fnmatch_ex
from _pytest.pathlib import PurePath
@@ -64,10 +64,10 @@ class AssertionRewritingHook(object):
def __init__(self, config):
self.config = config
- try:
- self.fnpats = config.getini("python_files")
- except ValueError:
- self.fnpats = ["test_*.py", "*_test.py"]
+ try:
+ self.fnpats = config.getini("python_files")
+ except ValueError:
+ self.fnpats = ["test_*.py", "*_test.py"]
self.session = None
self.modules = {}
self._rewritten_names = set()
@@ -274,14 +274,14 @@ class AssertionRewritingHook(object):
self._marked_for_rewrite_cache.clear()
def _warn_already_imported(self, name):
- from _pytest.warning_types import PytestAssertRewriteWarning
- from _pytest.warnings import _issue_warning_captured
-
- _issue_warning_captured(
- PytestAssertRewriteWarning(
- "Module already imported so cannot be rewritten: %s" % name
- ),
- self.config.hook,
+ from _pytest.warning_types import PytestAssertRewriteWarning
+ from _pytest.warnings import _issue_warning_captured
+
+ _issue_warning_captured(
+ PytestAssertRewriteWarning(
+ "Module already imported so cannot be rewritten: %s" % name
+ ),
+ self.config.hook,
stacklevel=5,
)
@@ -304,7 +304,7 @@ class AssertionRewritingHook(object):
mod.__loader__ = self
# Normally, this attribute is 3.4+
mod.__spec__ = spec_from_file_location(name, co.co_filename, loader=self)
- exec(co, mod.__dict__)
+ exec(co, mod.__dict__)
except: # noqa
if name in sys.modules:
del sys.modules[name]
@@ -337,11 +337,11 @@ def _write_pyc(state, co, source_stat, pyc):
try:
with atomicwrites.atomic_write(pyc, mode="wb", overwrite=True) as fp:
fp.write(imp.get_magic())
- # as of now, bytecode header expects 32-bit numbers for size and mtime (#4903)
- mtime = int(source_stat.mtime) & 0xFFFFFFFF
+ # as of now, bytecode header expects 32-bit numbers for size and mtime (#4903)
+ mtime = int(source_stat.mtime) & 0xFFFFFFFF
size = source_stat.size & 0xFFFFFFFF
- # "<LL" stands for 2 unsigned longs, little-ending
- fp.write(struct.pack("<LL", mtime, size))
+ # "<LL" stands for 2 unsigned longs, little-ending
+ fp.write(struct.pack("<LL", mtime, size))
fp.write(marshal.dumps(co))
except EnvironmentError as e:
state.trace("error writing pyc file at %s: errno=%s" % (pyc, e.errno))
@@ -436,7 +436,7 @@ def _read_pyc(source, pyc, trace=lambda x: None):
if (
len(data) != 12
or data[:4] != imp.get_magic()
- or struct.unpack("<LL", data[4:]) != (mtime & 0xFFFFFFFF, size & 0xFFFFFFFF)
+ or struct.unpack("<LL", data[4:]) != (mtime & 0xFFFFFFFF, size & 0xFFFFFFFF)
):
trace("_read_pyc(%s): invalid or out of date pyc" % source)
return None
@@ -467,7 +467,7 @@ def _saferepr(obj):
JSON reprs.
"""
- r = saferepr(obj)
+ r = saferepr(obj)
# only occurs in python2.x, repr must return text in python3+
if isinstance(r, bytes):
# Represent unprintable bytes as `\x##`
@@ -483,7 +483,7 @@ def _format_assertmsg(obj):
For strings this simply replaces newlines with '\n~' so that
util.format_explanation() will preserve them instead of escaping
- newlines. For other objects saferepr() is used first.
+ newlines. For other objects saferepr() is used first.
"""
# reprlib appears to have a bug which means that if a string
@@ -492,7 +492,7 @@ def _format_assertmsg(obj):
# However in either case we want to preserve the newline.
replaces = [(u"\n", u"\n~"), (u"%", u"%%")]
if not isinstance(obj, six.string_types):
- obj = saferepr(obj)
+ obj = saferepr(obj)
replaces.append((u"\\n", u"\n~"))
if isinstance(obj, bytes):
@@ -505,15 +505,15 @@ def _format_assertmsg(obj):
def _should_repr_global_name(obj):
- if callable(obj):
- return False
-
- try:
- return not hasattr(obj, "__name__")
- except Exception:
- return True
+ if callable(obj):
+ return False
+ try:
+ return not hasattr(obj, "__name__")
+ except Exception:
+ return True
+
def _format_boolop(explanations, is_or):
explanation = "(" + (is_or and " or " or " and ").join(explanations) + ")"
if isinstance(explanation, six.text_type):
@@ -658,7 +658,7 @@ class AssertionRewriter(ast.NodeVisitor):
# Insert some special imports at the top of the module but after any
# docstrings and __future__ imports.
aliases = [
- ast.alias(six.moves.builtins.__name__, "@py_builtins"),
+ ast.alias(six.moves.builtins.__name__, "@py_builtins"),
ast.alias("_pytest.assertion.rewrite", "@pytest_ar"),
]
doc = getattr(mod, "docstring", None)
@@ -733,13 +733,13 @@ class AssertionRewriter(ast.NodeVisitor):
return ast.Name(name, ast.Load())
def display(self, expr):
- """Call saferepr on the expression."""
- return self.helper("_saferepr", expr)
+ """Call saferepr on the expression."""
+ return self.helper("_saferepr", expr)
def helper(self, name, *args):
"""Call a helper in this module."""
py_name = ast.Name("@pytest_ar", ast.Load())
- attr = ast.Attribute(py_name, name, ast.Load())
+ attr = ast.Attribute(py_name, name, ast.Load())
return ast_Call(attr, list(args), [])
def builtin(self, name):
@@ -809,13 +809,13 @@ class AssertionRewriter(ast.NodeVisitor):
"""
if isinstance(assert_.test, ast.Tuple) and len(assert_.test.elts) >= 1:
- from _pytest.warning_types import PytestAssertRewriteWarning
+ from _pytest.warning_types import PytestAssertRewriteWarning
import warnings
warnings.warn_explicit(
- PytestAssertRewriteWarning(
- "assertion is always true, perhaps remove parentheses?"
- ),
+ PytestAssertRewriteWarning(
+ "assertion is always true, perhaps remove parentheses?"
+ ),
category=None,
filename=str(self.module_path),
lineno=assert_.lineno,
@@ -829,26 +829,26 @@ class AssertionRewriter(ast.NodeVisitor):
self.push_format_context()
# Rewrite assert into a bunch of statements.
top_condition, explanation = self.visit(assert_.test)
- # If in a test module, check if directly asserting None, in order to warn [Issue #3191]
- if self.module_path is not None:
- self.statements.append(
- self.warn_about_none_ast(
- top_condition, module_path=self.module_path, lineno=assert_.lineno
- )
- )
+ # If in a test module, check if directly asserting None, in order to warn [Issue #3191]
+ if self.module_path is not None:
+ self.statements.append(
+ self.warn_about_none_ast(
+ top_condition, module_path=self.module_path, lineno=assert_.lineno
+ )
+ )
# Create failure message.
body = self.on_failure
negation = ast.UnaryOp(ast.Not(), top_condition)
self.statements.append(ast.If(negation, body, []))
if assert_.msg:
- assertmsg = self.helper("_format_assertmsg", assert_.msg)
+ assertmsg = self.helper("_format_assertmsg", assert_.msg)
explanation = "\n>assert " + explanation
else:
assertmsg = ast.Str("")
explanation = "assert " + explanation
template = ast.BinOp(assertmsg, ast.Add(), ast.Str(explanation))
msg = self.pop_format_context(template)
- fmt = self.helper("_format_explanation", msg)
+ fmt = self.helper("_format_explanation", msg)
err_name = ast.Name("AssertionError", ast.Load())
exc = ast_Call(err_name, [fmt], [])
if sys.version_info[0] >= 3:
@@ -866,39 +866,39 @@ class AssertionRewriter(ast.NodeVisitor):
set_location(stmt, assert_.lineno, assert_.col_offset)
return self.statements
- def warn_about_none_ast(self, node, module_path, lineno):
- """
- Returns an AST issuing a warning if the value of node is `None`.
- This is used to warn the user when asserting a function that asserts
- internally already.
- See issue #3191 for more details.
- """
-
- # Using parse because it is different between py2 and py3.
- AST_NONE = ast.parse("None").body[0].value
- val_is_none = ast.Compare(node, [ast.Is()], [AST_NONE])
- send_warning = ast.parse(
- """
-from _pytest.warning_types import PytestAssertRewriteWarning
-from warnings import warn_explicit
-warn_explicit(
- PytestAssertRewriteWarning('asserting the value None, please use "assert is None"'),
- category=None,
- filename={filename!r},
- lineno={lineno},
-)
- """.format(
- filename=module_path.strpath, lineno=lineno
- )
- ).body
- return ast.If(val_is_none, send_warning, [])
-
+ def warn_about_none_ast(self, node, module_path, lineno):
+ """
+ Returns an AST issuing a warning if the value of node is `None`.
+ This is used to warn the user when asserting a function that asserts
+ internally already.
+ See issue #3191 for more details.
+ """
+
+ # Using parse because it is different between py2 and py3.
+ AST_NONE = ast.parse("None").body[0].value
+ val_is_none = ast.Compare(node, [ast.Is()], [AST_NONE])
+ send_warning = ast.parse(
+ """
+from _pytest.warning_types import PytestAssertRewriteWarning
+from warnings import warn_explicit
+warn_explicit(
+ PytestAssertRewriteWarning('asserting the value None, please use "assert is None"'),
+ category=None,
+ filename={filename!r},
+ lineno={lineno},
+)
+ """.format(
+ filename=module_path.strpath, lineno=lineno
+ )
+ ).body
+ return ast.If(val_is_none, send_warning, [])
+
def visit_Name(self, name):
# Display the repr of the name if it's a local variable or
# _should_repr_global_name() thinks it's acceptable.
locs = ast_Call(self.builtin("locals"), [], [])
inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs])
- dorepr = self.helper("_should_repr_global_name", name)
+ dorepr = self.helper("_should_repr_global_name", name)
test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
expr = ast.IfExp(test, self.display(name), ast.Str(name.id))
return name, self.explanation_param(expr)
@@ -934,7 +934,7 @@ warn_explicit(
self.statements = body = inner
self.statements = save
self.on_failure = fail_save
- expl_template = self.helper("_format_boolop", expl_list, ast.Num(is_or))
+ expl_template = self.helper("_format_boolop", expl_list, ast.Num(is_or))
expl = self.pop_format_context(expl_template)
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
@@ -1059,7 +1059,7 @@ warn_explicit(
left_res, left_expl = next_res, next_expl
# Use pytest.assertion.util._reprcompare if that's available.
expl_call = self.helper(
- "_call_reprcompare",
+ "_call_reprcompare",
ast.Tuple(syms, ast.Load()),
ast.Tuple(load_names, ast.Load()),
ast.Tuple(expls, ast.Load()),
diff --git a/contrib/python/pytest/py2/_pytest/assertion/truncate.py b/contrib/python/pytest/py2/_pytest/assertion/truncate.py
index 525896ea9a..0451daa091 100644
--- a/contrib/python/pytest/py2/_pytest/assertion/truncate.py
+++ b/contrib/python/pytest/py2/_pytest/assertion/truncate.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""
Utilities for truncating assertion output.
diff --git a/contrib/python/pytest/py2/_pytest/assertion/util.py b/contrib/python/pytest/py2/_pytest/assertion/util.py
index c382f1c609..12d59c0e02 100644
--- a/contrib/python/pytest/py2/_pytest/assertion/util.py
+++ b/contrib/python/pytest/py2/_pytest/assertion/util.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""Utilities for assertion debugging"""
from __future__ import absolute_import
from __future__ import division
@@ -10,9 +10,9 @@ import six
import _pytest._code
from ..compat import Sequence
-from _pytest import outcomes
-from _pytest._io.saferepr import saferepr
-from _pytest.compat import ATTRS_EQ_FIELD
+from _pytest import outcomes
+from _pytest._io.saferepr import saferepr
+from _pytest.compat import ATTRS_EQ_FIELD
# The _reprcompare attribute on the util module is used by the new assertion
# interpretation code and assertion rewriter to detect this plugin was
@@ -105,46 +105,46 @@ except NameError:
basestring = str
-def issequence(x):
- return isinstance(x, Sequence) and not isinstance(x, basestring)
-
-
-def istext(x):
- return isinstance(x, basestring)
-
-
-def isdict(x):
- return isinstance(x, dict)
-
-
-def isset(x):
- return isinstance(x, (set, frozenset))
-
-
-def isdatacls(obj):
- return getattr(obj, "__dataclass_fields__", None) is not None
-
-
-def isattrs(obj):
- return getattr(obj, "__attrs_attrs__", None) is not None
-
-
-def isiterable(obj):
- try:
- iter(obj)
- return not istext(obj)
- except TypeError:
- return False
-
-
-def assertrepr_compare(config, op, left, right):
- """Return specialised explanations for some operators/operands"""
- width = 80 - 15 - len(op) - 2 # 15 chars indentation, 1 space around op
- left_repr = saferepr(left, maxsize=int(width // 2))
- right_repr = saferepr(right, maxsize=width - len(left_repr))
-
- summary = u"%s %s %s" % (ecu(left_repr), op, ecu(right_repr))
-
+def issequence(x):
+ return isinstance(x, Sequence) and not isinstance(x, basestring)
+
+
+def istext(x):
+ return isinstance(x, basestring)
+
+
+def isdict(x):
+ return isinstance(x, dict)
+
+
+def isset(x):
+ return isinstance(x, (set, frozenset))
+
+
+def isdatacls(obj):
+ return getattr(obj, "__dataclass_fields__", None) is not None
+
+
+def isattrs(obj):
+ return getattr(obj, "__attrs_attrs__", None) is not None
+
+
+def isiterable(obj):
+ try:
+ iter(obj)
+ return not istext(obj)
+ except TypeError:
+ return False
+
+
+def assertrepr_compare(config, op, left, right):
+ """Return specialised explanations for some operators/operands"""
+ width = 80 - 15 - len(op) - 2 # 15 chars indentation, 1 space around op
+ left_repr = saferepr(left, maxsize=int(width // 2))
+ right_repr = saferepr(right, maxsize=width - len(left_repr))
+
+ summary = u"%s %s %s" % (ecu(left_repr), op, ecu(right_repr))
+
verbose = config.getoption("verbose")
explanation = None
try:
@@ -158,11 +158,11 @@ def assertrepr_compare(config, op, left, right):
explanation = _compare_eq_set(left, right, verbose)
elif isdict(left) and isdict(right):
explanation = _compare_eq_dict(left, right, verbose)
- elif type(left) == type(right) and (isdatacls(left) or isattrs(left)):
- type_fn = (isdatacls, isattrs)
- explanation = _compare_eq_cls(left, right, verbose, type_fn)
- elif verbose > 0:
- explanation = _compare_eq_verbose(left, right)
+ elif type(left) == type(right) and (isdatacls(left) or isattrs(left)):
+ type_fn = (isdatacls, isattrs)
+ explanation = _compare_eq_cls(left, right, verbose, type_fn)
+ elif verbose > 0:
+ explanation = _compare_eq_verbose(left, right)
if isiterable(left) and isiterable(right):
expl = _compare_eq_iterable(left, right, verbose)
if explanation is not None:
@@ -172,13 +172,13 @@ def assertrepr_compare(config, op, left, right):
elif op == "not in":
if istext(left) and istext(right):
explanation = _notin_text(left, right, verbose)
- except outcomes.Exit:
- raise
+ except outcomes.Exit:
+ raise
except Exception:
explanation = [
u"(pytest_assertion plugin: representation of details failed. "
u"Probably an object has a faulty __repr__.)",
- six.text_type(_pytest._code.ExceptionInfo.from_current()),
+ six.text_type(_pytest._code.ExceptionInfo.from_current()),
]
if not explanation:
@@ -187,8 +187,8 @@ def assertrepr_compare(config, op, left, right):
return [summary] + explanation
-def _diff_text(left, right, verbose=0):
- """Return the explanation for the diff between text or bytes.
+def _diff_text(left, right, verbose=0):
+ """Return the explanation for the diff between text or bytes.
Unless --verbose is used this will skip leading and trailing
characters which are identical to keep the diff minimal.
@@ -214,7 +214,7 @@ def _diff_text(left, right, verbose=0):
left = escape_for_readable_diff(left)
if isinstance(right, bytes):
right = escape_for_readable_diff(right)
- if verbose < 1:
+ if verbose < 1:
i = 0 # just in case left or right has zero length
for i in range(min(len(left), len(right))):
if left[i] != right[i]:
@@ -250,19 +250,19 @@ def _diff_text(left, right, verbose=0):
return explanation
-def _compare_eq_verbose(left, right):
- keepends = True
- left_lines = repr(left).splitlines(keepends)
- right_lines = repr(right).splitlines(keepends)
-
- explanation = []
- explanation += [u"-" + line for line in left_lines]
- explanation += [u"+" + line for line in right_lines]
-
- return explanation
-
-
-def _compare_eq_iterable(left, right, verbose=0):
+def _compare_eq_verbose(left, right):
+ keepends = True
+ left_lines = repr(left).splitlines(keepends)
+ right_lines = repr(right).splitlines(keepends)
+
+ explanation = []
+ explanation += [u"-" + line for line in left_lines]
+ explanation += [u"+" + line for line in right_lines]
+
+ return explanation
+
+
+def _compare_eq_iterable(left, right, verbose=0):
if not verbose:
return [u"Use -v to get the full diff"]
# dynamic import to speedup pytest
@@ -285,55 +285,55 @@ def _compare_eq_iterable(left, right, verbose=0):
return explanation
-def _compare_eq_sequence(left, right, verbose=0):
+def _compare_eq_sequence(left, right, verbose=0):
explanation = []
- len_left = len(left)
- len_right = len(right)
- for i in range(min(len_left, len_right)):
+ len_left = len(left)
+ len_right = len(right)
+ for i in range(min(len_left, len_right)):
if left[i] != right[i]:
explanation += [u"At index %s diff: %r != %r" % (i, left[i], right[i])]
break
- len_diff = len_left - len_right
-
- if len_diff:
- if len_diff > 0:
- dir_with_more = "Left"
- extra = saferepr(left[len_right])
- else:
- len_diff = 0 - len_diff
- dir_with_more = "Right"
- extra = saferepr(right[len_left])
-
- if len_diff == 1:
- explanation += [u"%s contains one more item: %s" % (dir_with_more, extra)]
- else:
- explanation += [
- u"%s contains %d more items, first extra item: %s"
- % (dir_with_more, len_diff, extra)
- ]
+ len_diff = len_left - len_right
+
+ if len_diff:
+ if len_diff > 0:
+ dir_with_more = "Left"
+ extra = saferepr(left[len_right])
+ else:
+ len_diff = 0 - len_diff
+ dir_with_more = "Right"
+ extra = saferepr(right[len_left])
+
+ if len_diff == 1:
+ explanation += [u"%s contains one more item: %s" % (dir_with_more, extra)]
+ else:
+ explanation += [
+ u"%s contains %d more items, first extra item: %s"
+ % (dir_with_more, len_diff, extra)
+ ]
return explanation
-def _compare_eq_set(left, right, verbose=0):
+def _compare_eq_set(left, right, verbose=0):
explanation = []
diff_left = left - right
diff_right = right - left
if diff_left:
explanation.append(u"Extra items in the left set:")
for item in diff_left:
- explanation.append(saferepr(item))
+ explanation.append(saferepr(item))
if diff_right:
explanation.append(u"Extra items in the right set:")
for item in diff_right:
- explanation.append(saferepr(item))
+ explanation.append(saferepr(item))
return explanation
-def _compare_eq_dict(left, right, verbose=0):
+def _compare_eq_dict(left, right, verbose=0):
explanation = []
- set_left = set(left)
- set_right = set(right)
- common = set_left.intersection(set_right)
+ set_left = set(left)
+ set_right = set(right)
+ common = set_left.intersection(set_right)
same = {k: left[k] for k in common if left[k] == right[k]}
if same and verbose < 2:
explanation += [u"Omitting %s identical items, use -vv to show" % len(same)]
@@ -344,71 +344,71 @@ def _compare_eq_dict(left, right, verbose=0):
if diff:
explanation += [u"Differing items:"]
for k in diff:
- explanation += [saferepr({k: left[k]}) + " != " + saferepr({k: right[k]})]
- extra_left = set_left - set_right
- len_extra_left = len(extra_left)
- if len_extra_left:
- explanation.append(
- u"Left contains %d more item%s:"
- % (len_extra_left, "" if len_extra_left == 1 else "s")
- )
+ explanation += [saferepr({k: left[k]}) + " != " + saferepr({k: right[k]})]
+ extra_left = set_left - set_right
+ len_extra_left = len(extra_left)
+ if len_extra_left:
+ explanation.append(
+ u"Left contains %d more item%s:"
+ % (len_extra_left, "" if len_extra_left == 1 else "s")
+ )
explanation.extend(
pprint.pformat({k: left[k] for k in extra_left}).splitlines()
)
- extra_right = set_right - set_left
- len_extra_right = len(extra_right)
- if len_extra_right:
- explanation.append(
- u"Right contains %d more item%s:"
- % (len_extra_right, "" if len_extra_right == 1 else "s")
- )
+ extra_right = set_right - set_left
+ len_extra_right = len(extra_right)
+ if len_extra_right:
+ explanation.append(
+ u"Right contains %d more item%s:"
+ % (len_extra_right, "" if len_extra_right == 1 else "s")
+ )
explanation.extend(
pprint.pformat({k: right[k] for k in extra_right}).splitlines()
)
return explanation
-def _compare_eq_cls(left, right, verbose, type_fns):
- isdatacls, isattrs = type_fns
- if isdatacls(left):
- all_fields = left.__dataclass_fields__
- fields_to_check = [field for field, info in all_fields.items() if info.compare]
- elif isattrs(left):
- all_fields = left.__attrs_attrs__
- fields_to_check = [
- field.name for field in all_fields if getattr(field, ATTRS_EQ_FIELD)
- ]
-
- same = []
- diff = []
- for field in fields_to_check:
- if getattr(left, field) == getattr(right, field):
- same.append(field)
- else:
- diff.append(field)
-
- explanation = []
- if same and verbose < 2:
- explanation.append(u"Omitting %s identical items, use -vv to show" % len(same))
- elif same:
- explanation += [u"Matching attributes:"]
- explanation += pprint.pformat(same).splitlines()
- if diff:
- explanation += [u"Differing attributes:"]
- for field in diff:
- explanation += [
- (u"%s: %r != %r") % (field, getattr(left, field), getattr(right, field))
- ]
- return explanation
-
-
-def _notin_text(term, text, verbose=0):
+def _compare_eq_cls(left, right, verbose, type_fns):
+ isdatacls, isattrs = type_fns
+ if isdatacls(left):
+ all_fields = left.__dataclass_fields__
+ fields_to_check = [field for field, info in all_fields.items() if info.compare]
+ elif isattrs(left):
+ all_fields = left.__attrs_attrs__
+ fields_to_check = [
+ field.name for field in all_fields if getattr(field, ATTRS_EQ_FIELD)
+ ]
+
+ same = []
+ diff = []
+ for field in fields_to_check:
+ if getattr(left, field) == getattr(right, field):
+ same.append(field)
+ else:
+ diff.append(field)
+
+ explanation = []
+ if same and verbose < 2:
+ explanation.append(u"Omitting %s identical items, use -vv to show" % len(same))
+ elif same:
+ explanation += [u"Matching attributes:"]
+ explanation += pprint.pformat(same).splitlines()
+ if diff:
+ explanation += [u"Differing attributes:"]
+ for field in diff:
+ explanation += [
+ (u"%s: %r != %r") % (field, getattr(left, field), getattr(right, field))
+ ]
+ return explanation
+
+
+def _notin_text(term, text, verbose=0):
index = text.find(term)
head = text[:index]
tail = text[index + len(term) :]
correct_text = head + tail
diff = _diff_text(correct_text, text, verbose)
- newdiff = [u"%s is contained here:" % saferepr(term, maxsize=42)]
+ newdiff = [u"%s is contained here:" % saferepr(term, maxsize=42)]
for line in diff:
if line.startswith(u"Skipping"):
continue
diff --git a/contrib/python/pytest/py2/_pytest/cacheprovider.py b/contrib/python/pytest/py2/_pytest/cacheprovider.py
index f5c5545484..f1e05676d2 100644
--- a/contrib/python/pytest/py2/_pytest/cacheprovider.py
+++ b/contrib/python/pytest/py2/_pytest/cacheprovider.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""
merged implementation of the cache provider
@@ -21,7 +21,7 @@ import pytest
from .compat import _PY2 as PY2
from .pathlib import Path
from .pathlib import resolve_from_str
-from .pathlib import rm_rf
+from .pathlib import rm_rf
README_CONTENT = u"""\
# pytest cache directory #
@@ -34,14 +34,14 @@ which provides the `--lf` and `--ff` options, as well as the `cache` fixture.
See [the docs](https://docs.pytest.org/en/latest/cache.html) for more information.
"""
-CACHEDIR_TAG_CONTENT = b"""\
-Signature: 8a477f597d28d172789f06886806bc55
-# This file is a cache directory tag created by pytest.
-# For information about cache directory tags, see:
-# http://www.bford.info/cachedir/spec.html
-"""
-
+CACHEDIR_TAG_CONTENT = b"""\
+Signature: 8a477f597d28d172789f06886806bc55
+# This file is a cache directory tag created by pytest.
+# For information about cache directory tags, see:
+# http://www.bford.info/cachedir/spec.html
+"""
+
@attr.s
class Cache(object):
_cachedir = attr.ib(repr=False)
@@ -51,7 +51,7 @@ class Cache(object):
def for_config(cls, config):
cachedir = cls.cache_dir_from_config(config)
if config.getoption("cacheclear") and cachedir.exists():
- rm_rf(cachedir)
+ rm_rf(cachedir)
cachedir.mkdir()
return cls(cachedir, config)
@@ -60,12 +60,12 @@ class Cache(object):
return resolve_from_str(config.getini("cache_dir"), config.rootdir)
def warn(self, fmt, **args):
- from _pytest.warnings import _issue_warning_captured
- from _pytest.warning_types import PytestCacheWarning
+ from _pytest.warnings import _issue_warning_captured
+ from _pytest.warning_types import PytestCacheWarning
- _issue_warning_captured(
- PytestCacheWarning(fmt.format(**args) if args else fmt),
- self._config.hook,
+ _issue_warning_captured(
+ PytestCacheWarning(fmt.format(**args) if args else fmt),
+ self._config.hook,
stacklevel=3,
)
@@ -122,12 +122,12 @@ class Cache(object):
cache_dir_exists_already = True
else:
cache_dir_exists_already = self._cachedir.exists()
- path.parent.mkdir(exist_ok=True, parents=True)
+ path.parent.mkdir(exist_ok=True, parents=True)
except (IOError, OSError):
self.warn("could not create cache path {path}", path=path)
return
- if not cache_dir_exists_already:
- self._ensure_supporting_files()
+ if not cache_dir_exists_already:
+ self._ensure_supporting_files()
try:
f = path.open("wb" if PY2 else "w")
except (IOError, OSError):
@@ -138,17 +138,17 @@ class Cache(object):
def _ensure_supporting_files(self):
"""Create supporting files in the cache dir that are not really part of the cache."""
- readme_path = self._cachedir / "README.md"
- readme_path.write_text(README_CONTENT)
-
- gitignore_path = self._cachedir.joinpath(".gitignore")
- msg = u"# Created by pytest automatically.\n*"
- gitignore_path.write_text(msg, encoding="UTF-8")
+ readme_path = self._cachedir / "README.md"
+ readme_path.write_text(README_CONTENT)
- cachedir_tag_path = self._cachedir.joinpath("CACHEDIR.TAG")
- cachedir_tag_path.write_bytes(CACHEDIR_TAG_CONTENT)
+ gitignore_path = self._cachedir.joinpath(".gitignore")
+ msg = u"# Created by pytest automatically.\n*"
+ gitignore_path.write_text(msg, encoding="UTF-8")
+ cachedir_tag_path = self._cachedir.joinpath("CACHEDIR.TAG")
+ cachedir_tag_path.write_bytes(CACHEDIR_TAG_CONTENT)
+
class LFPlugin(object):
""" Plugin which implements the --lf (run last-failing) option """
@@ -158,37 +158,37 @@ class LFPlugin(object):
self.active = any(config.getoption(key) for key in active_keys)
self.lastfailed = config.cache.get("cache/lastfailed", {})
self._previously_failed_count = None
- self._report_status = None
- self._skipped_files = 0 # count skipped files during collection due to --lf
-
- def last_failed_paths(self):
- """Returns a set with all Paths()s of the previously failed nodeids (cached).
- """
- try:
- return self._last_failed_paths
- except AttributeError:
- rootpath = Path(self.config.rootdir)
- result = {rootpath / nodeid.split("::")[0] for nodeid in self.lastfailed}
- result = {x for x in result if x.exists()}
- self._last_failed_paths = result
- return result
-
- def pytest_ignore_collect(self, path):
- """
- Ignore this file path if we are in --lf mode and it is not in the list of
- previously failed files.
- """
- if self.active and self.config.getoption("lf") and path.isfile():
- last_failed_paths = self.last_failed_paths()
- if last_failed_paths:
- skip_it = Path(path) not in self.last_failed_paths()
- if skip_it:
- self._skipped_files += 1
- return skip_it
-
+ self._report_status = None
+ self._skipped_files = 0 # count skipped files during collection due to --lf
+
+ def last_failed_paths(self):
+ """Returns a set with all Paths()s of the previously failed nodeids (cached).
+ """
+ try:
+ return self._last_failed_paths
+ except AttributeError:
+ rootpath = Path(self.config.rootdir)
+ result = {rootpath / nodeid.split("::")[0] for nodeid in self.lastfailed}
+ result = {x for x in result if x.exists()}
+ self._last_failed_paths = result
+ return result
+
+ def pytest_ignore_collect(self, path):
+ """
+ Ignore this file path if we are in --lf mode and it is not in the list of
+ previously failed files.
+ """
+ if self.active and self.config.getoption("lf") and path.isfile():
+ last_failed_paths = self.last_failed_paths()
+ if last_failed_paths:
+ skip_it = Path(path) not in self.last_failed_paths()
+ if skip_it:
+ self._skipped_files += 1
+ return skip_it
+
def pytest_report_collectionfinish(self):
if self.active and self.config.getoption("verbose") >= 0:
- return "run-last-failure: %s" % self._report_status
+ return "run-last-failure: %s" % self._report_status
def pytest_runtest_logreport(self, report):
if (report.when == "call" and report.passed) or report.skipped:
@@ -206,51 +206,51 @@ class LFPlugin(object):
self.lastfailed[report.nodeid] = True
def pytest_collection_modifyitems(self, session, config, items):
- if not self.active:
- return
-
- if self.lastfailed:
- previously_failed = []
- previously_passed = []
- for item in items:
- if item.nodeid in self.lastfailed:
- previously_failed.append(item)
- else:
- previously_passed.append(item)
- self._previously_failed_count = len(previously_failed)
-
- if not previously_failed:
- # Running a subset of all tests with recorded failures
- # only outside of it.
- self._report_status = "%d known failures not in selected tests" % (
- len(self.lastfailed),
- )
- else:
+ if not self.active:
+ return
+
+ if self.lastfailed:
+ previously_failed = []
+ previously_passed = []
+ for item in items:
+ if item.nodeid in self.lastfailed:
+ previously_failed.append(item)
+ else:
+ previously_passed.append(item)
+ self._previously_failed_count = len(previously_failed)
+
+ if not previously_failed:
+ # Running a subset of all tests with recorded failures
+ # only outside of it.
+ self._report_status = "%d known failures not in selected tests" % (
+ len(self.lastfailed),
+ )
+ else:
if self.config.getoption("lf"):
items[:] = previously_failed
config.hook.pytest_deselected(items=previously_passed)
- else: # --failedfirst
+ else: # --failedfirst
items[:] = previously_failed + previously_passed
-
- noun = "failure" if self._previously_failed_count == 1 else "failures"
- suffix = " first" if self.config.getoption("failedfirst") else ""
- self._report_status = "rerun previous {count} {noun}{suffix}".format(
- count=self._previously_failed_count, suffix=suffix, noun=noun
- )
-
- if self._skipped_files > 0:
- files_noun = "file" if self._skipped_files == 1 else "files"
- self._report_status += " (skipped {files} {files_noun})".format(
- files=self._skipped_files, files_noun=files_noun
- )
- else:
- self._report_status = "no previously failed tests, "
- if self.config.getoption("last_failed_no_failures") == "none":
- self._report_status += "deselecting all items."
+
+ noun = "failure" if self._previously_failed_count == 1 else "failures"
+ suffix = " first" if self.config.getoption("failedfirst") else ""
+ self._report_status = "rerun previous {count} {noun}{suffix}".format(
+ count=self._previously_failed_count, suffix=suffix, noun=noun
+ )
+
+ if self._skipped_files > 0:
+ files_noun = "file" if self._skipped_files == 1 else "files"
+ self._report_status += " (skipped {files} {files_noun})".format(
+ files=self._skipped_files, files_noun=files_noun
+ )
+ else:
+ self._report_status = "no previously failed tests, "
+ if self.config.getoption("last_failed_no_failures") == "none":
+ self._report_status += "deselecting all items."
config.hook.pytest_deselected(items=items)
items[:] = []
- else:
- self._report_status += "not deselecting items."
+ else:
+ self._report_status += "not deselecting items."
def pytest_sessionfinish(self, session):
config = self.config
@@ -325,13 +325,13 @@ def pytest_addoption(parser):
)
group.addoption(
"--cache-show",
- action="append",
- nargs="?",
+ action="append",
+ nargs="?",
dest="cacheshow",
- help=(
- "show cache contents, don't perform collection or tests. "
- "Optional argument: glob (default: '*')."
- ),
+ help=(
+ "show cache contents, don't perform collection or tests. "
+ "Optional argument: glob (default: '*')."
+ ),
)
group.addoption(
"--cache-clear",
@@ -350,7 +350,7 @@ def pytest_addoption(parser):
dest="last_failed_no_failures",
choices=("all", "none"),
default="all",
- help="which tests to run with no previously (known) failures.",
+ help="which tests to run with no previously (known) failures.",
)
@@ -386,7 +386,7 @@ def cache(request):
def pytest_report_header(config):
"""Display cachedir with --cache-show and if non-default."""
- if config.option.verbose > 0 or config.getini("cache_dir") != ".pytest_cache":
+ if config.option.verbose > 0 or config.getini("cache_dir") != ".pytest_cache":
cachedir = config.cache._cachedir
# TODO: evaluate generating upward relative paths
# starting with .., ../.. if sensible
@@ -406,16 +406,16 @@ def cacheshow(config, session):
if not config.cache._cachedir.is_dir():
tw.line("cache is empty")
return 0
-
- glob = config.option.cacheshow[0]
- if glob is None:
- glob = "*"
-
+
+ glob = config.option.cacheshow[0]
+ if glob is None:
+ glob = "*"
+
dummy = object()
basedir = config.cache._cachedir
vdir = basedir / "v"
- tw.sep("-", "cache values for %r" % glob)
- for valpath in sorted(x for x in vdir.rglob(glob) if x.is_file()):
+ tw.sep("-", "cache values for %r" % glob)
+ for valpath in sorted(x for x in vdir.rglob(glob) if x.is_file()):
key = valpath.relative_to(vdir)
val = config.cache.get(key, dummy)
if val is dummy:
@@ -427,8 +427,8 @@ def cacheshow(config, session):
ddir = basedir / "d"
if ddir.is_dir():
- contents = sorted(ddir.rglob(glob))
- tw.sep("-", "cache directories for %r" % glob)
+ contents = sorted(ddir.rglob(glob))
+ tw.sep("-", "cache directories for %r" % glob)
for p in contents:
# if p.check(dir=1):
# print("%s/" % p.relto(basedir))
diff --git a/contrib/python/pytest/py2/_pytest/capture.py b/contrib/python/pytest/py2/_pytest/capture.py
index 68c17772f3..98e2cfa8f8 100644
--- a/contrib/python/pytest/py2/_pytest/capture.py
+++ b/contrib/python/pytest/py2/_pytest/capture.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""
per-test stdout/stderr capturing mechanism.
@@ -18,7 +18,7 @@ from tempfile import TemporaryFile
import six
import pytest
-from _pytest.compat import _PY3
+from _pytest.compat import _PY3
from _pytest.compat import CaptureIO
patchsysdict = {0: "stdin", 1: "stdout", 2: "stderr"}
@@ -85,13 +85,13 @@ class CaptureManager(object):
self._global_capturing = None
self._current_item = None
- def __repr__(self):
- return "<CaptureManager _method=%r _global_capturing=%r _current_item=%r>" % (
- self._method,
- self._global_capturing,
- self._current_item,
- )
-
+ def __repr__(self):
+ return "<CaptureManager _method=%r _global_capturing=%r _current_item=%r>" % (
+ self._method,
+ self._global_capturing,
+ self._current_item,
+ )
+
def _getcapture(self, method):
if method == "fd":
return MultiCapture(out=True, err=True, Capture=FDCapture)
@@ -99,18 +99,18 @@ class CaptureManager(object):
return MultiCapture(out=True, err=True, Capture=SysCapture)
elif method == "no":
return MultiCapture(out=False, err=False, in_=False)
- raise ValueError("unknown capturing method: %r" % method) # pragma: no cover
-
- def is_capturing(self):
- if self.is_globally_capturing():
- return "global"
- capture_fixture = getattr(self._current_item, "_capture_fixture", None)
- if capture_fixture is not None:
- return (
- "fixture %s" % self._current_item._capture_fixture.request.fixturename
- )
- return False
-
+ raise ValueError("unknown capturing method: %r" % method) # pragma: no cover
+
+ def is_capturing(self):
+ if self.is_globally_capturing():
+ return "global"
+ capture_fixture = getattr(self._current_item, "_capture_fixture", None)
+ if capture_fixture is not None:
+ return (
+ "fixture %s" % self._current_item._capture_fixture.request.fixturename
+ )
+ return False
+
# Global capturing control
def is_globally_capturing(self):
@@ -128,25 +128,25 @@ class CaptureManager(object):
self._global_capturing = None
def resume_global_capture(self):
- # During teardown of the python process, and on rare occasions, capture
- # attributes can be `None` while trying to resume global capture.
- if self._global_capturing is not None:
- self._global_capturing.resume_capturing()
+ # During teardown of the python process, and on rare occasions, capture
+ # attributes can be `None` while trying to resume global capture.
+ if self._global_capturing is not None:
+ self._global_capturing.resume_capturing()
def suspend_global_capture(self, in_=False):
cap = getattr(self, "_global_capturing", None)
if cap is not None:
cap.suspend_capturing(in_=in_)
- def suspend(self, in_=False):
- # Need to undo local capsys-et-al if it exists before disabling global capture.
- self.suspend_fixture(self._current_item)
- self.suspend_global_capture(in_)
-
- def resume(self):
- self.resume_global_capture()
- self.resume_fixture(self._current_item)
-
+ def suspend(self, in_=False):
+ # Need to undo local capsys-et-al if it exists before disabling global capture.
+ self.suspend_fixture(self._current_item)
+ self.suspend_global_capture(in_)
+
+ def resume(self):
+ self.resume_global_capture()
+ self.resume_fixture(self._current_item)
+
def read_global_capture(self):
return self._global_capturing.readouterr()
@@ -180,12 +180,12 @@ class CaptureManager(object):
@contextlib.contextmanager
def global_and_fixture_disabled(self):
- """Context manager to temporarily disable global and current fixture capturing."""
- self.suspend()
+ """Context manager to temporarily disable global and current fixture capturing."""
+ self.suspend()
try:
yield
finally:
- self.resume()
+ self.resume()
@contextlib.contextmanager
def item_capture(self, when, item):
@@ -263,11 +263,11 @@ def _ensure_only_one_capture_fixture(request, name):
@pytest.fixture
def capsys(request):
- """Enable text capturing of writes to ``sys.stdout`` and ``sys.stderr``.
-
- The captured output is made available via ``capsys.readouterr()`` method
- calls, which return a ``(out, err)`` namedtuple.
- ``out`` and ``err`` will be ``text`` objects.
+ """Enable text capturing of writes to ``sys.stdout`` and ``sys.stderr``.
+
+ The captured output is made available via ``capsys.readouterr()`` method
+ calls, which return a ``(out, err)`` namedtuple.
+ ``out`` and ``err`` will be ``text`` objects.
"""
_ensure_only_one_capture_fixture(request, "capsys")
with _install_capture_fixture_on_item(request, SysCapture) as fixture:
@@ -276,28 +276,28 @@ def capsys(request):
@pytest.fixture
def capsysbinary(request):
- """Enable bytes capturing of writes to ``sys.stdout`` and ``sys.stderr``.
-
- The captured output is made available via ``capsysbinary.readouterr()``
- method calls, which return a ``(out, err)`` namedtuple.
- ``out`` and ``err`` will be ``bytes`` objects.
+ """Enable bytes capturing of writes to ``sys.stdout`` and ``sys.stderr``.
+
+ The captured output is made available via ``capsysbinary.readouterr()``
+ method calls, which return a ``(out, err)`` namedtuple.
+ ``out`` and ``err`` will be ``bytes`` objects.
"""
_ensure_only_one_capture_fixture(request, "capsysbinary")
# Currently, the implementation uses the python3 specific `.buffer`
# property of CaptureIO.
if sys.version_info < (3,):
- raise request.raiseerror("capsysbinary is only supported on Python 3")
+ raise request.raiseerror("capsysbinary is only supported on Python 3")
with _install_capture_fixture_on_item(request, SysCaptureBinary) as fixture:
yield fixture
@pytest.fixture
def capfd(request):
- """Enable text capturing of writes to file descriptors ``1`` and ``2``.
-
- The captured output is made available via ``capfd.readouterr()`` method
- calls, which return a ``(out, err)`` namedtuple.
- ``out`` and ``err`` will be ``text`` objects.
+ """Enable text capturing of writes to file descriptors ``1`` and ``2``.
+
+ The captured output is made available via ``capfd.readouterr()`` method
+ calls, which return a ``(out, err)`` namedtuple.
+ ``out`` and ``err`` will be ``text`` objects.
"""
_ensure_only_one_capture_fixture(request, "capfd")
if not hasattr(os, "dup"):
@@ -310,11 +310,11 @@ def capfd(request):
@pytest.fixture
def capfdbinary(request):
- """Enable bytes capturing of writes to file descriptors ``1`` and ``2``.
-
- The captured output is made available via ``capfd.readouterr()`` method
- calls, which return a ``(out, err)`` namedtuple.
- ``out`` and ``err`` will be ``byte`` objects.
+ """Enable bytes capturing of writes to file descriptors ``1`` and ``2``.
+
+ The captured output is made available via ``capfd.readouterr()`` method
+ calls, which return a ``(out, err)`` namedtuple.
+ ``out`` and ``err`` will be ``byte`` objects.
"""
_ensure_only_one_capture_fixture(request, "capfdbinary")
if not hasattr(os, "dup"):
@@ -336,9 +336,9 @@ def _install_capture_fixture_on_item(request, capture_class):
"""
request.node._capture_fixture = fixture = CaptureFixture(capture_class, request)
capmanager = request.config.pluginmanager.getplugin("capturemanager")
- # Need to active this fixture right away in case it is being used by another fixture (setup phase).
- # If this fixture is being used only by a test function (call phase), then we wouldn't need this
- # activation, but it doesn't hurt.
+ # Need to active this fixture right away in case it is being used by another fixture (setup phase).
+ # If this fixture is being used only by a test function (call phase), then we wouldn't need this
+ # activation, but it doesn't hurt.
capmanager.activate_fixture(request.node)
yield fixture
fixture.close()
@@ -359,7 +359,7 @@ class CaptureFixture(object):
self._captured_err = self.captureclass.EMPTY_BUFFER
def _start(self):
- if self._capture is None:
+ if self._capture is None:
self._capture = MultiCapture(
out=True, err=True, in_=False, Capture=self.captureclass
)
@@ -376,7 +376,7 @@ class CaptureFixture(object):
def readouterr(self):
"""Read and return the captured output so far, resetting the internal buffer.
- :return: captured content as a namedtuple with ``out`` and ``err`` string attributes
+ :return: captured content as a namedtuple with ``out`` and ``err`` string attributes
"""
captured_out, captured_err = self._captured_out, self._captured_err
if self._capture is not None:
@@ -389,13 +389,13 @@ class CaptureFixture(object):
def _suspend(self):
"""Suspends this fixture's own capturing temporarily."""
- if self._capture is not None:
- self._capture.suspend_capturing()
+ if self._capture is not None:
+ self._capture.suspend_capturing()
def _resume(self):
"""Resumes this fixture's own capturing temporarily."""
- if self._capture is not None:
- self._capture.resume_capturing()
+ if self._capture is not None:
+ self._capture.resume_capturing()
@contextlib.contextmanager
def disabled(self):
@@ -434,10 +434,10 @@ class EncodedFile(object):
def write(self, obj):
if isinstance(obj, six.text_type):
obj = obj.encode(self.encoding, "replace")
- elif _PY3:
- raise TypeError(
- "write() argument must be str, not {}".format(type(obj).__name__)
- )
+ elif _PY3:
+ raise TypeError(
+ "write() argument must be str, not {}".format(type(obj).__name__)
+ )
self.buffer.write(obj)
def writelines(self, linelist):
@@ -449,10 +449,10 @@ class EncodedFile(object):
"""Ensure that file.name is a string."""
return repr(self.buffer)
- @property
- def mode(self):
- return self.buffer.mode.replace("b", "")
-
+ @property
+ def mode(self):
+ return self.buffer.mode.replace("b", "")
+
def __getattr__(self, name):
return getattr(object.__getattribute__(self, "buffer"), name)
@@ -462,7 +462,7 @@ CaptureResult = collections.namedtuple("CaptureResult", ["out", "err"])
class MultiCapture(object):
out = err = in_ = None
- _state = None
+ _state = None
def __init__(self, out=True, err=True, in_=True, Capture=None):
if in_:
@@ -472,17 +472,17 @@ class MultiCapture(object):
if err:
self.err = Capture(2)
- def __repr__(self):
- return "<MultiCapture out=%r err=%r in_=%r _state=%r _in_suspended=%r>" % (
- self.out,
- self.err,
- self.in_,
- self._state,
- getattr(self, "_in_suspended", "<UNSET>"),
- )
-
+ def __repr__(self):
+ return "<MultiCapture out=%r err=%r in_=%r _state=%r _in_suspended=%r>" % (
+ self.out,
+ self.err,
+ self.in_,
+ self._state,
+ getattr(self, "_in_suspended", "<UNSET>"),
+ )
+
def start_capturing(self):
- self._state = "started"
+ self._state = "started"
if self.in_:
self.in_.start()
if self.out:
@@ -500,7 +500,7 @@ class MultiCapture(object):
return out, err
def suspend_capturing(self, in_=False):
- self._state = "suspended"
+ self._state = "suspended"
if self.out:
self.out.suspend()
if self.err:
@@ -510,7 +510,7 @@ class MultiCapture(object):
self._in_suspended = True
def resume_capturing(self):
- self._state = "resumed"
+ self._state = "resumed"
if self.out:
self.out.resume()
if self.err:
@@ -521,9 +521,9 @@ class MultiCapture(object):
def stop_capturing(self):
""" stop capturing and reset capturing streams """
- if self._state == "stopped":
+ if self._state == "stopped":
raise ValueError("was already stopped")
- self._state = "stopped"
+ self._state = "stopped"
if self.out:
self.out.done()
if self.err:
@@ -551,7 +551,7 @@ class FDCaptureBinary(object):
"""
EMPTY_BUFFER = b""
- _state = None
+ _state = None
def __init__(self, targetfd, tmpfile=None):
self.targetfd = targetfd
@@ -578,11 +578,11 @@ class FDCaptureBinary(object):
self.tmpfile_fd = tmpfile.fileno()
def __repr__(self):
- return "<FDCapture %s oldfd=%s _state=%r>" % (
- self.targetfd,
- getattr(self, "targetfd_save", None),
- self._state,
- )
+ return "<FDCapture %s oldfd=%s _state=%r>" % (
+ self.targetfd,
+ getattr(self, "targetfd_save", None),
+ self._state,
+ )
def start(self):
""" Start capturing on targetfd using memorized tmpfile. """
@@ -592,7 +592,7 @@ class FDCaptureBinary(object):
raise ValueError("saved filedescriptor not valid anymore")
os.dup2(self.tmpfile_fd, self.targetfd)
self.syscapture.start()
- self._state = "started"
+ self._state = "started"
def snap(self):
self.tmpfile.seek(0)
@@ -609,17 +609,17 @@ class FDCaptureBinary(object):
os.close(targetfd_save)
self.syscapture.done()
_attempt_to_close_capture_file(self.tmpfile)
- self._state = "done"
+ self._state = "done"
def suspend(self):
self.syscapture.suspend()
os.dup2(self.targetfd_save, self.targetfd)
- self._state = "suspended"
+ self._state = "suspended"
def resume(self):
self.syscapture.resume()
os.dup2(self.tmpfile_fd, self.targetfd)
- self._state = "resumed"
+ self._state = "resumed"
def writeorg(self, data):
""" write to original file descriptor. """
@@ -637,7 +637,7 @@ class FDCapture(FDCaptureBinary):
EMPTY_BUFFER = str()
def snap(self):
- res = super(FDCapture, self).snap()
+ res = super(FDCapture, self).snap()
enc = getattr(self.tmpfile, "encoding", None)
if enc and isinstance(res, bytes):
res = six.text_type(res, enc, "replace")
@@ -647,7 +647,7 @@ class FDCapture(FDCaptureBinary):
class SysCapture(object):
EMPTY_BUFFER = str()
- _state = None
+ _state = None
def __init__(self, fd, tmpfile=None):
name = patchsysdict[fd]
@@ -660,17 +660,17 @@ class SysCapture(object):
tmpfile = CaptureIO()
self.tmpfile = tmpfile
- def __repr__(self):
- return "<SysCapture %s _old=%r, tmpfile=%r _state=%r>" % (
- self.name,
- self._old,
- self.tmpfile,
- self._state,
- )
-
+ def __repr__(self):
+ return "<SysCapture %s _old=%r, tmpfile=%r _state=%r>" % (
+ self.name,
+ self._old,
+ self.tmpfile,
+ self._state,
+ )
+
def start(self):
setattr(sys, self.name, self.tmpfile)
- self._state = "started"
+ self._state = "started"
def snap(self):
res = self.tmpfile.getvalue()
@@ -682,15 +682,15 @@ class SysCapture(object):
setattr(sys, self.name, self._old)
del self._old
_attempt_to_close_capture_file(self.tmpfile)
- self._state = "done"
+ self._state = "done"
def suspend(self):
setattr(sys, self.name, self._old)
- self._state = "suspended"
+ self._state = "suspended"
def resume(self):
setattr(sys, self.name, self.tmpfile)
- self._state = "resumed"
+ self._state = "resumed"
def writeorg(self, data):
self._old.write(data)
@@ -753,11 +753,11 @@ def _colorama_workaround():
first import of colorama while I/O capture is active, colorama will
fail in various ways.
"""
- if sys.platform.startswith("win32"):
- try:
- import colorama # noqa: F401
- except ImportError:
- pass
+ if sys.platform.startswith("win32"):
+ try:
+ import colorama # noqa: F401
+ except ImportError:
+ pass
def _readline_workaround():
@@ -778,11 +778,11 @@ def _readline_workaround():
See https://github.com/pytest-dev/pytest/pull/1281
"""
- if sys.platform.startswith("win32"):
- try:
- import readline # noqa: F401
- except ImportError:
- pass
+ if sys.platform.startswith("win32"):
+ try:
+ import readline # noqa: F401
+ except ImportError:
+ pass
def _py36_windowsconsoleio_workaround(stream):
@@ -834,9 +834,9 @@ def _py36_windowsconsoleio_workaround(stream):
f.line_buffering,
)
- sys.stdin = _reopen_stdio(sys.stdin, "rb")
- sys.stdout = _reopen_stdio(sys.stdout, "wb")
- sys.stderr = _reopen_stdio(sys.stderr, "wb")
+ sys.stdin = _reopen_stdio(sys.stdin, "rb")
+ sys.stdout = _reopen_stdio(sys.stdout, "wb")
+ sys.stderr = _reopen_stdio(sys.stderr, "wb")
def _attempt_to_close_capture_file(f):
diff --git a/contrib/python/pytest/py2/_pytest/compat.py b/contrib/python/pytest/py2/_pytest/compat.py
index e5c3b84667..6b8b597cf6 100644
--- a/contrib/python/pytest/py2/_pytest/compat.py
+++ b/contrib/python/pytest/py2/_pytest/compat.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""
python version compatibility code
"""
@@ -13,13 +13,13 @@ import re
import sys
from contextlib import contextmanager
-import attr
+import attr
import py
import six
from six import text_type
import _pytest
-from _pytest._io.saferepr import saferepr
+from _pytest._io.saferepr import saferepr
from _pytest.outcomes import fail
from _pytest.outcomes import TEST_OUTCOME
@@ -47,11 +47,11 @@ MODULE_NOT_FOUND_ERROR = "ModuleNotFoundError" if PY36 else "ImportError"
if _PY3:
from collections.abc import MutableMapping as MappingMixin
- from collections.abc import Iterable, Mapping, Sequence, Sized
+ from collections.abc import Iterable, Mapping, Sequence, Sized
else:
# those raise DeprecationWarnings in Python >=3.7
from collections import MutableMapping as MappingMixin # noqa
- from collections import Iterable, Mapping, Sequence, Sized # noqa
+ from collections import Iterable, Mapping, Sequence, Sized # noqa
if sys.version_info >= (3, 4):
@@ -62,12 +62,12 @@ else:
return None
-if sys.version_info >= (3, 8):
- from importlib import metadata as importlib_metadata # noqa
-else:
- import importlib_metadata # noqa
-
-
+if sys.version_info >= (3, 8):
+ from importlib import metadata as importlib_metadata # noqa
+else:
+ import importlib_metadata # noqa
+
+
def _format_args(func):
return str(signature(func))
@@ -190,18 +190,18 @@ def get_default_arg_names(function):
)
-_non_printable_ascii_translate_table = {
- i: u"\\x{:02x}".format(i) for i in range(128) if i not in range(32, 127)
-}
-_non_printable_ascii_translate_table.update(
- {ord("\t"): u"\\t", ord("\r"): u"\\r", ord("\n"): u"\\n"}
-)
-
-
-def _translate_non_printable(s):
- return s.translate(_non_printable_ascii_translate_table)
-
-
+_non_printable_ascii_translate_table = {
+ i: u"\\x{:02x}".format(i) for i in range(128) if i not in range(32, 127)
+}
+_non_printable_ascii_translate_table.update(
+ {ord("\t"): u"\\t", ord("\r"): u"\\r", ord("\n"): u"\\n"}
+)
+
+
+def _translate_non_printable(s):
+ return s.translate(_non_printable_ascii_translate_table)
+
+
if _PY3:
STRING_TYPES = bytes, str
UNICODE_TYPES = six.text_type
@@ -241,10 +241,10 @@ if _PY3:
"""
if isinstance(val, bytes):
- ret = _bytes_to_ascii(val)
+ ret = _bytes_to_ascii(val)
else:
- ret = val
- return ret
+ ret = val
+ return ret
else:
@@ -262,12 +262,12 @@ else:
"""
if isinstance(val, bytes):
try:
- ret = val.decode("utf-8")
+ ret = val.decode("utf-8")
except UnicodeDecodeError:
- ret = val.decode("utf-8", "ignore")
+ ret = val.decode("utf-8", "ignore")
else:
- ret = val.encode("utf-8", "replace").decode("utf-8")
- return ret
+ ret = val.encode("utf-8", "replace").decode("utf-8")
+ return ret
class _PytestWrapper(object):
@@ -302,7 +302,7 @@ def get_real_func(obj):
else:
raise ValueError(
("could not find real function of {start}\nstopped at {current}").format(
- start=saferepr(start_obj), current=saferepr(obj)
+ start=saferepr(start_obj), current=saferepr(obj)
)
)
if isinstance(obj, functools.partial):
@@ -378,16 +378,16 @@ if _PY3:
def safe_str(v):
"""returns v as string"""
- try:
- return str(v)
- except UnicodeEncodeError:
- return str(v, encoding="utf-8")
+ try:
+ return str(v)
+ except UnicodeEncodeError:
+ return str(v, encoding="utf-8")
else:
def safe_str(v):
- """returns v as string, converting to utf-8 if necessary"""
+ """returns v as string, converting to utf-8 if necessary"""
try:
return str(v)
except UnicodeError:
@@ -416,8 +416,8 @@ def _setup_collect_fakemodule():
pytest.collect = ModuleType("pytest.collect")
pytest.collect.__all__ = [] # used for setns
- for attribute in COLLECT_FAKEMODULE_ATTRIBUTES:
- setattr(pytest.collect, attribute, getattr(pytest, attribute))
+ for attribute in COLLECT_FAKEMODULE_ATTRIBUTES:
+ setattr(pytest.collect, attribute, getattr(pytest, attribute))
if _PY2:
@@ -465,9 +465,9 @@ if six.PY2:
else:
from functools import lru_cache # noqa: F401
-
-
-if getattr(attr, "__version_info__", ()) >= (19, 2):
- ATTRS_EQ_FIELD = "eq"
-else:
- ATTRS_EQ_FIELD = "cmp"
+
+
+if getattr(attr, "__version_info__", ()) >= (19, 2):
+ ATTRS_EQ_FIELD = "eq"
+else:
+ ATTRS_EQ_FIELD = "cmp"
diff --git a/contrib/python/pytest/py2/_pytest/config/__init__.py b/contrib/python/pytest/py2/_pytest/config/__init__.py
index 0737ff9d51..eb976516db 100644
--- a/contrib/python/pytest/py2/_pytest/config/__init__.py
+++ b/contrib/python/pytest/py2/_pytest/config/__init__.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" command line options, ini-file and conftest.py processing. """
from __future__ import absolute_import
from __future__ import division
@@ -13,10 +13,10 @@ import sys
import types
import warnings
-import attr
+import attr
import py
import six
-from packaging.version import Version
+from packaging.version import Version
from pluggy import HookimplMarker
from pluggy import HookspecMarker
from pluggy import PluginManager
@@ -28,16 +28,16 @@ from .exceptions import PrintHelp
from .exceptions import UsageError
from .findpaths import determine_setup
from .findpaths import exists
-from _pytest import deprecated
+from _pytest import deprecated
from _pytest._code import ExceptionInfo
from _pytest._code import filter_traceback
-from _pytest.compat import importlib_metadata
+from _pytest.compat import importlib_metadata
from _pytest.compat import lru_cache
from _pytest.compat import safe_str
-from _pytest.outcomes import fail
+from _pytest.outcomes import fail
from _pytest.outcomes import Skipped
-from _pytest.pathlib import Path
-from _pytest.warning_types import PytestConfigWarning
+from _pytest.pathlib import Path
+from _pytest.warning_types import PytestConfigWarning
hookimpl = HookimplMarker("pytest")
hookspec = HookspecMarker("pytest")
@@ -117,18 +117,18 @@ def directory_arg(path, optname):
return path
-# Plugins that cannot be disabled via "-p no:X" currently.
-essential_plugins = (
+# Plugins that cannot be disabled via "-p no:X" currently.
+essential_plugins = (
"mark",
"main",
"runner",
- "fixtures",
- "helpconfig", # Provides -p.
-)
-
-default_plugins = essential_plugins + (
+ "fixtures",
+ "helpconfig", # Provides -p.
+)
+
+default_plugins = essential_plugins + (
"python",
- "terminal",
+ "terminal",
"debugging",
"unittest",
"capture",
@@ -149,27 +149,27 @@ default_plugins = essential_plugins + (
"stepwise",
"warnings",
"logging",
- "reports",
+ "reports",
)
builtin_plugins = set(default_plugins)
builtin_plugins.add("pytester")
-def get_config(args=None, plugins=None):
+def get_config(args=None, plugins=None):
# subsequent calls to main will create a fresh instance
pluginmanager = PytestPluginManager()
- config = Config(
- pluginmanager,
- invocation_params=Config.InvocationParams(
- args=args, plugins=plugins, dir=Path().resolve()
- ),
- )
-
- if args is not None:
- # Handle any "-p no:plugin" args.
- pluginmanager.consider_preparse(args)
-
+ config = Config(
+ pluginmanager,
+ invocation_params=Config.InvocationParams(
+ args=args, plugins=plugins, dir=Path().resolve()
+ ),
+ )
+
+ if args is not None:
+ # Handle any "-p no:plugin" args.
+ pluginmanager.consider_preparse(args)
+
for spec in default_plugins:
pluginmanager.import_plugin(spec)
return config
@@ -194,10 +194,10 @@ def _prepareconfig(args=None, plugins=None):
elif isinstance(args, py.path.local):
args = [str(args)]
elif not isinstance(args, (tuple, list)):
- msg = "`args` parameter expected to be a list or tuple of strings, got: {!r} (type: {})"
- raise TypeError(msg.format(args, type(args)))
+ msg = "`args` parameter expected to be a list or tuple of strings, got: {!r} (type: {})"
+ raise TypeError(msg.format(args, type(args)))
- config = get_config(args, plugins)
+ config = get_config(args, plugins)
pluginmanager = config.pluginmanager
try:
if plugins:
@@ -207,9 +207,9 @@ def _prepareconfig(args=None, plugins=None):
else:
pluginmanager.register(plugin)
if warning:
- from _pytest.warnings import _issue_warning_captured
+ from _pytest.warnings import _issue_warning_captured
- _issue_warning_captured(warning, hook=config.hook, stacklevel=4)
+ _issue_warning_captured(warning, hook=config.hook, stacklevel=4)
return pluginmanager.hook.pytest_cmdline_parse(
pluginmanager=pluginmanager, args=args
)
@@ -263,7 +263,7 @@ class PytestPluginManager(PluginManager):
Use :py:meth:`pluggy.PluginManager.add_hookspecs <PluginManager.add_hookspecs>`
instead.
"""
- warnings.warn(deprecated.PLUGIN_MANAGER_ADDHOOKS, stacklevel=2)
+ warnings.warn(deprecated.PLUGIN_MANAGER_ADDHOOKS, stacklevel=2)
return self.add_hookspecs(module_or_class)
def parse_hookimpl_opts(self, plugin, name):
@@ -272,8 +272,8 @@ class PytestPluginManager(PluginManager):
# (see issue #1073)
if not name.startswith("pytest_"):
return
- # ignore names which can not be hooks
- if name == "pytest_plugins":
+ # ignore names which can not be hooks
+ if name == "pytest_plugins":
return
method = getattr(plugin, name)
@@ -286,13 +286,13 @@ class PytestPluginManager(PluginManager):
# collect unmarked hooks as long as they have the `pytest_' prefix
if opts is None and name.startswith("pytest_"):
opts = {}
- if opts is not None:
- # TODO: DeprecationWarning, people should use hookimpl
- # https://github.com/pytest-dev/pytest/issues/4562
- known_marks = {m.name for m in getattr(method, "pytestmark", [])}
+ if opts is not None:
+ # TODO: DeprecationWarning, people should use hookimpl
+ # https://github.com/pytest-dev/pytest/issues/4562
+ known_marks = {m.name for m in getattr(method, "pytestmark", [])}
for name in ("tryfirst", "trylast", "optionalhook", "hookwrapper"):
- opts.setdefault(name, hasattr(method, name) or name in known_marks)
+ opts.setdefault(name, hasattr(method, name) or name in known_marks)
return opts
def parse_hookspec_opts(self, module_or_class, name):
@@ -301,27 +301,27 @@ class PytestPluginManager(PluginManager):
)
if opts is None:
method = getattr(module_or_class, name)
-
+
if name.startswith("pytest_"):
- # todo: deprecate hookspec hacks
- # https://github.com/pytest-dev/pytest/issues/4562
- known_marks = {m.name for m in getattr(method, "pytestmark", [])}
+ # todo: deprecate hookspec hacks
+ # https://github.com/pytest-dev/pytest/issues/4562
+ known_marks = {m.name for m in getattr(method, "pytestmark", [])}
opts = {
- "firstresult": hasattr(method, "firstresult")
- or "firstresult" in known_marks,
- "historic": hasattr(method, "historic")
- or "historic" in known_marks,
+ "firstresult": hasattr(method, "firstresult")
+ or "firstresult" in known_marks,
+ "historic": hasattr(method, "historic")
+ or "historic" in known_marks,
}
return opts
def register(self, plugin, name=None):
if name in ["pytest_catchlog", "pytest_capturelog"]:
- warnings.warn(
- PytestConfigWarning(
- "{} plugin has been merged into the core, "
- "please remove it from your requirements.".format(
- name.replace("_", "-")
- )
+ warnings.warn(
+ PytestConfigWarning(
+ "{} plugin has been merged into the core, "
+ "please remove it from your requirements.".format(
+ name.replace("_", "-")
+ )
)
)
return
@@ -425,10 +425,10 @@ class PytestPluginManager(PluginManager):
continue
conftestpath = parent.join("conftest.py")
if conftestpath.isfile():
- # Use realpath to avoid loading the same conftest twice
- # with build systems that create build directories containing
- # symlinks to actual files.
- mod = self._importconftest(conftestpath.realpath())
+ # Use realpath to avoid loading the same conftest twice
+ # with build systems that create build directories containing
+ # symlinks to actual files.
+ mod = self._importconftest(conftestpath.realpath())
clist.append(mod)
self._dirpath2confmods[directory] = clist
return clist
@@ -457,14 +457,14 @@ class PytestPluginManager(PluginManager):
and not self._using_pyargs
):
from _pytest.deprecated import (
- PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST,
+ PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST,
)
- fail(
- PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST.format(
- conftestpath, self._confcutdir
- ),
- pytrace=False,
+ fail(
+ PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST.format(
+ conftestpath, self._confcutdir
+ ),
+ pytrace=False,
)
except Exception:
raise ConftestImportFailure(conftestpath, sys.exc_info())
@@ -487,30 +487,30 @@ class PytestPluginManager(PluginManager):
#
def consider_preparse(self, args):
- i = 0
- n = len(args)
- while i < n:
- opt = args[i]
- i += 1
- if isinstance(opt, six.string_types):
- if opt == "-p":
- try:
- parg = args[i]
- except IndexError:
- return
- i += 1
- elif opt.startswith("-p"):
- parg = opt[2:]
- else:
- continue
- self.consider_pluginarg(parg)
+ i = 0
+ n = len(args)
+ while i < n:
+ opt = args[i]
+ i += 1
+ if isinstance(opt, six.string_types):
+ if opt == "-p":
+ try:
+ parg = args[i]
+ except IndexError:
+ return
+ i += 1
+ elif opt.startswith("-p"):
+ parg = opt[2:]
+ else:
+ continue
+ self.consider_pluginarg(parg)
def consider_pluginarg(self, arg):
if arg.startswith("no:"):
name = arg[3:]
- if name in essential_plugins:
- raise UsageError("plugin %s cannot be disabled" % name)
-
+ if name in essential_plugins:
+ raise UsageError("plugin %s cannot be disabled" % name)
+
# PR #4304 : remove stepwise if cacheprovider is blocked
if name == "cacheprovider":
self.set_blocked("stepwise")
@@ -520,15 +520,15 @@ class PytestPluginManager(PluginManager):
if not name.startswith("pytest_"):
self.set_blocked("pytest_" + name)
else:
- name = arg
- # Unblock the plugin. None indicates that it has been blocked.
- # There is no interface with pluggy for this.
- if self._name2plugin.get(name, -1) is None:
- del self._name2plugin[name]
- if not name.startswith("pytest_"):
- if self._name2plugin.get("pytest_" + name, -1) is None:
- del self._name2plugin["pytest_" + name]
- self.import_plugin(arg, consider_entry_points=True)
+ name = arg
+ # Unblock the plugin. None indicates that it has been blocked.
+ # There is no interface with pluggy for this.
+ if self._name2plugin.get(name, -1) is None:
+ del self._name2plugin[name]
+ if not name.startswith("pytest_"):
+ if self._name2plugin.get("pytest_" + name, -1) is None:
+ del self._name2plugin["pytest_" + name]
+ self.import_plugin(arg, consider_entry_points=True)
def consider_conftest(self, conftestmodule):
self.register(conftestmodule, name=conftestmodule.__file__)
@@ -544,30 +544,30 @@ class PytestPluginManager(PluginManager):
for import_spec in plugins:
self.import_plugin(import_spec)
- def import_plugin(self, modname, consider_entry_points=False):
- """
- Imports a plugin with ``modname``. If ``consider_entry_points`` is True, entry point
- names are also considered to find a plugin.
- """
+ def import_plugin(self, modname, consider_entry_points=False):
+ """
+ Imports a plugin with ``modname``. If ``consider_entry_points`` is True, entry point
+ names are also considered to find a plugin.
+ """
# most often modname refers to builtin modules, e.g. "pytester",
# "terminal" or "capture". Those plugins are registered under their
# basename for historic purposes but must be imported with the
# _pytest prefix.
- assert isinstance(modname, six.string_types), (
+ assert isinstance(modname, six.string_types), (
"module name as text required, got %r" % modname
)
modname = str(modname)
if self.is_blocked(modname) or self.get_plugin(modname) is not None:
return
-
- importspec = "_pytest." + modname if modname in builtin_plugins else modname
+
+ importspec = "_pytest." + modname if modname in builtin_plugins else modname
self.rewrite_hook.mark_rewrite(importspec)
-
- if consider_entry_points:
- loaded = self.load_setuptools_entrypoints("pytest11", name=modname)
- if loaded:
- return
-
+
+ if consider_entry_points:
+ loaded = self.load_setuptools_entrypoints("pytest11", name=modname)
+ if loaded:
+ return
+
try:
__import__(importspec)
except ImportError as e:
@@ -575,19 +575,19 @@ class PytestPluginManager(PluginManager):
modname,
safe_str(e.args[0]),
)
- new_exc = ImportError(new_exc_message)
- tb = sys.exc_info()[2]
+ new_exc = ImportError(new_exc_message)
+ tb = sys.exc_info()[2]
- six.reraise(ImportError, new_exc, tb)
+ six.reraise(ImportError, new_exc, tb)
except Skipped as e:
- from _pytest.warnings import _issue_warning_captured
-
- _issue_warning_captured(
- PytestConfigWarning("skipped plugin %r: %s" % (modname, e.msg)),
- self.hook,
- stacklevel=1,
- )
+ from _pytest.warnings import _issue_warning_captured
+
+ _issue_warning_captured(
+ PytestConfigWarning("skipped plugin %r: %s" % (modname, e.msg)),
+ self.hook,
+ stacklevel=1,
+ )
else:
mod = sys.modules[importspec]
self.register(mod, modname)
@@ -601,8 +601,8 @@ def _get_plugin_specs_as_list(specs):
which case it is returned as a list. Specs can also be `None` in which case an
empty list is returned.
"""
- if specs is not None and not isinstance(specs, types.ModuleType):
- if isinstance(specs, six.string_types):
+ if specs is not None and not isinstance(specs, types.ModuleType):
+ if isinstance(specs, six.string_types):
specs = specs.split(",") if specs else []
if not isinstance(specs, (list, tuple)):
raise UsageError(
@@ -629,117 +629,117 @@ notset = Notset()
def _iter_rewritable_modules(package_files):
- """
- Given an iterable of file names in a source distribution, return the "names" that should
- be marked for assertion rewrite (for example the package "pytest_mock/__init__.py" should
- be added as "pytest_mock" in the assertion rewrite mechanism.
-
- This function has to deal with dist-info based distributions and egg based distributions
- (which are still very much in use for "editable" installs).
-
- Here are the file names as seen in a dist-info based distribution:
-
- pytest_mock/__init__.py
- pytest_mock/_version.py
- pytest_mock/plugin.py
- pytest_mock.egg-info/PKG-INFO
-
- Here are the file names as seen in an egg based distribution:
-
- src/pytest_mock/__init__.py
- src/pytest_mock/_version.py
- src/pytest_mock/plugin.py
- src/pytest_mock.egg-info/PKG-INFO
- LICENSE
- setup.py
-
- We have to take in account those two distribution flavors in order to determine which
- names should be considered for assertion rewriting.
-
- More information:
- https://github.com/pytest-dev/pytest-mock/issues/167
- """
- package_files = list(package_files)
- seen_some = False
+ """
+ Given an iterable of file names in a source distribution, return the "names" that should
+ be marked for assertion rewrite (for example the package "pytest_mock/__init__.py" should
+ be added as "pytest_mock" in the assertion rewrite mechanism.
+
+ This function has to deal with dist-info based distributions and egg based distributions
+ (which are still very much in use for "editable" installs).
+
+ Here are the file names as seen in a dist-info based distribution:
+
+ pytest_mock/__init__.py
+ pytest_mock/_version.py
+ pytest_mock/plugin.py
+ pytest_mock.egg-info/PKG-INFO
+
+ Here are the file names as seen in an egg based distribution:
+
+ src/pytest_mock/__init__.py
+ src/pytest_mock/_version.py
+ src/pytest_mock/plugin.py
+ src/pytest_mock.egg-info/PKG-INFO
+ LICENSE
+ setup.py
+
+ We have to take in account those two distribution flavors in order to determine which
+ names should be considered for assertion rewriting.
+
+ More information:
+ https://github.com/pytest-dev/pytest-mock/issues/167
+ """
+ package_files = list(package_files)
+ seen_some = False
for fn in package_files:
is_simple_module = "/" not in fn and fn.endswith(".py")
is_package = fn.count("/") == 1 and fn.endswith("__init__.py")
if is_simple_module:
module_name, _ = os.path.splitext(fn)
- # we ignore "setup.py" at the root of the distribution
- if module_name != "setup":
- seen_some = True
- yield module_name
+ # we ignore "setup.py" at the root of the distribution
+ if module_name != "setup":
+ seen_some = True
+ yield module_name
elif is_package:
package_name = os.path.dirname(fn)
- seen_some = True
+ seen_some = True
yield package_name
- if not seen_some:
- # at this point we did not find any packages or modules suitable for assertion
- # rewriting, so we try again by stripping the first path component (to account for
- # "src" based source trees for example)
- # this approach lets us have the common case continue to be fast, as egg-distributions
- # are rarer
- new_package_files = []
- for fn in package_files:
- parts = fn.split("/")
- new_fn = "/".join(parts[1:])
- if new_fn:
- new_package_files.append(new_fn)
- if new_package_files:
- for _module in _iter_rewritable_modules(new_package_files):
- yield _module
-
-
+ if not seen_some:
+ # at this point we did not find any packages or modules suitable for assertion
+ # rewriting, so we try again by stripping the first path component (to account for
+ # "src" based source trees for example)
+ # this approach lets us have the common case continue to be fast, as egg-distributions
+ # are rarer
+ new_package_files = []
+ for fn in package_files:
+ parts = fn.split("/")
+ new_fn = "/".join(parts[1:])
+ if new_fn:
+ new_package_files.append(new_fn)
+ if new_package_files:
+ for _module in _iter_rewritable_modules(new_package_files):
+ yield _module
+
+
class Config(object):
- """
- Access to configuration values, pluginmanager and plugin hooks.
-
- :ivar PytestPluginManager pluginmanager: the plugin manager handles plugin registration and hook invocation.
-
- :ivar argparse.Namespace option: access to command line option as attributes.
-
- :ivar InvocationParams invocation_params:
-
- Object containing the parameters regarding the ``pytest.main``
- invocation.
- Contains the followinig read-only attributes:
- * ``args``: list of command-line arguments as passed to ``pytest.main()``.
- * ``plugins``: list of extra plugins, might be None
- * ``dir``: directory where ``pytest.main()`` was invoked from.
- """
-
- @attr.s(frozen=True)
- class InvocationParams(object):
- """Holds parameters passed during ``pytest.main()``
-
- .. note::
-
- Currently the environment variable PYTEST_ADDOPTS is also handled by
- pytest implicitly, not being part of the invocation.
-
- Plugins accessing ``InvocationParams`` must be aware of that.
- """
-
- args = attr.ib()
- plugins = attr.ib()
- dir = attr.ib()
-
- def __init__(self, pluginmanager, invocation_params=None, *args):
- from .argparsing import Parser, FILE_OR_DIR
-
- if invocation_params is None:
- invocation_params = self.InvocationParams(
- args=(), plugins=None, dir=Path().resolve()
- )
-
+ """
+ Access to configuration values, pluginmanager and plugin hooks.
+
+ :ivar PytestPluginManager pluginmanager: the plugin manager handles plugin registration and hook invocation.
+
+ :ivar argparse.Namespace option: access to command line option as attributes.
+
+ :ivar InvocationParams invocation_params:
+
+ Object containing the parameters regarding the ``pytest.main``
+ invocation.
+ Contains the followinig read-only attributes:
+ * ``args``: list of command-line arguments as passed to ``pytest.main()``.
+ * ``plugins``: list of extra plugins, might be None
+ * ``dir``: directory where ``pytest.main()`` was invoked from.
+ """
+
+ @attr.s(frozen=True)
+ class InvocationParams(object):
+ """Holds parameters passed during ``pytest.main()``
+
+ .. note::
+
+ Currently the environment variable PYTEST_ADDOPTS is also handled by
+ pytest implicitly, not being part of the invocation.
+
+ Plugins accessing ``InvocationParams`` must be aware of that.
+ """
+
+ args = attr.ib()
+ plugins = attr.ib()
+ dir = attr.ib()
+
+ def __init__(self, pluginmanager, invocation_params=None, *args):
+ from .argparsing import Parser, FILE_OR_DIR
+
+ if invocation_params is None:
+ invocation_params = self.InvocationParams(
+ args=(), plugins=None, dir=Path().resolve()
+ )
+
#: access to command line option as attributes.
#: (deprecated), use :py:func:`getoption() <_pytest.config.Config.getoption>` instead
self.option = argparse.Namespace()
- self.invocation_params = invocation_params
-
+ self.invocation_params = invocation_params
+
_a = FILE_OR_DIR
self._parser = Parser(
usage="%%(prog)s [options] [%s] [%s] [...]" % (_a, _a),
@@ -755,12 +755,12 @@ class Config(object):
self._cleanup = []
self.pluginmanager.register(self, "pytestconfig")
self._configured = False
- self.hook.pytest_addoption.call_historic(kwargs=dict(parser=self._parser))
+ self.hook.pytest_addoption.call_historic(kwargs=dict(parser=self._parser))
- @property
- def invocation_dir(self):
- """Backward compatibility"""
- return py.path.local(str(self.invocation_params.dir))
+ @property
+ def invocation_dir(self):
+ """Backward compatibility"""
+ return py.path.local(str(self.invocation_params.dir))
def add_cleanup(self, func):
""" Add a function to be called when the config object gets out of
@@ -781,35 +781,35 @@ class Config(object):
fin = self._cleanup.pop()
fin()
- def get_terminal_writer(self):
- return self.pluginmanager.get_plugin("terminalreporter")._tw
+ def get_terminal_writer(self):
+ return self.pluginmanager.get_plugin("terminalreporter")._tw
- def pytest_cmdline_parse(self, pluginmanager, args):
- try:
- self.parse(args)
- except UsageError:
-
- # Handle --version and --help here in a minimal fashion.
- # This gets done via helpconfig normally, but its
- # pytest_cmdline_main is not called in case of errors.
- if getattr(self.option, "version", False) or "--version" in args:
- from _pytest.helpconfig import showversion
-
- showversion(self)
- elif (
- getattr(self.option, "help", False) or "--help" in args or "-h" in args
- ):
- self._parser._getparser().print_help()
- sys.stdout.write(
- "\nNOTE: displaying only minimal help due to UsageError.\n\n"
- )
+ def pytest_cmdline_parse(self, pluginmanager, args):
+ try:
+ self.parse(args)
+ except UsageError:
- raise
+ # Handle --version and --help here in a minimal fashion.
+ # This gets done via helpconfig normally, but its
+ # pytest_cmdline_main is not called in case of errors.
+ if getattr(self.option, "version", False) or "--version" in args:
+ from _pytest.helpconfig import showversion
+
+ showversion(self)
+ elif (
+ getattr(self.option, "help", False) or "--help" in args or "-h" in args
+ ):
+ self._parser._getparser().print_help()
+ sys.stdout.write(
+ "\nNOTE: displaying only minimal help due to UsageError.\n\n"
+ )
+
+ raise
return self
def notify_exception(self, excinfo, option=None):
- if option and getattr(option, "fulltrace", False):
+ if option and getattr(option, "fulltrace", False):
style = "long"
else:
style = "native"
@@ -832,7 +832,7 @@ class Config(object):
@classmethod
def fromdictargs(cls, option_dict, args):
""" constructor useable for subprocesses. """
- config = get_config(args)
+ config = get_config(args)
config.option.__dict__.update(option_dict)
config.parse(args, addopts=False)
for x in config.option.plugins:
@@ -876,7 +876,7 @@ class Config(object):
by the importhook.
"""
ns, unknown_args = self._parser.parse_known_and_unknown_args(args)
- mode = getattr(ns, "assertmode", "plain")
+ mode = getattr(ns, "assertmode", "plain")
if mode == "rewrite":
try:
hook = _pytest.assertion.install_importhook(self)
@@ -899,41 +899,41 @@ class Config(object):
return
package_files = (
- str(file)
- for dist in importlib_metadata.distributions()
- if any(ep.group == "pytest11" for ep in dist.entry_points)
- for file in dist.files or []
+ str(file)
+ for dist in importlib_metadata.distributions()
+ if any(ep.group == "pytest11" for ep in dist.entry_points)
+ for file in dist.files or []
)
for name in _iter_rewritable_modules(package_files):
hook.mark_rewrite(name)
- def _validate_args(self, args, via):
- """Validate known args."""
- self._parser._config_source_hint = via
- try:
- self._parser.parse_known_and_unknown_args(
- args, namespace=copy.copy(self.option)
- )
- finally:
- del self._parser._config_source_hint
-
- return args
-
+ def _validate_args(self, args, via):
+ """Validate known args."""
+ self._parser._config_source_hint = via
+ try:
+ self._parser.parse_known_and_unknown_args(
+ args, namespace=copy.copy(self.option)
+ )
+ finally:
+ del self._parser._config_source_hint
+
+ return args
+
def _preparse(self, args, addopts=True):
if addopts:
- env_addopts = os.environ.get("PYTEST_ADDOPTS", "")
- if len(env_addopts):
- args[:] = (
- self._validate_args(shlex.split(env_addopts), "via PYTEST_ADDOPTS")
- + args
- )
+ env_addopts = os.environ.get("PYTEST_ADDOPTS", "")
+ if len(env_addopts):
+ args[:] = (
+ self._validate_args(shlex.split(env_addopts), "via PYTEST_ADDOPTS")
+ + args
+ )
self._initini(args)
if addopts:
- args[:] = (
- self._validate_args(self.getini("addopts"), "via addopts config") + args
- )
-
+ args[:] = (
+ self._validate_args(self.getini("addopts"), "via addopts config") + args
+ )
+
self._checkversion()
self._consider_importhook(args)
self.pluginmanager.consider_preparse(args)
@@ -957,15 +957,15 @@ class Config(object):
if ns.help or ns.version:
# we don't want to prevent --help/--version to work
# so just let is pass and print a warning at the end
- from _pytest.warnings import _issue_warning_captured
-
- _issue_warning_captured(
- PytestConfigWarning(
- "could not load initial conftests: {}".format(e.path)
- ),
- self.hook,
- stacklevel=2,
- )
+ from _pytest.warnings import _issue_warning_captured
+
+ _issue_warning_captured(
+ PytestConfigWarning(
+ "could not load initial conftests: {}".format(e.path)
+ ),
+ self.hook,
+ stacklevel=2,
+ )
else:
raise
@@ -974,7 +974,7 @@ class Config(object):
minver = self.inicfg.get("minversion", None)
if minver:
- if Version(minver) > Version(pytest.__version__):
+ if Version(minver) > Version(pytest.__version__):
raise pytest.UsageError(
"%s:%d: requires pytest-%s, actual pytest-%s'"
% (
diff --git a/contrib/python/pytest/py2/_pytest/config/argparsing.py b/contrib/python/pytest/py2/_pytest/config/argparsing.py
index 37fb772db9..26b5bd88dd 100644
--- a/contrib/python/pytest/py2/_pytest/config/argparsing.py
+++ b/contrib/python/pytest/py2/_pytest/config/argparsing.py
@@ -1,11 +1,11 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
import argparse
import warnings
import py
import six
-from _pytest.config.exceptions import UsageError
+from _pytest.config.exceptions import UsageError
FILE_OR_DIR = "file_or_dir"
@@ -17,8 +17,8 @@ class Parser(object):
there's an error processing the command line arguments.
"""
- prog = None
-
+ prog = None
+
def __init__(self, usage=None, processopt=None):
self._anonymous = OptionGroup("custom options", parser=self)
self._groups = []
@@ -83,7 +83,7 @@ class Parser(object):
def _getparser(self):
from _pytest._argcomplete import filescompleter
- optparser = MyOptionParser(self, self.extra_info, prog=self.prog)
+ optparser = MyOptionParser(self, self.extra_info, prog=self.prog)
groups = self._groups + [self._anonymous]
for group in groups:
if group.options:
@@ -320,13 +320,13 @@ class OptionGroup(object):
class MyOptionParser(argparse.ArgumentParser):
- def __init__(self, parser, extra_info=None, prog=None):
+ def __init__(self, parser, extra_info=None, prog=None):
if not extra_info:
extra_info = {}
self._parser = parser
argparse.ArgumentParser.__init__(
self,
- prog=prog,
+ prog=prog,
usage=parser._usage,
add_help=False,
formatter_class=DropShorterLongHelpFormatter,
@@ -336,14 +336,14 @@ class MyOptionParser(argparse.ArgumentParser):
self.extra_info = extra_info
def error(self, message):
- """Transform argparse error message into UsageError."""
- msg = "%s: error: %s" % (self.prog, message)
-
- if hasattr(self._parser, "_config_source_hint"):
- msg = "%s (%s)" % (msg, self._parser._config_source_hint)
+ """Transform argparse error message into UsageError."""
+ msg = "%s: error: %s" % (self.prog, message)
- raise UsageError(self.format_usage() + msg)
+ if hasattr(self._parser, "_config_source_hint"):
+ msg = "%s (%s)" % (msg, self._parser._config_source_hint)
+ raise UsageError(self.format_usage() + msg)
+
def parse_args(self, args=None, namespace=None):
"""allow splitting of positional arguments"""
args, argv = self.parse_known_args(args, namespace)
diff --git a/contrib/python/pytest/py2/_pytest/config/exceptions.py b/contrib/python/pytest/py2/_pytest/config/exceptions.py
index bf58fde5db..eb902229be 100644
--- a/contrib/python/pytest/py2/_pytest/config/exceptions.py
+++ b/contrib/python/pytest/py2/_pytest/config/exceptions.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
class UsageError(Exception):
""" error in pytest usage or invocation"""
diff --git a/contrib/python/pytest/py2/_pytest/config/findpaths.py b/contrib/python/pytest/py2/_pytest/config/findpaths.py
index e6779b289b..0af3e525a6 100644
--- a/contrib/python/pytest/py2/_pytest/config/findpaths.py
+++ b/contrib/python/pytest/py2/_pytest/config/findpaths.py
@@ -1,10 +1,10 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
import os
import py
from .exceptions import UsageError
-from _pytest.outcomes import fail
+from _pytest.outcomes import fail
def exists(path, ignore=EnvironmentError):
@@ -33,24 +33,24 @@ def getcfg(args, config=None):
for inibasename in inibasenames:
p = base.join(inibasename)
if exists(p):
- try:
- iniconfig = py.iniconfig.IniConfig(p)
- except py.iniconfig.ParseError as exc:
- raise UsageError(str(exc))
+ try:
+ iniconfig = py.iniconfig.IniConfig(p)
+ except py.iniconfig.ParseError as exc:
+ raise UsageError(str(exc))
if (
inibasename == "setup.cfg"
and "tool:pytest" in iniconfig.sections
):
return base, p, iniconfig["tool:pytest"]
- elif "pytest" in iniconfig.sections:
- if inibasename == "setup.cfg" and config is not None:
-
- fail(
- CFG_PYTEST_SECTION.format(filename=inibasename),
- pytrace=False,
- )
- return base, p, iniconfig["pytest"]
+ elif "pytest" in iniconfig.sections:
+ if inibasename == "setup.cfg" and config is not None:
+
+ fail(
+ CFG_PYTEST_SECTION.format(filename=inibasename),
+ pytrace=False,
+ )
+ return base, p, iniconfig["pytest"]
elif inibasename == "pytest.ini":
# allowed to be empty
return base, p, {}
@@ -114,40 +114,40 @@ def determine_setup(inifile, args, rootdir_cmd_arg=None, config=None):
if is_cfg_file and section == "pytest" and config is not None:
from _pytest.deprecated import CFG_PYTEST_SECTION
- fail(
- CFG_PYTEST_SECTION.format(filename=str(inifile)), pytrace=False
+ fail(
+ CFG_PYTEST_SECTION.format(filename=str(inifile)), pytrace=False
)
break
except KeyError:
inicfg = None
- if rootdir_cmd_arg is None:
- rootdir = get_common_ancestor(dirs)
+ if rootdir_cmd_arg is None:
+ rootdir = get_common_ancestor(dirs)
else:
ancestor = get_common_ancestor(dirs)
rootdir, inifile, inicfg = getcfg([ancestor], config=config)
- if rootdir is None and rootdir_cmd_arg is None:
- for possible_rootdir in ancestor.parts(reverse=True):
- if possible_rootdir.join("setup.py").exists():
- rootdir = possible_rootdir
+ if rootdir is None and rootdir_cmd_arg is None:
+ for possible_rootdir in ancestor.parts(reverse=True):
+ if possible_rootdir.join("setup.py").exists():
+ rootdir = possible_rootdir
break
else:
- if dirs != [ancestor]:
- rootdir, inifile, inicfg = getcfg(dirs, config=config)
+ if dirs != [ancestor]:
+ rootdir, inifile, inicfg = getcfg(dirs, config=config)
if rootdir is None:
- if config is not None:
- cwd = config.invocation_dir
- else:
- cwd = py.path.local()
- rootdir = get_common_ancestor([cwd, ancestor])
+ if config is not None:
+ cwd = config.invocation_dir
+ else:
+ cwd = py.path.local()
+ rootdir = get_common_ancestor([cwd, ancestor])
is_fs_root = os.path.splitdrive(str(rootdir))[1] == "/"
if is_fs_root:
rootdir = ancestor
if rootdir_cmd_arg:
- rootdir = py.path.local(os.path.expandvars(rootdir_cmd_arg))
- if not rootdir.isdir():
+ rootdir = py.path.local(os.path.expandvars(rootdir_cmd_arg))
+ if not rootdir.isdir():
raise UsageError(
"Directory '{}' not found. Check your '--rootdir' option.".format(
- rootdir
+ rootdir
)
)
return rootdir, inifile, inicfg or {}
diff --git a/contrib/python/pytest/py2/_pytest/debugging.py b/contrib/python/pytest/py2/_pytest/debugging.py
index bc114c8683..1bbca0f7bb 100644
--- a/contrib/python/pytest/py2/_pytest/debugging.py
+++ b/contrib/python/pytest/py2/_pytest/debugging.py
@@ -1,18 +1,18 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" interactive debugging with PDB, the Python Debugger. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
-import argparse
+import argparse
import pdb
import sys
from doctest import UnexpectedException
from _pytest import outcomes
from _pytest.config import hookimpl
-from _pytest.config.exceptions import UsageError
+from _pytest.config.exceptions import UsageError
def import_readline():
@@ -51,17 +51,17 @@ def tty():
sys.path = old_sys_path
-def _validate_usepdb_cls(value):
- """Validate syntax of --pdbcls option."""
- try:
- modname, classname = value.split(":")
- except ValueError:
- raise argparse.ArgumentTypeError(
- "{!r} is not in the format 'modname:classname'".format(value)
- )
- return (modname, classname)
-
-
+def _validate_usepdb_cls(value):
+ """Validate syntax of --pdbcls option."""
+ try:
+ modname, classname = value.split(":")
+ except ValueError:
+ raise argparse.ArgumentTypeError(
+ "{!r} is not in the format 'modname:classname'".format(value)
+ )
+ return (modname, classname)
+
+
def pytest_addoption(parser):
group = parser.getgroup("general")
group._addoption(
@@ -74,7 +74,7 @@ def pytest_addoption(parser):
"--pdbcls",
dest="usepdb_cls",
metavar="modulename:classname",
- type=_validate_usepdb_cls,
+ type=_validate_usepdb_cls,
help="start a custom interactive Python debugger on errors. "
"For example: --pdbcls=IPython.terminal.debugger:TerminalPdb",
)
@@ -93,7 +93,7 @@ def pytest_configure(config):
config.pluginmanager.register(PdbInvoke(), "pdbinvoke")
pytestPDB._saved.append(
- (pdb.set_trace, pytestPDB._pluginmanager, pytestPDB._config)
+ (pdb.set_trace, pytestPDB._pluginmanager, pytestPDB._config)
)
pdb.set_trace = pytestPDB.set_trace
pytestPDB._pluginmanager = config.pluginmanager
@@ -117,181 +117,181 @@ class pytestPDB(object):
_pluginmanager = None
_config = None
_saved = []
- _recursive_debug = 0
- _wrapped_pdb_cls = None
-
- @classmethod
- def _is_capturing(cls, capman):
- if capman:
- return capman.is_capturing()
- return False
-
- @classmethod
- def _import_pdb_cls(cls, capman):
- if not cls._config:
- # Happens when using pytest.set_trace outside of a test.
- return pdb.Pdb
-
- usepdb_cls = cls._config.getvalue("usepdb_cls")
-
- if cls._wrapped_pdb_cls and cls._wrapped_pdb_cls[0] == usepdb_cls:
- return cls._wrapped_pdb_cls[1]
-
- if usepdb_cls:
- modname, classname = usepdb_cls
-
- try:
- __import__(modname)
- mod = sys.modules[modname]
-
- # Handle --pdbcls=pdb:pdb.Pdb (useful e.g. with pdbpp).
- parts = classname.split(".")
- pdb_cls = getattr(mod, parts[0])
- for part in parts[1:]:
- pdb_cls = getattr(pdb_cls, part)
- except Exception as exc:
- value = ":".join((modname, classname))
- raise UsageError(
- "--pdbcls: could not import {!r}: {}".format(value, exc)
- )
- else:
- pdb_cls = pdb.Pdb
-
- wrapped_cls = cls._get_pdb_wrapper_class(pdb_cls, capman)
- cls._wrapped_pdb_cls = (usepdb_cls, wrapped_cls)
- return wrapped_cls
+ _recursive_debug = 0
+ _wrapped_pdb_cls = None
@classmethod
- def _get_pdb_wrapper_class(cls, pdb_cls, capman):
+ def _is_capturing(cls, capman):
+ if capman:
+ return capman.is_capturing()
+ return False
+
+ @classmethod
+ def _import_pdb_cls(cls, capman):
+ if not cls._config:
+ # Happens when using pytest.set_trace outside of a test.
+ return pdb.Pdb
+
+ usepdb_cls = cls._config.getvalue("usepdb_cls")
+
+ if cls._wrapped_pdb_cls and cls._wrapped_pdb_cls[0] == usepdb_cls:
+ return cls._wrapped_pdb_cls[1]
+
+ if usepdb_cls:
+ modname, classname = usepdb_cls
+
+ try:
+ __import__(modname)
+ mod = sys.modules[modname]
+
+ # Handle --pdbcls=pdb:pdb.Pdb (useful e.g. with pdbpp).
+ parts = classname.split(".")
+ pdb_cls = getattr(mod, parts[0])
+ for part in parts[1:]:
+ pdb_cls = getattr(pdb_cls, part)
+ except Exception as exc:
+ value = ":".join((modname, classname))
+ raise UsageError(
+ "--pdbcls: could not import {!r}: {}".format(value, exc)
+ )
+ else:
+ pdb_cls = pdb.Pdb
+
+ wrapped_cls = cls._get_pdb_wrapper_class(pdb_cls, capman)
+ cls._wrapped_pdb_cls = (usepdb_cls, wrapped_cls)
+ return wrapped_cls
+
+ @classmethod
+ def _get_pdb_wrapper_class(cls, pdb_cls, capman):
import _pytest.config
- class PytestPdbWrapper(pdb_cls, object):
- _pytest_capman = capman
- _continued = False
-
- def do_debug(self, arg):
- cls._recursive_debug += 1
- ret = super(PytestPdbWrapper, self).do_debug(arg)
- cls._recursive_debug -= 1
- return ret
-
- def do_continue(self, arg):
- ret = super(PytestPdbWrapper, self).do_continue(arg)
- if cls._recursive_debug == 0:
- tw = _pytest.config.create_terminal_writer(cls._config)
- tw.line()
-
- capman = self._pytest_capman
- capturing = pytestPDB._is_capturing(capman)
- if capturing:
- if capturing == "global":
+ class PytestPdbWrapper(pdb_cls, object):
+ _pytest_capman = capman
+ _continued = False
+
+ def do_debug(self, arg):
+ cls._recursive_debug += 1
+ ret = super(PytestPdbWrapper, self).do_debug(arg)
+ cls._recursive_debug -= 1
+ return ret
+
+ def do_continue(self, arg):
+ ret = super(PytestPdbWrapper, self).do_continue(arg)
+ if cls._recursive_debug == 0:
+ tw = _pytest.config.create_terminal_writer(cls._config)
+ tw.line()
+
+ capman = self._pytest_capman
+ capturing = pytestPDB._is_capturing(capman)
+ if capturing:
+ if capturing == "global":
tw.sep(">", "PDB continue (IO-capturing resumed)")
else:
- tw.sep(
- ">",
- "PDB continue (IO-capturing resumed for %s)"
- % capturing,
- )
- capman.resume()
- else:
- tw.sep(">", "PDB continue")
- cls._pluginmanager.hook.pytest_leave_pdb(config=cls._config, pdb=self)
- self._continued = True
- return ret
-
- do_c = do_cont = do_continue
-
- def do_quit(self, arg):
- """Raise Exit outcome when quit command is used in pdb.
-
- This is a bit of a hack - it would be better if BdbQuit
- could be handled, but this would require to wrap the
- whole pytest run, and adjust the report etc.
- """
- ret = super(PytestPdbWrapper, self).do_quit(arg)
-
- if cls._recursive_debug == 0:
- outcomes.exit("Quitting debugger")
-
- return ret
-
- do_q = do_quit
- do_exit = do_quit
-
- def setup(self, f, tb):
- """Suspend on setup().
-
- Needed after do_continue resumed, and entering another
- breakpoint again.
- """
- ret = super(PytestPdbWrapper, self).setup(f, tb)
- if not ret and self._continued:
- # pdb.setup() returns True if the command wants to exit
- # from the interaction: do not suspend capturing then.
- if self._pytest_capman:
- self._pytest_capman.suspend_global_capture(in_=True)
- return ret
-
- def get_stack(self, f, t):
- stack, i = super(PytestPdbWrapper, self).get_stack(f, t)
- if f is None:
- # Find last non-hidden frame.
- i = max(0, len(stack) - 1)
- while i and stack[i][0].f_locals.get("__tracebackhide__", False):
- i -= 1
- return stack, i
-
- return PytestPdbWrapper
-
- @classmethod
- def _init_pdb(cls, method, *args, **kwargs):
- """ Initialize PDB debugging, dropping any IO capturing. """
- import _pytest.config
-
- if cls._pluginmanager is not None:
- capman = cls._pluginmanager.getplugin("capturemanager")
+ tw.sep(
+ ">",
+ "PDB continue (IO-capturing resumed for %s)"
+ % capturing,
+ )
+ capman.resume()
+ else:
+ tw.sep(">", "PDB continue")
+ cls._pluginmanager.hook.pytest_leave_pdb(config=cls._config, pdb=self)
+ self._continued = True
+ return ret
+
+ do_c = do_cont = do_continue
+
+ def do_quit(self, arg):
+ """Raise Exit outcome when quit command is used in pdb.
+
+ This is a bit of a hack - it would be better if BdbQuit
+ could be handled, but this would require to wrap the
+ whole pytest run, and adjust the report etc.
+ """
+ ret = super(PytestPdbWrapper, self).do_quit(arg)
+
+ if cls._recursive_debug == 0:
+ outcomes.exit("Quitting debugger")
+
+ return ret
+
+ do_q = do_quit
+ do_exit = do_quit
+
+ def setup(self, f, tb):
+ """Suspend on setup().
+
+ Needed after do_continue resumed, and entering another
+ breakpoint again.
+ """
+ ret = super(PytestPdbWrapper, self).setup(f, tb)
+ if not ret and self._continued:
+ # pdb.setup() returns True if the command wants to exit
+ # from the interaction: do not suspend capturing then.
+ if self._pytest_capman:
+ self._pytest_capman.suspend_global_capture(in_=True)
+ return ret
+
+ def get_stack(self, f, t):
+ stack, i = super(PytestPdbWrapper, self).get_stack(f, t)
+ if f is None:
+ # Find last non-hidden frame.
+ i = max(0, len(stack) - 1)
+ while i and stack[i][0].f_locals.get("__tracebackhide__", False):
+ i -= 1
+ return stack, i
+
+ return PytestPdbWrapper
+
+ @classmethod
+ def _init_pdb(cls, method, *args, **kwargs):
+ """ Initialize PDB debugging, dropping any IO capturing. """
+ import _pytest.config
+
+ if cls._pluginmanager is not None:
+ capman = cls._pluginmanager.getplugin("capturemanager")
else:
- capman = None
- if capman:
- capman.suspend(in_=True)
-
- if cls._config:
- tw = _pytest.config.create_terminal_writer(cls._config)
- tw.line()
-
- if cls._recursive_debug == 0:
- # Handle header similar to pdb.set_trace in py37+.
- header = kwargs.pop("header", None)
- if header is not None:
- tw.sep(">", header)
- else:
- capturing = cls._is_capturing(capman)
- if capturing == "global":
- tw.sep(">", "PDB %s (IO-capturing turned off)" % (method,))
- elif capturing:
- tw.sep(
- ">",
- "PDB %s (IO-capturing turned off for %s)"
- % (method, capturing),
- )
- else:
- tw.sep(">", "PDB %s" % (method,))
-
- _pdb = cls._import_pdb_cls(capman)(**kwargs)
-
- if cls._pluginmanager:
- cls._pluginmanager.hook.pytest_enter_pdb(config=cls._config, pdb=_pdb)
- return _pdb
-
- @classmethod
- def set_trace(cls, *args, **kwargs):
- """Invoke debugging via ``Pdb.set_trace``, dropping any IO capturing."""
- tty()
- frame = sys._getframe().f_back
- _pdb = cls._init_pdb("set_trace", *args, **kwargs)
- _pdb.set_trace(frame)
-
-
+ capman = None
+ if capman:
+ capman.suspend(in_=True)
+
+ if cls._config:
+ tw = _pytest.config.create_terminal_writer(cls._config)
+ tw.line()
+
+ if cls._recursive_debug == 0:
+ # Handle header similar to pdb.set_trace in py37+.
+ header = kwargs.pop("header", None)
+ if header is not None:
+ tw.sep(">", header)
+ else:
+ capturing = cls._is_capturing(capman)
+ if capturing == "global":
+ tw.sep(">", "PDB %s (IO-capturing turned off)" % (method,))
+ elif capturing:
+ tw.sep(
+ ">",
+ "PDB %s (IO-capturing turned off for %s)"
+ % (method, capturing),
+ )
+ else:
+ tw.sep(">", "PDB %s" % (method,))
+
+ _pdb = cls._import_pdb_cls(capman)(**kwargs)
+
+ if cls._pluginmanager:
+ cls._pluginmanager.hook.pytest_enter_pdb(config=cls._config, pdb=_pdb)
+ return _pdb
+
+ @classmethod
+ def set_trace(cls, *args, **kwargs):
+ """Invoke debugging via ``Pdb.set_trace``, dropping any IO capturing."""
+ tty()
+ frame = sys._getframe().f_back
+ _pdb = cls._init_pdb("set_trace", *args, **kwargs)
+ _pdb.set_trace(frame)
+
+
class PdbInvoke(object):
def pytest_exception_interact(self, node, call, report):
capman = node.config.pluginmanager.getplugin("capturemanager")
@@ -316,15 +316,15 @@ class PdbTrace(object):
def _test_pytest_function(pyfuncitem):
- _pdb = pytestPDB._init_pdb("runcall")
+ _pdb = pytestPDB._init_pdb("runcall")
testfunction = pyfuncitem.obj
- pyfuncitem.obj = _pdb.runcall
- if "func" in pyfuncitem._fixtureinfo.argnames: # pragma: no branch
- raise ValueError("--trace can't be used with a fixture named func!")
- pyfuncitem.funcargs["func"] = testfunction
- new_list = list(pyfuncitem._fixtureinfo.argnames)
- new_list.append("func")
- pyfuncitem._fixtureinfo.argnames = tuple(new_list)
+ pyfuncitem.obj = _pdb.runcall
+ if "func" in pyfuncitem._fixtureinfo.argnames: # pragma: no branch
+ raise ValueError("--trace can't be used with a fixture named func!")
+ pyfuncitem.funcargs["func"] = testfunction
+ new_list = list(pyfuncitem._fixtureinfo.argnames)
+ new_list.append("func")
+ pyfuncitem._fixtureinfo.argnames = tuple(new_list)
def _enter_pdb(node, excinfo, rep):
@@ -352,7 +352,7 @@ def _enter_pdb(node, excinfo, rep):
tw.sep(">", "entering PDB")
tb = _postmortem_traceback(excinfo)
rep._pdbshown = True
- post_mortem(tb)
+ post_mortem(tb)
return rep
@@ -366,8 +366,8 @@ def _postmortem_traceback(excinfo):
def post_mortem(t):
- p = pytestPDB._init_pdb("post_mortem")
+ p = pytestPDB._init_pdb("post_mortem")
p.reset()
p.interaction(None, t)
- if p.quitting:
- outcomes.exit("Quitting debugger")
+ if p.quitting:
+ outcomes.exit("Quitting debugger")
diff --git a/contrib/python/pytest/py2/_pytest/deprecated.py b/contrib/python/pytest/py2/_pytest/deprecated.py
index 12394aca3f..13573dc86e 100644
--- a/contrib/python/pytest/py2/_pytest/deprecated.py
+++ b/contrib/python/pytest/py2/_pytest/deprecated.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""
This module contains deprecation messages and bits of code used elsewhere in the codebase
that is planned to be removed in the next pytest release.
@@ -17,80 +17,80 @@ from _pytest.warning_types import PytestDeprecationWarning
from _pytest.warning_types import RemovedInPytest4Warning
from _pytest.warning_types import UnformattedWarning
-YIELD_TESTS = "yield tests were removed in pytest 4.0 - {name} will be ignored"
+YIELD_TESTS = "yield tests were removed in pytest 4.0 - {name} will be ignored"
-FIXTURE_FUNCTION_CALL = (
- 'Fixture "{name}" called directly. Fixtures are not meant to be called directly,\n'
- "but are created automatically when test functions request them as parameters.\n"
- "See https://docs.pytest.org/en/latest/fixture.html for more information about fixtures, and\n"
- "https://docs.pytest.org/en/latest/deprecations.html#calling-fixtures-directly about how to update your code."
+FIXTURE_FUNCTION_CALL = (
+ 'Fixture "{name}" called directly. Fixtures are not meant to be called directly,\n'
+ "but are created automatically when test functions request them as parameters.\n"
+ "See https://docs.pytest.org/en/latest/fixture.html for more information about fixtures, and\n"
+ "https://docs.pytest.org/en/latest/deprecations.html#calling-fixtures-directly about how to update your code."
)
FIXTURE_NAMED_REQUEST = PytestDeprecationWarning(
"'request' is a reserved name for fixtures and will raise an error in future versions"
)
-CFG_PYTEST_SECTION = "[pytest] section in {filename} files is no longer supported, change to [tool:pytest] instead."
+CFG_PYTEST_SECTION = "[pytest] section in {filename} files is no longer supported, change to [tool:pytest] instead."
GETFUNCARGVALUE = RemovedInPytest4Warning(
"getfuncargvalue is deprecated, use getfixturevalue"
)
-RAISES_MESSAGE_PARAMETER = PytestDeprecationWarning(
- "The 'message' parameter is deprecated.\n"
- "(did you mean to use `match='some regex'` to check the exception message?)\n"
- "Please see:\n"
- " https://docs.pytest.org/en/4.6-maintenance/deprecations.html#message-parameter-of-pytest-raises"
+RAISES_MESSAGE_PARAMETER = PytestDeprecationWarning(
+ "The 'message' parameter is deprecated.\n"
+ "(did you mean to use `match='some regex'` to check the exception message?)\n"
+ "Please see:\n"
+ " https://docs.pytest.org/en/4.6-maintenance/deprecations.html#message-parameter-of-pytest-raises"
)
-RESULT_LOG = PytestDeprecationWarning(
- "--result-log is deprecated and scheduled for removal in pytest 5.0.\n"
- "See https://docs.pytest.org/en/latest/deprecations.html#result-log-result-log for more information."
+RESULT_LOG = PytestDeprecationWarning(
+ "--result-log is deprecated and scheduled for removal in pytest 5.0.\n"
+ "See https://docs.pytest.org/en/latest/deprecations.html#result-log-result-log for more information."
)
-RAISES_EXEC = PytestDeprecationWarning(
- "raises(..., 'code(as_a_string)') is deprecated, use the context manager form or use `exec()` directly\n\n"
- "See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec"
+RAISES_EXEC = PytestDeprecationWarning(
+ "raises(..., 'code(as_a_string)') is deprecated, use the context manager form or use `exec()` directly\n\n"
+ "See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec"
)
-WARNS_EXEC = PytestDeprecationWarning(
- "warns(..., 'code(as_a_string)') is deprecated, use the context manager form or use `exec()` directly.\n\n"
- "See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec"
+WARNS_EXEC = PytestDeprecationWarning(
+ "warns(..., 'code(as_a_string)') is deprecated, use the context manager form or use `exec()` directly.\n\n"
+ "See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec"
)
-PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST = (
- "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported "
- "because it affects the entire directory tree in a non-explicit way.\n"
- " {}\n"
- "Please move it to a top level conftest file at the rootdir:\n"
- " {}\n"
- "For more information, visit:\n"
- " https://docs.pytest.org/en/latest/deprecations.html#pytest-plugins-in-non-top-level-conftest-files"
+PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST = (
+ "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported "
+ "because it affects the entire directory tree in a non-explicit way.\n"
+ " {}\n"
+ "Please move it to a top level conftest file at the rootdir:\n"
+ " {}\n"
+ "For more information, visit:\n"
+ " https://docs.pytest.org/en/latest/deprecations.html#pytest-plugins-in-non-top-level-conftest-files"
)
-PYTEST_CONFIG_GLOBAL = PytestDeprecationWarning(
- "the `pytest.config` global is deprecated. Please use `request.config` "
- "or `pytest_configure` (if you're a pytest plugin) instead."
+PYTEST_CONFIG_GLOBAL = PytestDeprecationWarning(
+ "the `pytest.config` global is deprecated. Please use `request.config` "
+ "or `pytest_configure` (if you're a pytest plugin) instead."
)
-PYTEST_ENSURETEMP = RemovedInPytest4Warning(
- "pytest/tmpdir_factory.ensuretemp is deprecated, \n"
- "please use the tmp_path fixture or tmp_path_factory.mktemp"
+PYTEST_ENSURETEMP = RemovedInPytest4Warning(
+ "pytest/tmpdir_factory.ensuretemp is deprecated, \n"
+ "please use the tmp_path fixture or tmp_path_factory.mktemp"
)
-PYTEST_LOGWARNING = PytestDeprecationWarning(
- "pytest_logwarning is deprecated, no longer being called, and will be removed soon\n"
- "please use pytest_warning_captured instead"
+PYTEST_LOGWARNING = PytestDeprecationWarning(
+ "pytest_logwarning is deprecated, no longer being called, and will be removed soon\n"
+ "please use pytest_warning_captured instead"
)
-PYTEST_WARNS_UNKNOWN_KWARGS = UnformattedWarning(
- PytestDeprecationWarning,
- "pytest.warns() got unexpected keyword arguments: {args!r}.\n"
- "This will be an error in future versions.",
+PYTEST_WARNS_UNKNOWN_KWARGS = UnformattedWarning(
+ PytestDeprecationWarning,
+ "pytest.warns() got unexpected keyword arguments: {args!r}.\n"
+ "This will be an error in future versions.",
)
-PYTEST_PARAM_UNKNOWN_KWARGS = UnformattedWarning(
- PytestDeprecationWarning,
- "pytest.param() got unexpected keyword arguments: {args!r}.\n"
- "This will be an error in future versions.",
+PYTEST_PARAM_UNKNOWN_KWARGS = UnformattedWarning(
+ PytestDeprecationWarning,
+ "pytest.param() got unexpected keyword arguments: {args!r}.\n"
+ "This will be an error in future versions.",
)
diff --git a/contrib/python/pytest/py2/_pytest/doctest.py b/contrib/python/pytest/py2/_pytest/doctest.py
index 659d24aeeb..ade99d120f 100644
--- a/contrib/python/pytest/py2/_pytest/doctest.py
+++ b/contrib/python/pytest/py2/_pytest/doctest.py
@@ -1,24 +1,24 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" discover and run doctests in modules and test files."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-import inspect
+import inspect
import platform
import sys
import traceback
-import warnings
-from contextlib import contextmanager
+import warnings
+from contextlib import contextmanager
import pytest
from _pytest._code.code import ExceptionInfo
from _pytest._code.code import ReprFileLocation
from _pytest._code.code import TerminalRepr
-from _pytest.compat import safe_getattr
+from _pytest.compat import safe_getattr
from _pytest.fixtures import FixtureRequest
-from _pytest.outcomes import Skipped
-from _pytest.warning_types import PytestWarning
+from _pytest.outcomes import Skipped
+from _pytest.warning_types import PytestWarning
DOCTEST_REPORT_CHOICE_NONE = "none"
DOCTEST_REPORT_CHOICE_CDIFF = "cdiff"
@@ -157,8 +157,8 @@ def _init_runner_class():
raise failure
def report_unexpected_exception(self, out, test, example, exc_info):
- if isinstance(exc_info[1], Skipped):
- raise exc_info[1]
+ if isinstance(exc_info[1], Skipped):
+ raise exc_info[1]
failure = doctest.UnexpectedException(test, example, exc_info)
if self.continue_on_failure:
out.append(failure)
@@ -354,69 +354,69 @@ def _check_all_skipped(test):
pytest.skip("all tests skipped by +SKIP option")
-def _is_mocked(obj):
- """
- returns if a object is possibly a mock object by checking the existence of a highly improbable attribute
- """
- return (
- safe_getattr(obj, "pytest_mock_example_attribute_that_shouldnt_exist", None)
- is not None
- )
-
-
-@contextmanager
-def _patch_unwrap_mock_aware():
- """
- contextmanager which replaces ``inspect.unwrap`` with a version
- that's aware of mock objects and doesn't recurse on them
- """
- real_unwrap = getattr(inspect, "unwrap", None)
- if real_unwrap is None:
- yield
- else:
-
- def _mock_aware_unwrap(obj, stop=None):
- try:
- if stop is None or stop is _is_mocked:
- return real_unwrap(obj, stop=_is_mocked)
- return real_unwrap(obj, stop=lambda obj: _is_mocked(obj) or stop(obj))
- except Exception as e:
- warnings.warn(
- "Got %r when unwrapping %r. This is usually caused "
- "by a violation of Python's object protocol; see e.g. "
- "https://github.com/pytest-dev/pytest/issues/5080" % (e, obj),
- PytestWarning,
- )
- raise
-
- inspect.unwrap = _mock_aware_unwrap
- try:
- yield
- finally:
- inspect.unwrap = real_unwrap
-
-
+def _is_mocked(obj):
+ """
+ returns if a object is possibly a mock object by checking the existence of a highly improbable attribute
+ """
+ return (
+ safe_getattr(obj, "pytest_mock_example_attribute_that_shouldnt_exist", None)
+ is not None
+ )
+
+
+@contextmanager
+def _patch_unwrap_mock_aware():
+ """
+ contextmanager which replaces ``inspect.unwrap`` with a version
+ that's aware of mock objects and doesn't recurse on them
+ """
+ real_unwrap = getattr(inspect, "unwrap", None)
+ if real_unwrap is None:
+ yield
+ else:
+
+ def _mock_aware_unwrap(obj, stop=None):
+ try:
+ if stop is None or stop is _is_mocked:
+ return real_unwrap(obj, stop=_is_mocked)
+ return real_unwrap(obj, stop=lambda obj: _is_mocked(obj) or stop(obj))
+ except Exception as e:
+ warnings.warn(
+ "Got %r when unwrapping %r. This is usually caused "
+ "by a violation of Python's object protocol; see e.g. "
+ "https://github.com/pytest-dev/pytest/issues/5080" % (e, obj),
+ PytestWarning,
+ )
+ raise
+
+ inspect.unwrap = _mock_aware_unwrap
+ try:
+ yield
+ finally:
+ inspect.unwrap = real_unwrap
+
+
class DoctestModule(pytest.Module):
def collect(self):
import doctest
- class MockAwareDocTestFinder(doctest.DocTestFinder):
- """
- a hackish doctest finder that overrides stdlib internals to fix a stdlib bug
-
- https://github.com/pytest-dev/pytest/issues/3456
- https://bugs.python.org/issue25532
- """
-
- def _find(self, tests, obj, name, module, source_lines, globs, seen):
- if _is_mocked(obj):
- return
- with _patch_unwrap_mock_aware():
-
- doctest.DocTestFinder._find(
- self, tests, obj, name, module, source_lines, globs, seen
- )
-
+ class MockAwareDocTestFinder(doctest.DocTestFinder):
+ """
+ a hackish doctest finder that overrides stdlib internals to fix a stdlib bug
+
+ https://github.com/pytest-dev/pytest/issues/3456
+ https://bugs.python.org/issue25532
+ """
+
+ def _find(self, tests, obj, name, module, source_lines, globs, seen):
+ if _is_mocked(obj):
+ return
+ with _patch_unwrap_mock_aware():
+
+ doctest.DocTestFinder._find(
+ self, tests, obj, name, module, source_lines, globs, seen
+ )
+
if self.fspath.basename == "conftest.py":
module = self.config.pluginmanager._importconftest(self.fspath)
else:
@@ -428,7 +428,7 @@ class DoctestModule(pytest.Module):
else:
raise
# uses internal doctest module parsing mechanism
- finder = MockAwareDocTestFinder()
+ finder = MockAwareDocTestFinder()
optionflags = get_optionflags(self)
runner = _get_runner(
verbose=0,
diff --git a/contrib/python/pytest/py2/_pytest/fixtures.py b/contrib/python/pytest/py2/_pytest/fixtures.py
index 280a48608b..244b0ef4f8 100644
--- a/contrib/python/pytest/py2/_pytest/fixtures.py
+++ b/contrib/python/pytest/py2/_pytest/fixtures.py
@@ -1,11 +1,11 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import functools
import inspect
-import itertools
+import itertools
import sys
import warnings
from collections import defaultdict
@@ -18,7 +18,7 @@ import six
import _pytest
from _pytest import nodes
-from _pytest._code.code import FormattedExcinfo
+from _pytest._code.code import FormattedExcinfo
from _pytest._code.code import TerminalRepr
from _pytest.compat import _format_args
from _pytest.compat import _PytestWrapper
@@ -308,8 +308,8 @@ class FuncFixtureInfo(object):
# fixture names specified via usefixtures and via autouse=True in fixture
# definitions.
initialnames = attr.ib(type=tuple)
- names_closure = attr.ib() # List[str]
- name2fixturedefs = attr.ib() # List[str, List[FixtureDef]]
+ names_closure = attr.ib() # List[str]
+ name2fixturedefs = attr.ib() # List[str, List[FixtureDef]]
def prune_dependency_tree(self):
"""Recompute names_closure from initialnames and name2fixturedefs
@@ -567,7 +567,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
)
fail(msg, pytrace=False)
else:
- param_index = funcitem.callspec.indices[argname]
+ param_index = funcitem.callspec.indices[argname]
# if a parametrize invocation set a scope it will override
# the static scope defined with the fixture function
paramscopenum = funcitem.callspec._arg2scopenum.get(argname)
@@ -586,14 +586,14 @@ class FixtureRequest(FuncargnamesCompatAttr):
# call the fixture function
fixturedef.execute(request=subrequest)
finally:
- self._schedule_finalizers(fixturedef, subrequest)
-
- def _schedule_finalizers(self, fixturedef, subrequest):
- # if fixture function failed it might have registered finalizers
- self.session._setupstate.addfinalizer(
- functools.partial(fixturedef.finish, request=subrequest), subrequest.node
- )
-
+ self._schedule_finalizers(fixturedef, subrequest)
+
+ def _schedule_finalizers(self, fixturedef, subrequest):
+ # if fixture function failed it might have registered finalizers
+ self.session._setupstate.addfinalizer(
+ functools.partial(fixturedef.finish, request=subrequest), subrequest.node
+ )
+
def _check_scope(self, argname, invoking_scope, requested_scope):
if argname == "request":
return
@@ -615,7 +615,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
fs, lineno = getfslineno(factory)
p = self._pyfuncitem.session.fspath.bestrelpath(fs)
args = _format_args(factory)
- lines.append("%s:%d: def %s%s" % (p, lineno + 1, factory.__name__, args))
+ lines.append("%s:%d: def %s%s" % (p, lineno + 1, factory.__name__, args))
return lines
def _getscopeitem(self, scope):
@@ -662,15 +662,15 @@ class SubRequest(FixtureRequest):
def addfinalizer(self, finalizer):
self._fixturedef.addfinalizer(finalizer)
- def _schedule_finalizers(self, fixturedef, subrequest):
- # if the executing fixturedef was not explicitly requested in the argument list (via
- # getfixturevalue inside the fixture call) then ensure this fixture def will be finished
- # first
- if fixturedef.argname not in self.funcargnames:
- fixturedef.addfinalizer(
- functools.partial(self._fixturedef.finish, request=self)
- )
- super(SubRequest, self)._schedule_finalizers(fixturedef, subrequest)
+ def _schedule_finalizers(self, fixturedef, subrequest):
+ # if the executing fixturedef was not explicitly requested in the argument list (via
+ # getfixturevalue inside the fixture call) then ensure this fixture def will be finished
+ # first
+ if fixturedef.argname not in self.funcargnames:
+ fixturedef.addfinalizer(
+ functools.partial(self._fixturedef.finish, request=self)
+ )
+ super(SubRequest, self)._schedule_finalizers(fixturedef, subrequest)
scopes = "session package module class function".split()
@@ -854,8 +854,8 @@ class FixtureDef(object):
exceptions.append(sys.exc_info())
if exceptions:
e = exceptions[0]
- # Ensure to not keep frame references through traceback.
- del exceptions
+ # Ensure to not keep frame references through traceback.
+ del exceptions
six.reraise(*e)
finally:
hook = self._fixturemanager.session.gethookproxy(request.node.fspath)
@@ -949,17 +949,17 @@ def _ensure_immutable_ids(ids):
return tuple(ids)
-def wrap_function_to_error_out_if_called_directly(function, fixture_marker):
- """Wrap the given fixture function so we can raise an error about it being called directly,
- instead of used as an argument in a test function.
+def wrap_function_to_error_out_if_called_directly(function, fixture_marker):
+ """Wrap the given fixture function so we can raise an error about it being called directly,
+ instead of used as an argument in a test function.
"""
- message = FIXTURE_FUNCTION_CALL.format(
+ message = FIXTURE_FUNCTION_CALL.format(
name=fixture_marker.name or function.__name__
)
- @six.wraps(function)
- def result(*args, **kwargs):
- fail(message, pytrace=False)
+ @six.wraps(function)
+ def result(*args, **kwargs):
+ fail(message, pytrace=False)
# keep reference to the original function in our own custom attribute so we don't unwrap
# further than this point and lose useful wrappings like @mock.patch (#3774)
@@ -985,7 +985,7 @@ class FixtureFunctionMarker(object):
"fixture is being applied more than once to the same function"
)
- function = wrap_function_to_error_out_if_called_directly(function, self)
+ function = wrap_function_to_error_out_if_called_directly(function, self)
name = self.name or function.__name__
if name == "request":
@@ -1022,7 +1022,7 @@ def fixture(scope="function", params=None, autouse=False, ids=None, name=None):
:arg params: an optional list of parameters which will cause multiple
invocations of the fixture function and all of the tests
using it.
- The current parameter is available in ``request.param``.
+ The current parameter is available in ``request.param``.
:arg autouse: if True, the fixture func is activated for all tests that
can see it. If False (the default) then an explicit
@@ -1067,22 +1067,22 @@ def pytestconfig(request):
Example::
def test_foo(pytestconfig):
- if pytestconfig.getoption("verbose") > 0:
+ if pytestconfig.getoption("verbose") > 0:
...
"""
return request.config
-def pytest_addoption(parser):
- parser.addini(
- "usefixtures",
- type="args",
- default=[],
- help="list of default fixtures to be used with this project",
- )
-
-
+def pytest_addoption(parser):
+ parser.addini(
+ "usefixtures",
+ type="args",
+ default=[],
+ help="list of default fixtures to be used with this project",
+ )
+
+
class FixtureManager(object):
"""
pytest fixtures definitions and information is stored and managed
@@ -1127,40 +1127,40 @@ class FixtureManager(object):
self._nodeid_and_autousenames = [("", self.config.getini("usefixtures"))]
session.config.pluginmanager.register(self, "funcmanage")
- def _get_direct_parametrize_args(self, node):
- """This function returns all the direct parametrization
- arguments of a node, so we don't mistake them for fixtures
-
- Check https://github.com/pytest-dev/pytest/issues/5036
-
- This things are done later as well when dealing with parametrization
- so this could be improved
- """
- from _pytest.mark import ParameterSet
-
- parametrize_argnames = []
- for marker in node.iter_markers(name="parametrize"):
- if not marker.kwargs.get("indirect", False):
- p_argnames, _ = ParameterSet._parse_parametrize_args(
- *marker.args, **marker.kwargs
- )
- parametrize_argnames.extend(p_argnames)
-
- return parametrize_argnames
-
+ def _get_direct_parametrize_args(self, node):
+ """This function returns all the direct parametrization
+ arguments of a node, so we don't mistake them for fixtures
+
+ Check https://github.com/pytest-dev/pytest/issues/5036
+
+ This things are done later as well when dealing with parametrization
+ so this could be improved
+ """
+ from _pytest.mark import ParameterSet
+
+ parametrize_argnames = []
+ for marker in node.iter_markers(name="parametrize"):
+ if not marker.kwargs.get("indirect", False):
+ p_argnames, _ = ParameterSet._parse_parametrize_args(
+ *marker.args, **marker.kwargs
+ )
+ parametrize_argnames.extend(p_argnames)
+
+ return parametrize_argnames
+
def getfixtureinfo(self, node, func, cls, funcargs=True):
if funcargs and not getattr(node, "nofuncargs", False):
argnames = getfuncargnames(func, cls=cls)
else:
argnames = ()
-
- usefixtures = itertools.chain.from_iterable(
+
+ usefixtures = itertools.chain.from_iterable(
mark.args for mark in node.iter_markers(name="usefixtures")
)
initialnames = tuple(usefixtures) + argnames
fm = node.session._fixturemanager
initialnames, names_closure, arg2fixturedefs = fm.getfixtureclosure(
- initialnames, node, ignore_args=self._get_direct_parametrize_args(node)
+ initialnames, node, ignore_args=self._get_direct_parametrize_args(node)
)
return FuncFixtureInfo(argnames, initialnames, names_closure, arg2fixturedefs)
@@ -1194,7 +1194,7 @@ class FixtureManager(object):
autousenames.extend(basenames)
return autousenames
- def getfixtureclosure(self, fixturenames, parentnode, ignore_args=()):
+ def getfixtureclosure(self, fixturenames, parentnode, ignore_args=()):
# collect the closure of all fixtures , starting with the given
# fixturenames as the initial set. As we have to visit all
# factory definitions anyway, we also return an arg2fixturedefs
@@ -1222,8 +1222,8 @@ class FixtureManager(object):
while lastlen != len(fixturenames_closure):
lastlen = len(fixturenames_closure)
for argname in fixturenames_closure:
- if argname in ignore_args:
- continue
+ if argname in ignore_args:
+ continue
if argname in arg2fixturedefs:
continue
fixturedefs = self.getfixturedefs(argname, parentid)
@@ -1248,19 +1248,19 @@ class FixtureManager(object):
if faclist:
fixturedef = faclist[-1]
if fixturedef.params is not None:
- markers = list(metafunc.definition.iter_markers("parametrize"))
- for parametrize_mark in markers:
- if "argnames" in parametrize_mark.kwargs:
- argnames = parametrize_mark.kwargs["argnames"]
- else:
- argnames = parametrize_mark.args[0]
-
- if not isinstance(argnames, (tuple, list)):
- argnames = [
- x.strip() for x in argnames.split(",") if x.strip()
- ]
- if argname in argnames:
- break
+ markers = list(metafunc.definition.iter_markers("parametrize"))
+ for parametrize_mark in markers:
+ if "argnames" in parametrize_mark.kwargs:
+ argnames = parametrize_mark.kwargs["argnames"]
+ else:
+ argnames = parametrize_mark.args[0]
+
+ if not isinstance(argnames, (tuple, list)):
+ argnames = [
+ x.strip() for x in argnames.split(",") if x.strip()
+ ]
+ if argname in argnames:
+ break
else:
metafunc.parametrize(
argname,
@@ -1292,14 +1292,14 @@ class FixtureManager(object):
# access below can raise. safe_getatt() ignores such exceptions.
obj = safe_getattr(holderobj, name, None)
marker = getfixturemarker(obj)
- if not isinstance(marker, FixtureFunctionMarker):
+ if not isinstance(marker, FixtureFunctionMarker):
# magic globals with __getattr__ might have got us a wrong
# fixture attribute
continue
- if marker.name:
- name = marker.name
-
+ if marker.name:
+ name = marker.name
+
# during fixture definition we wrap the original fixture function
# to issue a warning if called directly, so here we unwrap it in order to not emit the warning
# when pytest itself calls the fixture function
diff --git a/contrib/python/pytest/py2/_pytest/freeze_support.py b/contrib/python/pytest/py2/_pytest/freeze_support.py
index aeeec2a56b..acbf4db251 100644
--- a/contrib/python/pytest/py2/_pytest/freeze_support.py
+++ b/contrib/python/pytest/py2/_pytest/freeze_support.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""
Provides a function to report all internal modules for using freezing tools
pytest
diff --git a/contrib/python/pytest/py2/_pytest/helpconfig.py b/contrib/python/pytest/py2/_pytest/helpconfig.py
index 5681160160..be4bc2c0bc 100644
--- a/contrib/python/pytest/py2/_pytest/helpconfig.py
+++ b/contrib/python/pytest/py2/_pytest/helpconfig.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" version info, help messages, tracing configuration. """
from __future__ import absolute_import
from __future__ import division
@@ -61,7 +61,7 @@ def pytest_addoption(parser):
dest="plugins",
default=[],
metavar="name",
- help="early-load given plugin module name or entry point (multi-allowed). "
+ help="early-load given plugin module name or entry point (multi-allowed). "
"To avoid loading of plugins, use the `no:` prefix, e.g. "
"`no:doctest`.",
)
@@ -119,20 +119,20 @@ def pytest_cmdline_parse():
config.add_cleanup(unset_tracing)
-def showversion(config):
- p = py.path.local(pytest.__file__)
- sys.stderr.write(
- "This is pytest version %s, imported from %s\n" % (pytest.__version__, p)
- )
- plugininfo = getpluginversioninfo(config)
- if plugininfo:
- for line in plugininfo:
- sys.stderr.write(line + "\n")
-
-
+def showversion(config):
+ p = py.path.local(pytest.__file__)
+ sys.stderr.write(
+ "This is pytest version %s, imported from %s\n" % (pytest.__version__, p)
+ )
+ plugininfo = getpluginversioninfo(config)
+ if plugininfo:
+ for line in plugininfo:
+ sys.stderr.write(line + "\n")
+
+
def pytest_cmdline_main(config):
if config.option.version:
- showversion(config)
+ showversion(config)
return 0
elif config.option.help:
config._do_configure()
@@ -142,8 +142,8 @@ def pytest_cmdline_main(config):
def showhelp(config):
- import textwrap
-
+ import textwrap
+
reporter = config.pluginmanager.get_plugin("terminalreporter")
tw = reporter._tw
tw.write(config._parser.optparser.format_help())
@@ -153,38 +153,38 @@ def showhelp(config):
)
tw.line()
- columns = tw.fullwidth # costly call
- indent_len = 24 # based on argparse's max_help_position=24
- indent = " " * indent_len
+ columns = tw.fullwidth # costly call
+ indent_len = 24 # based on argparse's max_help_position=24
+ indent = " " * indent_len
for name in config._parser._ininames:
help, type, default = config._parser._inidict[name]
if type is None:
type = "string"
- spec = "%s (%s):" % (name, type)
- tw.write(" %s" % spec)
- spec_len = len(spec)
- if spec_len > (indent_len - 3):
- # Display help starting at a new line.
- tw.line()
- helplines = textwrap.wrap(
- help,
- columns,
- initial_indent=indent,
- subsequent_indent=indent,
- break_on_hyphens=False,
- )
-
- for line in helplines:
- tw.line(line)
- else:
- # Display help starting after the spec, following lines indented.
- tw.write(" " * (indent_len - spec_len - 2))
- wrapped = textwrap.wrap(help, columns - indent_len, break_on_hyphens=False)
-
- tw.line(wrapped[0])
- for line in wrapped[1:]:
- tw.line(indent + line)
-
+ spec = "%s (%s):" % (name, type)
+ tw.write(" %s" % spec)
+ spec_len = len(spec)
+ if spec_len > (indent_len - 3):
+ # Display help starting at a new line.
+ tw.line()
+ helplines = textwrap.wrap(
+ help,
+ columns,
+ initial_indent=indent,
+ subsequent_indent=indent,
+ break_on_hyphens=False,
+ )
+
+ for line in helplines:
+ tw.line(line)
+ else:
+ # Display help starting after the spec, following lines indented.
+ tw.write(" " * (indent_len - spec_len - 2))
+ wrapped = textwrap.wrap(help, columns - indent_len, break_on_hyphens=False)
+
+ tw.line(wrapped[0])
+ for line in wrapped[1:]:
+ tw.line(indent + line)
+
tw.line()
tw.line("environment variables:")
vars = [
diff --git a/contrib/python/pytest/py2/_pytest/hookspec.py b/contrib/python/pytest/py2/_pytest/hookspec.py
index 7ab6154b17..d98652a199 100644
--- a/contrib/python/pytest/py2/_pytest/hookspec.py
+++ b/contrib/python/pytest/py2/_pytest/hookspec.py
@@ -1,8 +1,8 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" hook specifications for pytest plugins, invoked from main.py and builtin plugins. """
from pluggy import HookspecMarker
-from _pytest.deprecated import PYTEST_LOGWARNING
+from _pytest.deprecated import PYTEST_LOGWARNING
hookspec = HookspecMarker("pytest")
@@ -100,8 +100,8 @@ def pytest_cmdline_parse(pluginmanager, args):
Stops at first non-None result, see :ref:`firstresult`
.. note::
- This hook will only be called for plugin classes passed to the ``plugins`` arg when using `pytest.main`_ to
- perform an in-process test run.
+ This hook will only be called for plugin classes passed to the ``plugins`` arg when using `pytest.main`_ to
+ perform an in-process test run.
:param _pytest.config.PytestPluginManager pluginmanager: pytest plugin manager
:param list[str] args: list of arguments passed on the command line
@@ -189,7 +189,7 @@ def pytest_ignore_collect(path, config):
Stops at first non-None result, see :ref:`firstresult`
- :param path: a :py:class:`py.path.local` - the path to analyze
+ :param path: a :py:class:`py.path.local` - the path to analyze
:param _pytest.config.Config config: pytest config object
"""
@@ -200,7 +200,7 @@ def pytest_collect_directory(path, parent):
Stops at first non-None result, see :ref:`firstresult`
- :param path: a :py:class:`py.path.local` - the path to analyze
+ :param path: a :py:class:`py.path.local` - the path to analyze
"""
@@ -208,7 +208,7 @@ def pytest_collect_file(path, parent):
""" return collection Node or None for the given path. Any new node
needs to have the specified ``parent`` as a parent.
- :param path: a :py:class:`py.path.local` - the path to collect
+ :param path: a :py:class:`py.path.local` - the path to collect
"""
@@ -228,7 +228,7 @@ def pytest_collectreport(report):
def pytest_deselected(items):
- """ called for test items deselected, e.g. by keyword. """
+ """ called for test items deselected, e.g. by keyword. """
@hookspec(firstresult=True)
@@ -250,12 +250,12 @@ def pytest_pycollect_makemodule(path, parent):
The pytest_collect_file hook needs to be used if you want to
create test modules for files that do not match as a test module.
- Stops at first non-None result, see :ref:`firstresult`
-
- :param path: a :py:class:`py.path.local` - the path of module to collect
- """
+ Stops at first non-None result, see :ref:`firstresult`
+ :param path: a :py:class:`py.path.local` - the path of module to collect
+ """
+
@hookspec(firstresult=True)
def pytest_pycollect_makeitem(collector, name, obj):
""" return custom item/collector for a python object in a module, or None.
@@ -380,41 +380,41 @@ def pytest_runtest_logreport(report):
the respective phase of executing a test. """
-@hookspec(firstresult=True)
-def pytest_report_to_serializable(config, report):
- """
- .. warning::
- This hook is experimental and subject to change between pytest releases, even
- bug fixes.
-
- The intent is for this to be used by plugins maintained by the core-devs, such
- as ``pytest-xdist``, ``pytest-subtests``, and as a replacement for the internal
- 'resultlog' plugin.
-
- In the future it might become part of the public hook API.
-
- Serializes the given report object into a data structure suitable for sending
- over the wire, e.g. converted to JSON.
- """
-
-
-@hookspec(firstresult=True)
-def pytest_report_from_serializable(config, data):
- """
- .. warning::
- This hook is experimental and subject to change between pytest releases, even
- bug fixes.
-
- The intent is for this to be used by plugins maintained by the core-devs, such
- as ``pytest-xdist``, ``pytest-subtests``, and as a replacement for the internal
- 'resultlog' plugin.
-
- In the future it might become part of the public hook API.
-
- Restores a report object previously serialized with pytest_report_to_serializable().
- """
-
-
+@hookspec(firstresult=True)
+def pytest_report_to_serializable(config, report):
+ """
+ .. warning::
+ This hook is experimental and subject to change between pytest releases, even
+ bug fixes.
+
+ The intent is for this to be used by plugins maintained by the core-devs, such
+ as ``pytest-xdist``, ``pytest-subtests``, and as a replacement for the internal
+ 'resultlog' plugin.
+
+ In the future it might become part of the public hook API.
+
+ Serializes the given report object into a data structure suitable for sending
+ over the wire, e.g. converted to JSON.
+ """
+
+
+@hookspec(firstresult=True)
+def pytest_report_from_serializable(config, data):
+ """
+ .. warning::
+ This hook is experimental and subject to change between pytest releases, even
+ bug fixes.
+
+ The intent is for this to be used by plugins maintained by the core-devs, such
+ as ``pytest-xdist``, ``pytest-subtests``, and as a replacement for the internal
+ 'resultlog' plugin.
+
+ In the future it might become part of the public hook API.
+
+ Restores a report object previously serialized with pytest_report_to_serializable().
+ """
+
+
# -------------------------------------------------------------------------
# Fixture related hooks
# -------------------------------------------------------------------------
@@ -520,27 +520,27 @@ def pytest_report_collectionfinish(config, startdir, items):
@hookspec(firstresult=True)
-def pytest_report_teststatus(report, config):
+def pytest_report_teststatus(report, config):
""" return result-category, shortletter and verbose word for reporting.
- :param _pytest.config.Config config: pytest config object
-
+ :param _pytest.config.Config config: pytest config object
+
Stops at first non-None result, see :ref:`firstresult` """
-def pytest_terminal_summary(terminalreporter, exitstatus, config):
+def pytest_terminal_summary(terminalreporter, exitstatus, config):
"""Add a section to terminal summary reporting.
:param _pytest.terminal.TerminalReporter terminalreporter: the internal terminal reporter object
:param int exitstatus: the exit status that will be reported back to the OS
- :param _pytest.config.Config config: pytest config object
+ :param _pytest.config.Config config: pytest config object
- .. versionadded:: 4.2
+ .. versionadded:: 4.2
The ``config`` parameter.
"""
-@hookspec(historic=True, warn_on_impl=PYTEST_LOGWARNING)
+@hookspec(historic=True, warn_on_impl=PYTEST_LOGWARNING)
def pytest_logwarning(message, code, nodeid, fslocation):
"""
.. deprecated:: 3.8
diff --git a/contrib/python/pytest/py2/_pytest/junitxml.py b/contrib/python/pytest/py2/_pytest/junitxml.py
index 853dcb7744..2cd6f58ee2 100644
--- a/contrib/python/pytest/py2/_pytest/junitxml.py
+++ b/contrib/python/pytest/py2/_pytest/junitxml.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""
report test results in JUnit-XML format,
for use with Jenkins and build integration servers.
@@ -15,14 +15,14 @@ from __future__ import print_function
import functools
import os
-import platform
+import platform
import re
import sys
import time
-from datetime import datetime
+from datetime import datetime
import py
-import six
+import six
import pytest
from _pytest import nodes
@@ -45,12 +45,12 @@ class Junit(py.xml.Namespace):
_legal_chars = (0x09, 0x0A, 0x0D)
_legal_ranges = ((0x20, 0x7E), (0x80, 0xD7FF), (0xE000, 0xFFFD), (0x10000, 0x10FFFF))
_legal_xml_re = [
- u"%s-%s" % (six.unichr(low), six.unichr(high))
+ u"%s-%s" % (six.unichr(low), six.unichr(high))
for (low, high) in _legal_ranges
if low < sys.maxunicode
]
-_legal_xml_re = [six.unichr(x) for x in _legal_chars] + _legal_xml_re
-illegal_xml_re = re.compile(u"[^%s]" % u"".join(_legal_xml_re))
+_legal_xml_re = [six.unichr(x) for x in _legal_chars] + _legal_xml_re
+illegal_xml_re = re.compile(u"[^%s]" % u"".join(_legal_xml_re))
del _legal_chars
del _legal_ranges
del _legal_xml_re
@@ -62,41 +62,41 @@ def bin_xml_escape(arg):
def repl(matchobj):
i = ord(matchobj.group())
if i <= 0xFF:
- return u"#x%02X" % i
+ return u"#x%02X" % i
else:
- return u"#x%04X" % i
+ return u"#x%04X" % i
return py.xml.raw(illegal_xml_re.sub(repl, py.xml.escape(arg)))
-def merge_family(left, right):
- result = {}
- for kl, vl in left.items():
- for kr, vr in right.items():
- if not isinstance(vl, list):
- raise TypeError(type(vl))
- result[kl] = vl + vr
- left.update(result)
-
-
-families = {}
-families["_base"] = {"testcase": ["classname", "name"]}
-families["_base_legacy"] = {"testcase": ["file", "line", "url"]}
-
-# xUnit 1.x inherits legacy attributes
-families["xunit1"] = families["_base"].copy()
-merge_family(families["xunit1"], families["_base_legacy"])
-
-# xUnit 2.x uses strict base attributes
-families["xunit2"] = families["_base"]
-
-
+def merge_family(left, right):
+ result = {}
+ for kl, vl in left.items():
+ for kr, vr in right.items():
+ if not isinstance(vl, list):
+ raise TypeError(type(vl))
+ result[kl] = vl + vr
+ left.update(result)
+
+
+families = {}
+families["_base"] = {"testcase": ["classname", "name"]}
+families["_base_legacy"] = {"testcase": ["file", "line", "url"]}
+
+# xUnit 1.x inherits legacy attributes
+families["xunit1"] = families["_base"].copy()
+merge_family(families["xunit1"], families["_base_legacy"])
+
+# xUnit 2.x uses strict base attributes
+families["xunit2"] = families["_base"]
+
+
class _NodeReporter(object):
def __init__(self, nodeid, xml):
self.id = nodeid
self.xml = xml
self.add_stats = self.xml.add_stats
- self.family = self.xml.family
+ self.family = self.xml.family
self.duration = 0
self.properties = []
self.nodes = []
@@ -144,20 +144,20 @@ class _NodeReporter(object):
self.attrs = attrs
self.attrs.update(existing_attrs) # restore any user-defined attributes
- # Preserve legacy testcase behavior
- if self.family == "xunit1":
- return
-
- # Filter out attributes not permitted by this test family.
- # Including custom attributes because they are not valid here.
- temp_attrs = {}
- for key in self.attrs.keys():
- if key in families[self.family]["testcase"]:
- temp_attrs[key] = self.attrs[key]
- self.attrs = temp_attrs
-
+ # Preserve legacy testcase behavior
+ if self.family == "xunit1":
+ return
+
+ # Filter out attributes not permitted by this test family.
+ # Including custom attributes because they are not valid here.
+ temp_attrs = {}
+ for key in self.attrs.keys():
+ if key in families[self.family]["testcase"]:
+ temp_attrs[key] = self.attrs[key]
+ self.attrs = temp_attrs
+
def to_xml(self):
- testcase = Junit.testcase(time="%.3f" % self.duration, **self.attrs)
+ testcase = Junit.testcase(time="%.3f" % self.duration, **self.attrs)
testcase.append(self.make_properties_node())
for node in self.nodes:
testcase.append(node)
@@ -169,9 +169,9 @@ class _NodeReporter(object):
self.append(node)
def write_captured_output(self, report):
- if not self.xml.log_passing_tests and report.passed:
- return
-
+ if not self.xml.log_passing_tests and report.passed:
+ return
+
content_out = report.capstdout
content_log = report.caplog
content_err = report.capstderr
@@ -231,7 +231,7 @@ class _NodeReporter(object):
else:
if hasattr(report.longrepr, "reprcrash"):
message = report.longrepr.reprcrash.message
- elif isinstance(report.longrepr, six.string_types):
+ elif isinstance(report.longrepr, six.string_types):
message = report.longrepr
else:
message = str(report.longrepr)
@@ -250,7 +250,7 @@ class _NodeReporter(object):
self._add_simple(Junit.skipped, "collection skipped", report.longrepr)
def append_error(self, report):
- if report.when == "teardown":
+ if report.when == "teardown":
msg = "test teardown failure"
else:
msg = "test setup failure"
@@ -258,14 +258,14 @@ class _NodeReporter(object):
def append_skipped(self, report):
if hasattr(report, "wasxfail"):
- xfailreason = report.wasxfail
- if xfailreason.startswith("reason: "):
- xfailreason = xfailreason[8:]
- self.append(
- Junit.skipped(
- "", type="pytest.xfail", message=bin_xml_escape(xfailreason)
- )
- )
+ xfailreason = report.wasxfail
+ if xfailreason.startswith("reason: "):
+ xfailreason = xfailreason[8:]
+ self.append(
+ Junit.skipped(
+ "", type="pytest.xfail", message=bin_xml_escape(xfailreason)
+ )
+ )
else:
filename, lineno, skipreason = report.longrepr
if skipreason.startswith("Skipped: "):
@@ -287,21 +287,21 @@ class _NodeReporter(object):
self.to_xml = lambda: py.xml.raw(data)
-def _warn_incompatibility_with_xunit2(request, fixture_name):
- """Emits a PytestWarning about the given fixture being incompatible with newer xunit revisions"""
- from _pytest.warning_types import PytestWarning
-
- xml = getattr(request.config, "_xml", None)
- if xml is not None and xml.family not in ("xunit1", "legacy"):
- request.node.warn(
- PytestWarning(
- "{fixture_name} is incompatible with junit_family '{family}' (use 'legacy' or 'xunit1')".format(
- fixture_name=fixture_name, family=xml.family
- )
- )
- )
-
-
+def _warn_incompatibility_with_xunit2(request, fixture_name):
+ """Emits a PytestWarning about the given fixture being incompatible with newer xunit revisions"""
+ from _pytest.warning_types import PytestWarning
+
+ xml = getattr(request.config, "_xml", None)
+ if xml is not None and xml.family not in ("xunit1", "legacy"):
+ request.node.warn(
+ PytestWarning(
+ "{fixture_name} is incompatible with junit_family '{family}' (use 'legacy' or 'xunit1')".format(
+ fixture_name=fixture_name, family=xml.family
+ )
+ )
+ )
+
+
@pytest.fixture
def record_property(request):
"""Add an extra properties the calling test.
@@ -315,7 +315,7 @@ def record_property(request):
def test_function(record_property):
record_property("example_key", 1)
"""
- _warn_incompatibility_with_xunit2(request, "record_property")
+ _warn_incompatibility_with_xunit2(request, "record_property")
def append_property(name, value):
request.node.user_properties.append((name, value))
@@ -329,67 +329,67 @@ def record_xml_attribute(request):
The fixture is callable with ``(name, value)``, with value being
automatically xml-encoded
"""
- from _pytest.warning_types import PytestExperimentalApiWarning
-
- request.node.warn(
- PytestExperimentalApiWarning("record_xml_attribute is an experimental feature")
- )
-
- _warn_incompatibility_with_xunit2(request, "record_xml_attribute")
-
- # Declare noop
- def add_attr_noop(name, value):
- pass
-
- attr_func = add_attr_noop
-
+ from _pytest.warning_types import PytestExperimentalApiWarning
+
+ request.node.warn(
+ PytestExperimentalApiWarning("record_xml_attribute is an experimental feature")
+ )
+
+ _warn_incompatibility_with_xunit2(request, "record_xml_attribute")
+
+ # Declare noop
+ def add_attr_noop(name, value):
+ pass
+
+ attr_func = add_attr_noop
+
xml = getattr(request.config, "_xml", None)
if xml is not None:
node_reporter = xml.node_reporter(request.node.nodeid)
- attr_func = node_reporter.add_attribute
-
- return attr_func
-
-
-def _check_record_param_type(param, v):
- """Used by record_testsuite_property to check that the given parameter name is of the proper
- type"""
- __tracebackhide__ = True
- if not isinstance(v, six.string_types):
- msg = "{param} parameter needs to be a string, but {g} given"
- raise TypeError(msg.format(param=param, g=type(v).__name__))
-
-
-@pytest.fixture(scope="session")
-def record_testsuite_property(request):
- """
- Records a new ``<property>`` tag as child of the root ``<testsuite>``. This is suitable to
- writing global information regarding the entire test suite, and is compatible with ``xunit2`` JUnit family.
-
- This is a ``session``-scoped fixture which is called with ``(name, value)``. Example:
-
- .. code-block:: python
-
- def test_foo(record_testsuite_property):
- record_testsuite_property("ARCH", "PPC")
- record_testsuite_property("STORAGE_TYPE", "CEPH")
-
- ``name`` must be a string, ``value`` will be converted to a string and properly xml-escaped.
- """
-
- __tracebackhide__ = True
-
- def record_func(name, value):
- """noop function in case --junitxml was not passed in the command-line"""
- __tracebackhide__ = True
- _check_record_param_type("name", name)
-
- xml = getattr(request.config, "_xml", None)
- if xml is not None:
- record_func = xml.add_global_property # noqa
- return record_func
-
-
+ attr_func = node_reporter.add_attribute
+
+ return attr_func
+
+
+def _check_record_param_type(param, v):
+ """Used by record_testsuite_property to check that the given parameter name is of the proper
+ type"""
+ __tracebackhide__ = True
+ if not isinstance(v, six.string_types):
+ msg = "{param} parameter needs to be a string, but {g} given"
+ raise TypeError(msg.format(param=param, g=type(v).__name__))
+
+
+@pytest.fixture(scope="session")
+def record_testsuite_property(request):
+ """
+ Records a new ``<property>`` tag as child of the root ``<testsuite>``. This is suitable to
+ writing global information regarding the entire test suite, and is compatible with ``xunit2`` JUnit family.
+
+ This is a ``session``-scoped fixture which is called with ``(name, value)``. Example:
+
+ .. code-block:: python
+
+ def test_foo(record_testsuite_property):
+ record_testsuite_property("ARCH", "PPC")
+ record_testsuite_property("STORAGE_TYPE", "CEPH")
+
+ ``name`` must be a string, ``value`` will be converted to a string and properly xml-escaped.
+ """
+
+ __tracebackhide__ = True
+
+ def record_func(name, value):
+ """noop function in case --junitxml was not passed in the command-line"""
+ __tracebackhide__ = True
+ _check_record_param_type("name", name)
+
+ xml = getattr(request.config, "_xml", None)
+ if xml is not None:
+ record_func = xml.add_global_property # noqa
+ return record_func
+
+
def pytest_addoption(parser):
group = parser.getgroup("terminal reporting")
group.addoption(
@@ -419,22 +419,22 @@ def pytest_addoption(parser):
"one of no|system-out|system-err",
default="no",
) # choices=['no', 'stdout', 'stderr'])
- parser.addini(
- "junit_log_passing_tests",
- "Capture log information for passing tests to JUnit report: ",
- type="bool",
- default=True,
- )
- parser.addini(
- "junit_duration_report",
- "Duration time to report: one of total|call",
- default="total",
- ) # choices=['total', 'call'])
- parser.addini(
- "junit_family",
- "Emit XML for schema: one of legacy|xunit1|xunit2",
- default="xunit1",
- )
+ parser.addini(
+ "junit_log_passing_tests",
+ "Capture log information for passing tests to JUnit report: ",
+ type="bool",
+ default=True,
+ )
+ parser.addini(
+ "junit_duration_report",
+ "Duration time to report: one of total|call",
+ default="total",
+ ) # choices=['total', 'call'])
+ parser.addini(
+ "junit_family",
+ "Emit XML for schema: one of legacy|xunit1|xunit2",
+ default="xunit1",
+ )
def pytest_configure(config):
@@ -446,9 +446,9 @@ def pytest_configure(config):
config.option.junitprefix,
config.getini("junit_suite_name"),
config.getini("junit_logging"),
- config.getini("junit_duration_report"),
- config.getini("junit_family"),
- config.getini("junit_log_passing_tests"),
+ config.getini("junit_duration_report"),
+ config.getini("junit_family"),
+ config.getini("junit_log_passing_tests"),
)
config.pluginmanager.register(config._xml)
@@ -476,37 +476,37 @@ def mangle_test_address(address):
class LogXML(object):
- def __init__(
- self,
- logfile,
- prefix,
- suite_name="pytest",
- logging="no",
- report_duration="total",
- family="xunit1",
- log_passing_tests=True,
- ):
+ def __init__(
+ self,
+ logfile,
+ prefix,
+ suite_name="pytest",
+ logging="no",
+ report_duration="total",
+ family="xunit1",
+ log_passing_tests=True,
+ ):
logfile = os.path.expanduser(os.path.expandvars(logfile))
self.logfile = os.path.normpath(os.path.abspath(logfile))
self.prefix = prefix
self.suite_name = suite_name
self.logging = logging
- self.log_passing_tests = log_passing_tests
- self.report_duration = report_duration
- self.family = family
+ self.log_passing_tests = log_passing_tests
+ self.report_duration = report_duration
+ self.family = family
self.stats = dict.fromkeys(["error", "passed", "failure", "skipped"], 0)
self.node_reporters = {} # nodeid -> _NodeReporter
self.node_reporters_ordered = []
self.global_properties = []
-
+
# List of reports that failed on call but teardown is pending.
self.open_reports = []
self.cnt_double_fail_tests = 0
- # Replaces convenience family with real family
- if self.family == "legacy":
- self.family = "xunit1"
-
+ # Replaces convenience family with real family
+ if self.family == "legacy":
+ self.family = "xunit1"
+
def finalize(self, report):
nodeid = getattr(report, "nodeid", report)
# local hack to handle xdist report order
@@ -597,8 +597,8 @@ class LogXML(object):
if report.when == "call":
reporter.append_failure(report)
self.open_reports.append(report)
- if not self.log_passing_tests:
- reporter.write_captured_output(report)
+ if not self.log_passing_tests:
+ reporter.write_captured_output(report)
else:
reporter.append_error(report)
elif report.skipped:
@@ -634,9 +634,9 @@ class LogXML(object):
"""accumulates total duration for nodeid from given report and updates
the Junit.testcase with the new total if already created.
"""
- if self.report_duration == "total" or report.when == self.report_duration:
- reporter = self.node_reporter(report)
- reporter.duration += getattr(report, "duration", 0.0)
+ if self.report_duration == "total" or report.when == self.report_duration:
+ reporter = self.node_reporter(report)
+ reporter.duration += getattr(report, "duration", 0.0)
def pytest_collectreport(self, report):
if not report.passed:
@@ -671,28 +671,28 @@ class LogXML(object):
)
logfile.write('<?xml version="1.0" encoding="utf-8"?>')
- suite_node = Junit.testsuite(
- self._get_global_properties_node(),
- [x.to_xml() for x in self.node_reporters_ordered],
- name=self.suite_name,
- errors=self.stats["error"],
- failures=self.stats["failure"],
- skipped=self.stats["skipped"],
- tests=numtests,
- time="%.3f" % suite_time_delta,
- timestamp=datetime.fromtimestamp(self.suite_start_time).isoformat(),
- hostname=platform.node(),
+ suite_node = Junit.testsuite(
+ self._get_global_properties_node(),
+ [x.to_xml() for x in self.node_reporters_ordered],
+ name=self.suite_name,
+ errors=self.stats["error"],
+ failures=self.stats["failure"],
+ skipped=self.stats["skipped"],
+ tests=numtests,
+ time="%.3f" % suite_time_delta,
+ timestamp=datetime.fromtimestamp(self.suite_start_time).isoformat(),
+ hostname=platform.node(),
)
- logfile.write(Junit.testsuites([suite_node]).unicode(indent=0))
+ logfile.write(Junit.testsuites([suite_node]).unicode(indent=0))
logfile.close()
def pytest_terminal_summary(self, terminalreporter):
terminalreporter.write_sep("-", "generated xml file: %s" % (self.logfile))
def add_global_property(self, name, value):
- __tracebackhide__ = True
- _check_record_param_type("name", name)
- self.global_properties.append((name, bin_xml_escape(value)))
+ __tracebackhide__ = True
+ _check_record_param_type("name", name)
+ self.global_properties.append((name, bin_xml_escape(value)))
def _get_global_properties_node(self):
"""Return a Junit node containing custom properties, if any.
diff --git a/contrib/python/pytest/py2/_pytest/logging.py b/contrib/python/pytest/py2/_pytest/logging.py
index 2400737ee4..0f94f361db 100644
--- a/contrib/python/pytest/py2/_pytest/logging.py
+++ b/contrib/python/pytest/py2/_pytest/logging.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" Access and control log capturing. """
from __future__ import absolute_import
from __future__ import division
@@ -14,17 +14,17 @@ import six
import pytest
from _pytest.compat import dummy_context_manager
from _pytest.config import create_terminal_writer
-from _pytest.pathlib import Path
+from _pytest.pathlib import Path
-DEFAULT_LOG_FORMAT = "%(levelname)-8s %(name)s:%(filename)s:%(lineno)d %(message)s"
+DEFAULT_LOG_FORMAT = "%(levelname)-8s %(name)s:%(filename)s:%(lineno)d %(message)s"
DEFAULT_LOG_DATE_FORMAT = "%H:%M:%S"
-_ANSI_ESCAPE_SEQ = re.compile(r"\x1b\[[\d;]+m")
-
-
-def _remove_ansi_escape_sequences(text):
- return _ANSI_ESCAPE_SEQ.sub("", text)
+_ANSI_ESCAPE_SEQ = re.compile(r"\x1b\[[\d;]+m")
+def _remove_ansi_escape_sequences(text):
+ return _ANSI_ESCAPE_SEQ.sub("", text)
+
+
class ColoredLevelFormatter(logging.Formatter):
"""
Colorize the %(levelname)..s part of the log format passed to __init__.
@@ -77,36 +77,36 @@ class ColoredLevelFormatter(logging.Formatter):
return super(ColoredLevelFormatter, self).format(record)
-if not six.PY2:
- # Formatter classes don't support format styles in PY2
-
- class PercentStyleMultiline(logging.PercentStyle):
- """A logging style with special support for multiline messages.
-
- If the message of a record consists of multiple lines, this style
- formats the message as if each line were logged separately.
- """
-
- @staticmethod
- def _update_message(record_dict, message):
- tmp = record_dict.copy()
- tmp["message"] = message
- return tmp
-
- def format(self, record):
- if "\n" in record.message:
- lines = record.message.splitlines()
- formatted = self._fmt % self._update_message(record.__dict__, lines[0])
- # TODO optimize this by introducing an option that tells the
- # logging framework that the indentation doesn't
- # change. This allows to compute the indentation only once.
- indentation = _remove_ansi_escape_sequences(formatted).find(lines[0])
- lines[0] = formatted
- return ("\n" + " " * indentation).join(lines)
- else:
- return self._fmt % record.__dict__
-
-
+if not six.PY2:
+ # Formatter classes don't support format styles in PY2
+
+ class PercentStyleMultiline(logging.PercentStyle):
+ """A logging style with special support for multiline messages.
+
+ If the message of a record consists of multiple lines, this style
+ formats the message as if each line were logged separately.
+ """
+
+ @staticmethod
+ def _update_message(record_dict, message):
+ tmp = record_dict.copy()
+ tmp["message"] = message
+ return tmp
+
+ def format(self, record):
+ if "\n" in record.message:
+ lines = record.message.splitlines()
+ formatted = self._fmt % self._update_message(record.__dict__, lines[0])
+ # TODO optimize this by introducing an option that tells the
+ # logging framework that the indentation doesn't
+ # change. This allows to compute the indentation only once.
+ indentation = _remove_ansi_escape_sequences(formatted).find(lines[0])
+ lines[0] = formatted
+ return ("\n" + " " * indentation).join(lines)
+ else:
+ return self._fmt % record.__dict__
+
+
def get_option_ini(config, *names):
for name in names:
ret = config.getoption(name) # 'default' arg won't work as expected
@@ -253,7 +253,7 @@ class LogCaptureFixture(object):
"""Creates a new funcarg."""
self._item = item
# dict of log name -> log level
- self._initial_log_levels = {} # Dict[str, int]
+ self._initial_log_levels = {} # Dict[str, int]
def _finalize(self):
"""Finalizes the fixture.
@@ -292,8 +292,8 @@ class LogCaptureFixture(object):
@property
def text(self):
- """Returns the formatted log text."""
- return _remove_ansi_escape_sequences(self.handler.stream.getvalue())
+ """Returns the formatted log text."""
+ return _remove_ansi_escape_sequences(self.handler.stream.getvalue())
@property
def records(self):
@@ -406,8 +406,8 @@ def get_actual_log_level(config, *setting_names):
)
-# run after terminalreporter/capturemanager are configured
-@pytest.hookimpl(trylast=True)
+# run after terminalreporter/capturemanager are configured
+@pytest.hookimpl(trylast=True)
def pytest_configure(config):
config.pluginmanager.register(LoggingPlugin(config), "logging-plugin")
@@ -425,99 +425,99 @@ class LoggingPlugin(object):
self._config = config
self.print_logs = get_option_ini(config, "log_print")
- self.formatter = self._create_formatter(
+ self.formatter = self._create_formatter(
get_option_ini(config, "log_format"),
get_option_ini(config, "log_date_format"),
)
self.log_level = get_actual_log_level(config, "log_level")
- self.log_file_level = get_actual_log_level(config, "log_file_level")
- self.log_file_format = get_option_ini(config, "log_file_format", "log_format")
- self.log_file_date_format = get_option_ini(
- config, "log_file_date_format", "log_date_format"
- )
- self.log_file_formatter = logging.Formatter(
- self.log_file_format, datefmt=self.log_file_date_format
- )
-
+ self.log_file_level = get_actual_log_level(config, "log_file_level")
+ self.log_file_format = get_option_ini(config, "log_file_format", "log_format")
+ self.log_file_date_format = get_option_ini(
+ config, "log_file_date_format", "log_date_format"
+ )
+ self.log_file_formatter = logging.Formatter(
+ self.log_file_format, datefmt=self.log_file_date_format
+ )
+
log_file = get_option_ini(config, "log_file")
if log_file:
self.log_file_handler = logging.FileHandler(
log_file, mode="w", encoding="UTF-8"
)
- self.log_file_handler.setFormatter(self.log_file_formatter)
+ self.log_file_handler.setFormatter(self.log_file_formatter)
else:
self.log_file_handler = None
self.log_cli_handler = None
- self.live_logs_context = lambda: dummy_context_manager()
- # Note that the lambda for the live_logs_context is needed because
- # live_logs_context can otherwise not be entered multiple times due
- # to limitations of contextlib.contextmanager.
-
- if self._log_cli_enabled():
- self._setup_cli_logging()
-
- def _create_formatter(self, log_format, log_date_format):
- # color option doesn't exist if terminal plugin is disabled
- color = getattr(self._config.option, "color", "no")
- if color != "no" and ColoredLevelFormatter.LEVELNAME_FMT_REGEX.search(
- log_format
- ):
- formatter = ColoredLevelFormatter(
- create_terminal_writer(self._config), log_format, log_date_format
- )
- else:
- formatter = logging.Formatter(log_format, log_date_format)
-
- if not six.PY2:
- formatter._style = PercentStyleMultiline(formatter._style._fmt)
- return formatter
-
- def _setup_cli_logging(self):
- config = self._config
- terminal_reporter = config.pluginmanager.get_plugin("terminalreporter")
- if terminal_reporter is None:
- # terminal reporter is disabled e.g. by pytest-xdist.
- return
-
- capture_manager = config.pluginmanager.get_plugin("capturemanager")
- # if capturemanager plugin is disabled, live logging still works.
- log_cli_handler = _LiveLoggingStreamHandler(terminal_reporter, capture_manager)
-
- log_cli_formatter = self._create_formatter(
- get_option_ini(config, "log_cli_format", "log_format"),
- get_option_ini(config, "log_cli_date_format", "log_date_format"),
- )
-
- log_cli_level = get_actual_log_level(config, "log_cli_level", "log_level")
- self.log_cli_handler = log_cli_handler
- self.live_logs_context = lambda: catching_logs(
- log_cli_handler, formatter=log_cli_formatter, level=log_cli_level
- )
-
- def set_log_path(self, fname):
- """Public method, which can set filename parameter for
- Logging.FileHandler(). Also creates parent directory if
- it does not exist.
-
- .. warning::
- Please considered as an experimental API.
- """
- fname = Path(fname)
-
- if not fname.is_absolute():
- fname = Path(self._config.rootdir, fname)
-
- if not fname.parent.exists():
- fname.parent.mkdir(exist_ok=True, parents=True)
-
- self.log_file_handler = logging.FileHandler(
- str(fname), mode="w", encoding="UTF-8"
- )
- self.log_file_handler.setFormatter(self.log_file_formatter)
-
+ self.live_logs_context = lambda: dummy_context_manager()
+ # Note that the lambda for the live_logs_context is needed because
+ # live_logs_context can otherwise not be entered multiple times due
+ # to limitations of contextlib.contextmanager.
+
+ if self._log_cli_enabled():
+ self._setup_cli_logging()
+
+ def _create_formatter(self, log_format, log_date_format):
+ # color option doesn't exist if terminal plugin is disabled
+ color = getattr(self._config.option, "color", "no")
+ if color != "no" and ColoredLevelFormatter.LEVELNAME_FMT_REGEX.search(
+ log_format
+ ):
+ formatter = ColoredLevelFormatter(
+ create_terminal_writer(self._config), log_format, log_date_format
+ )
+ else:
+ formatter = logging.Formatter(log_format, log_date_format)
+
+ if not six.PY2:
+ formatter._style = PercentStyleMultiline(formatter._style._fmt)
+ return formatter
+
+ def _setup_cli_logging(self):
+ config = self._config
+ terminal_reporter = config.pluginmanager.get_plugin("terminalreporter")
+ if terminal_reporter is None:
+ # terminal reporter is disabled e.g. by pytest-xdist.
+ return
+
+ capture_manager = config.pluginmanager.get_plugin("capturemanager")
+ # if capturemanager plugin is disabled, live logging still works.
+ log_cli_handler = _LiveLoggingStreamHandler(terminal_reporter, capture_manager)
+
+ log_cli_formatter = self._create_formatter(
+ get_option_ini(config, "log_cli_format", "log_format"),
+ get_option_ini(config, "log_cli_date_format", "log_date_format"),
+ )
+
+ log_cli_level = get_actual_log_level(config, "log_cli_level", "log_level")
+ self.log_cli_handler = log_cli_handler
+ self.live_logs_context = lambda: catching_logs(
+ log_cli_handler, formatter=log_cli_formatter, level=log_cli_level
+ )
+
+ def set_log_path(self, fname):
+ """Public method, which can set filename parameter for
+ Logging.FileHandler(). Also creates parent directory if
+ it does not exist.
+
+ .. warning::
+ Please considered as an experimental API.
+ """
+ fname = Path(fname)
+
+ if not fname.is_absolute():
+ fname = Path(self._config.rootdir, fname)
+
+ if not fname.parent.exists():
+ fname.parent.mkdir(exist_ok=True, parents=True)
+
+ self.log_file_handler = logging.FileHandler(
+ str(fname), mode="w", encoding="UTF-8"
+ )
+ self.log_file_handler.setFormatter(self.log_file_formatter)
+
def _log_cli_enabled(self):
"""Return True if log_cli should be considered enabled, either explicitly
or because --log-cli-level was given in the command-line.
@@ -540,15 +540,15 @@ class LoggingPlugin(object):
@contextmanager
def _runtest_for(self, item, when):
- with self._runtest_for_main(item, when):
- if self.log_file_handler is not None:
- with catching_logs(self.log_file_handler, level=self.log_file_level):
- yield
- else:
- yield
-
- @contextmanager
- def _runtest_for_main(self, item, when):
+ with self._runtest_for_main(item, when):
+ if self.log_file_handler is not None:
+ with catching_logs(self.log_file_handler, level=self.log_file_level):
+ yield
+ else:
+ yield
+
+ @contextmanager
+ def _runtest_for_main(self, item, when):
"""Implements the internals of pytest_runtest_xxx() hook."""
with catching_logs(
LogCaptureHandler(), formatter=self.formatter, level=self.log_level
@@ -603,26 +603,26 @@ class LoggingPlugin(object):
with self._runtest_for(None, "finish"):
yield
- @pytest.hookimpl(hookwrapper=True)
- def pytest_runtest_logreport(self):
- with self._runtest_for(None, "logreport"):
- yield
-
+ @pytest.hookimpl(hookwrapper=True)
+ def pytest_runtest_logreport(self):
+ with self._runtest_for(None, "logreport"):
+ yield
+
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_sessionfinish(self):
with self.live_logs_context():
if self.log_cli_handler:
self.log_cli_handler.set_when("sessionfinish")
if self.log_file_handler is not None:
- try:
- with catching_logs(
- self.log_file_handler, level=self.log_file_level
- ):
- yield
- finally:
- # Close the FileHandler explicitly.
- # (logging.shutdown might have lost the weakref?!)
- self.log_file_handler.close()
+ try:
+ with catching_logs(
+ self.log_file_handler, level=self.log_file_level
+ ):
+ yield
+ finally:
+ # Close the FileHandler explicitly.
+ # (logging.shutdown might have lost the weakref?!)
+ self.log_file_handler.close()
else:
yield
@@ -640,15 +640,15 @@ class LoggingPlugin(object):
@pytest.hookimpl(hookwrapper=True)
def pytest_runtestloop(self, session):
"""Runs all collected test items."""
-
- if session.config.option.collectonly:
- yield
- return
-
- if self._log_cli_enabled() and self._config.getoption("verbose") < 1:
- # setting verbose flag is needed to avoid messy test progress output
- self._config.option.verbose = 1
-
+
+ if session.config.option.collectonly:
+ yield
+ return
+
+ if self._log_cli_enabled() and self._config.getoption("verbose") < 1:
+ # setting verbose flag is needed to avoid messy test progress output
+ self._config.option.verbose = 1
+
with self.live_logs_context():
if self.log_file_handler is not None:
with catching_logs(self.log_file_handler, level=self.log_file_level):
diff --git a/contrib/python/pytest/py2/_pytest/main.py b/contrib/python/pytest/py2/_pytest/main.py
index a9d310cb62..95af7acf96 100644
--- a/contrib/python/pytest/py2/_pytest/main.py
+++ b/contrib/python/pytest/py2/_pytest/main.py
@@ -1,16 +1,16 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" core implementation of testing process: init, session, runtest loop. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import contextlib
-import fnmatch
+import fnmatch
import functools
import os
import pkgutil
import sys
-import warnings
+import warnings
import attr
import py
@@ -21,7 +21,7 @@ from _pytest import nodes
from _pytest.config import directory_arg
from _pytest.config import hookimpl
from _pytest.config import UsageError
-from _pytest.deprecated import PYTEST_CONFIG_GLOBAL
+from _pytest.deprecated import PYTEST_CONFIG_GLOBAL
from _pytest.outcomes import exit
from _pytest.runner import collect_one_node
@@ -67,10 +67,10 @@ def pytest_addoption(parser):
help="exit after first num failures or errors.",
)
group._addoption(
- "--strict-markers",
+ "--strict-markers",
"--strict",
action="store_true",
- help="markers not registered in the `markers` section of the configuration file raise errors.",
+ help="markers not registered in the `markers` section of the configuration file raise errors.",
)
group._addoption(
"-c",
@@ -115,12 +115,12 @@ def pytest_addoption(parser):
help="ignore path during collection (multi-allowed).",
)
group.addoption(
- "--ignore-glob",
- action="append",
- metavar="path",
- help="ignore path pattern during collection (multi-allowed).",
- )
- group.addoption(
+ "--ignore-glob",
+ action="append",
+ metavar="path",
+ help="ignore path pattern during collection (multi-allowed).",
+ )
+ group.addoption(
"--deselect",
action="append",
metavar="nodeid_prefix",
@@ -172,24 +172,24 @@ def pytest_addoption(parser):
)
-class _ConfigDeprecated(object):
- def __init__(self, config):
- self.__dict__["_config"] = config
-
- def __getattr__(self, attr):
- warnings.warn(PYTEST_CONFIG_GLOBAL, stacklevel=2)
- return getattr(self._config, attr)
-
- def __setattr__(self, attr, val):
- warnings.warn(PYTEST_CONFIG_GLOBAL, stacklevel=2)
- return setattr(self._config, attr, val)
-
- def __repr__(self):
- return "{}({!r})".format(type(self).__name__, self._config)
-
-
+class _ConfigDeprecated(object):
+ def __init__(self, config):
+ self.__dict__["_config"] = config
+
+ def __getattr__(self, attr):
+ warnings.warn(PYTEST_CONFIG_GLOBAL, stacklevel=2)
+ return getattr(self._config, attr)
+
+ def __setattr__(self, attr, val):
+ warnings.warn(PYTEST_CONFIG_GLOBAL, stacklevel=2)
+ return setattr(self._config, attr, val)
+
+ def __repr__(self):
+ return "{}({!r})".format(type(self).__name__, self._config)
+
+
def pytest_configure(config):
- __import__("pytest").config = _ConfigDeprecated(config) # compatibility
+ __import__("pytest").config = _ConfigDeprecated(config) # compatibility
def wrap_session(config, doit):
@@ -205,28 +205,28 @@ def wrap_session(config, doit):
initstate = 2
session.exitstatus = doit(config, session) or 0
except UsageError:
- session.exitstatus = EXIT_USAGEERROR
+ session.exitstatus = EXIT_USAGEERROR
raise
except Failed:
session.exitstatus = EXIT_TESTSFAILED
- except (KeyboardInterrupt, exit.Exception):
- excinfo = _pytest._code.ExceptionInfo.from_current()
+ except (KeyboardInterrupt, exit.Exception):
+ excinfo = _pytest._code.ExceptionInfo.from_current()
exitstatus = EXIT_INTERRUPTED
- if isinstance(excinfo.value, exit.Exception):
+ if isinstance(excinfo.value, exit.Exception):
if excinfo.value.returncode is not None:
exitstatus = excinfo.value.returncode
- if initstate < 2:
- sys.stderr.write(
- "{}: {}\n".format(excinfo.typename, excinfo.value.msg)
- )
+ if initstate < 2:
+ sys.stderr.write(
+ "{}: {}\n".format(excinfo.typename, excinfo.value.msg)
+ )
config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
session.exitstatus = exitstatus
except: # noqa
- excinfo = _pytest._code.ExceptionInfo.from_current()
+ excinfo = _pytest._code.ExceptionInfo.from_current()
config.notify_exception(excinfo, config.option)
session.exitstatus = EXIT_INTERNALERROR
if excinfo.errisinstance(SystemExit):
- sys.stderr.write("mainloop: caught unexpected SystemExit!\n")
+ sys.stderr.write("mainloop: caught unexpected SystemExit!\n")
finally:
excinfo = None # Explicitly break reference cycle.
@@ -303,20 +303,20 @@ def pytest_ignore_collect(path, config):
if py.path.local(path) in ignore_paths:
return True
- ignore_globs = config._getconftest_pathlist(
- "collect_ignore_glob", path=path.dirpath()
- )
- ignore_globs = ignore_globs or []
- excludeglobopt = config.getoption("ignore_glob")
- if excludeglobopt:
- ignore_globs.extend([py.path.local(x) for x in excludeglobopt])
-
- if any(
- fnmatch.fnmatch(six.text_type(path), six.text_type(glob))
- for glob in ignore_globs
- ):
- return True
-
+ ignore_globs = config._getconftest_pathlist(
+ "collect_ignore_glob", path=path.dirpath()
+ )
+ ignore_globs = ignore_globs or []
+ excludeglobopt = config.getoption("ignore_glob")
+ if excludeglobopt:
+ ignore_globs.extend([py.path.local(x) for x in excludeglobopt])
+
+ if any(
+ fnmatch.fnmatch(six.text_type(path), six.text_type(glob))
+ for glob in ignore_globs
+ ):
+ return True
+
allow_in_venv = config.getoption("collect_in_virtualenv")
if not allow_in_venv and _in_venv(path):
return True
@@ -432,7 +432,7 @@ class Session(nodes.FSCollector):
self.shouldfail = False
self.trace = config.trace.root.get("collection")
self._norecursepatterns = config.getini("norecursedirs")
- self.startdir = config.invocation_dir
+ self.startdir = config.invocation_dir
self._initialpaths = frozenset()
# Keep track of any collected nodes in here, so we don't duplicate fixtures
self._node_cache = {}
@@ -442,15 +442,15 @@ class Session(nodes.FSCollector):
self.config.pluginmanager.register(self, name="session")
- def __repr__(self):
- return "<%s %s exitstatus=%r testsfailed=%d testscollected=%d>" % (
- self.__class__.__name__,
- self.name,
- getattr(self, "exitstatus", "<UNSET>"),
- self.testsfailed,
- self.testscollected,
- )
-
+ def __repr__(self):
+ return "<%s %s exitstatus=%r testsfailed=%d testscollected=%d>" % (
+ self.__class__.__name__,
+ self.name,
+ getattr(self, "exitstatus", "<UNSET>"),
+ self.testsfailed,
+ self.testscollected,
+ )
+
def _node_location_to_relpath(self, node_path):
# bestrelpath is a quite slow function
return self._bestrelpathcache[node_path]
@@ -558,7 +558,7 @@ class Session(nodes.FSCollector):
# Start with a Session root, and delve to argpath item (dir or file)
# and stack all Packages found on the way.
# No point in finding packages when collecting doctests
- if not self.config.getoption("doctestmodules", False):
+ if not self.config.getoption("doctestmodules", False):
pm = self.config.pluginmanager
for parent in reversed(argpath.parts()):
if pm._confcutdir and pm._confcutdir.relto(parent):
@@ -582,7 +582,7 @@ class Session(nodes.FSCollector):
seen_dirs = set()
for path in argpath.visit(
- fil=self._visit_filter, rec=self._recurse, bf=True, sort=True
+ fil=self._visit_filter, rec=self._recurse, bf=True, sort=True
):
dirpath = path.dirpath()
if dirpath not in seen_dirs:
@@ -612,7 +612,7 @@ class Session(nodes.FSCollector):
col = self._node_cache[argpath]
else:
collect_root = self._pkg_roots.get(argpath.dirname, self)
- col = collect_root._collectfile(argpath, handle_dupes=False)
+ col = collect_root._collectfile(argpath, handle_dupes=False)
if col:
self._node_cache[argpath] = col
m = self.matchnodes(col, names)
@@ -621,24 +621,24 @@ class Session(nodes.FSCollector):
# Module itself, so just use that. If this special case isn't taken, then all
# the files in the package will be yielded.
if argpath.basename == "__init__.py":
- try:
- yield next(m[0].collect())
- except StopIteration:
- # The package collects nothing with only an __init__.py
- # file in it, which gets ignored by the default
- # "python_files" option.
- pass
+ try:
+ yield next(m[0].collect())
+ except StopIteration:
+ # The package collects nothing with only an __init__.py
+ # file in it, which gets ignored by the default
+ # "python_files" option.
+ pass
return
for y in m:
yield y
def _collectfile(self, path, handle_dupes=True):
- assert path.isfile(), "%r is not a file (isdir=%r, exists=%r, islink=%r)" % (
- path,
- path.isdir(),
- path.exists(),
- path.islink(),
- )
+ assert path.isfile(), "%r is not a file (isdir=%r, exists=%r, islink=%r)" % (
+ path,
+ path.isdir(),
+ path.exists(),
+ path.islink(),
+ )
ihook = self.gethookproxy(path)
if not self.isinitpath(path):
if ihook.pytest_ignore_collect(path=path, config=self.config):
@@ -668,18 +668,18 @@ class Session(nodes.FSCollector):
ihook.pytest_collect_directory(path=dirpath, parent=self)
return True
- if six.PY2:
-
- @staticmethod
- def _visit_filter(f):
- return f.check(file=1) and not f.strpath.endswith("*.pyc")
-
- else:
-
- @staticmethod
- def _visit_filter(f):
- return f.check(file=1)
-
+ if six.PY2:
+
+ @staticmethod
+ def _visit_filter(f):
+ return f.check(file=1) and not f.strpath.endswith("*.pyc")
+
+ else:
+
+ @staticmethod
+ def _visit_filter(f):
+ return f.check(file=1)
+
def _tryconvertpyarg(self, x):
"""Convert a dotted module name to path."""
try:
diff --git a/contrib/python/pytest/py2/_pytest/mark/__init__.py b/contrib/python/pytest/py2/_pytest/mark/__init__.py
index 6bc22fe27d..3d0f5912c8 100644
--- a/contrib/python/pytest/py2/_pytest/mark/__init__.py
+++ b/contrib/python/pytest/py2/_pytest/mark/__init__.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" generic mechanism for marking and selecting python functions. """
from __future__ import absolute_import
from __future__ import division
@@ -15,7 +15,7 @@ from .structures import MarkGenerator
from .structures import ParameterSet
from _pytest.config import UsageError
-__all__ = ["Mark", "MarkDecorator", "MarkGenerator", "get_empty_parameterset_mark"]
+__all__ = ["Mark", "MarkDecorator", "MarkGenerator", "get_empty_parameterset_mark"]
def param(*values, **kw):
@@ -53,7 +53,7 @@ def pytest_addoption(parser):
"other' matches all test functions and classes whose name "
"contains 'test_method' or 'test_other', while -k 'not test_method' "
"matches those that don't contain 'test_method' in their names. "
- "-k 'not test_method and not test_other' will eliminate the matches. "
+ "-k 'not test_method and not test_other' will eliminate the matches. "
"Additionally keywords are matched to classes and functions "
"containing extra names in their 'extra_keyword_matches' set, "
"as well as functions which have names assigned directly to them.",
@@ -101,9 +101,9 @@ pytest_cmdline_main.tryfirst = True
def deselect_by_keyword(items, config):
keywordexpr = config.option.keyword.lstrip()
- if not keywordexpr:
- return
-
+ if not keywordexpr:
+ return
+
if keywordexpr.startswith("-"):
keywordexpr = "not " + keywordexpr[1:]
selectuntil = False
@@ -151,7 +151,7 @@ def pytest_collection_modifyitems(items, config):
def pytest_configure(config):
config._old_mark_config = MARK_GEN._config
- MARK_GEN._config = config
+ MARK_GEN._config = config
empty_parameterset = config.getini(EMPTY_PARAMETERSET_OPTION)
diff --git a/contrib/python/pytest/py2/_pytest/mark/evaluate.py b/contrib/python/pytest/py2/_pytest/mark/evaluate.py
index 506546e253..a20ff94cd5 100644
--- a/contrib/python/pytest/py2/_pytest/mark/evaluate.py
+++ b/contrib/python/pytest/py2/_pytest/mark/evaluate.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
import os
import platform
import sys
diff --git a/contrib/python/pytest/py2/_pytest/mark/legacy.py b/contrib/python/pytest/py2/_pytest/mark/legacy.py
index c56482f14d..7b865f5ff8 100644
--- a/contrib/python/pytest/py2/_pytest/mark/legacy.py
+++ b/contrib/python/pytest/py2/_pytest/mark/legacy.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""
this is a place where we put datastructures used by legacy apis
we hope ot remove
@@ -46,15 +46,15 @@ class KeywordMapping(object):
mapped_names.add(item.name)
# Add the names added as extra keywords to current or parent items
- mapped_names.update(item.listextrakeywords())
+ mapped_names.update(item.listextrakeywords())
# Add the names attached to the current function through direct assignment
if hasattr(item, "function"):
- mapped_names.update(item.function.__dict__)
-
- # add the markers to the keywords as we no longer handle them correctly
- mapped_names.update(mark.name for mark in item.iter_markers())
+ mapped_names.update(item.function.__dict__)
+ # add the markers to the keywords as we no longer handle them correctly
+ mapped_names.update(mark.name for mark in item.iter_markers())
+
return cls(mapped_names)
def __getitem__(self, subname):
diff --git a/contrib/python/pytest/py2/_pytest/mark/structures.py b/contrib/python/pytest/py2/_pytest/mark/structures.py
index aaebe927be..71adac02bc 100644
--- a/contrib/python/pytest/py2/_pytest/mark/structures.py
+++ b/contrib/python/pytest/py2/_pytest/mark/structures.py
@@ -1,20 +1,20 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
import inspect
import warnings
from collections import namedtuple
from operator import attrgetter
import attr
-import six
+import six
-from ..compat import ascii_escaped
-from ..compat import ATTRS_EQ_FIELD
+from ..compat import ascii_escaped
+from ..compat import ATTRS_EQ_FIELD
from ..compat import getfslineno
from ..compat import MappingMixin
from ..compat import NOTSET
-from _pytest.deprecated import PYTEST_PARAM_UNKNOWN_KWARGS
+from _pytest.deprecated import PYTEST_PARAM_UNKNOWN_KWARGS
from _pytest.outcomes import fail
-from _pytest.warning_types import PytestUnknownMarkWarning
+from _pytest.warning_types import PytestUnknownMarkWarning
EMPTY_PARAMETERSET_OPTION = "empty_parameter_set_mark"
@@ -48,7 +48,7 @@ def get_empty_parameterset_mark(config, argnames, func):
f_name = func.__name__
_, lineno = getfslineno(func)
raise Collector.CollectError(
- "Empty parameter set in '%s' at line %d" % (f_name, lineno + 1)
+ "Empty parameter set in '%s' at line %d" % (f_name, lineno + 1)
)
else:
raise LookupError(requested_mark)
@@ -64,90 +64,90 @@ def get_empty_parameterset_mark(config, argnames, func):
class ParameterSet(namedtuple("ParameterSet", "values, marks, id")):
@classmethod
- def param(cls, *values, **kwargs):
- marks = kwargs.pop("marks", ())
+ def param(cls, *values, **kwargs):
+ marks = kwargs.pop("marks", ())
if isinstance(marks, MarkDecorator):
marks = (marks,)
else:
assert isinstance(marks, (tuple, list, set))
- id_ = kwargs.pop("id", None)
- if id_ is not None:
- if not isinstance(id_, six.string_types):
- raise TypeError(
- "Expected id to be a string, got {}: {!r}".format(type(id_), id_)
- )
- id_ = ascii_escaped(id_)
-
- if kwargs:
- warnings.warn(
- PYTEST_PARAM_UNKNOWN_KWARGS.format(args=sorted(kwargs)), stacklevel=3
- )
+ id_ = kwargs.pop("id", None)
+ if id_ is not None:
+ if not isinstance(id_, six.string_types):
+ raise TypeError(
+ "Expected id to be a string, got {}: {!r}".format(type(id_), id_)
+ )
+ id_ = ascii_escaped(id_)
+
+ if kwargs:
+ warnings.warn(
+ PYTEST_PARAM_UNKNOWN_KWARGS.format(args=sorted(kwargs)), stacklevel=3
+ )
return cls(values, marks, id_)
@classmethod
- def extract_from(cls, parameterset, force_tuple=False):
+ def extract_from(cls, parameterset, force_tuple=False):
"""
:param parameterset:
a legacy style parameterset that may or may not be a tuple,
and may or may not be wrapped into a mess of mark objects
- :param force_tuple:
+ :param force_tuple:
enforce tuple wrapping so single argument tuple values
don't get decomposed and break tests
"""
if isinstance(parameterset, cls):
return parameterset
- if force_tuple:
+ if force_tuple:
return cls.param(parameterset)
- else:
- return cls(parameterset, marks=[], id=None)
+ else:
+ return cls(parameterset, marks=[], id=None)
- @staticmethod
- def _parse_parametrize_args(argnames, argvalues, *args, **kwargs):
+ @staticmethod
+ def _parse_parametrize_args(argnames, argvalues, *args, **kwargs):
if not isinstance(argnames, (tuple, list)):
argnames = [x.strip() for x in argnames.split(",") if x.strip()]
force_tuple = len(argnames) == 1
else:
force_tuple = False
- return argnames, force_tuple
-
- @staticmethod
- def _parse_parametrize_parameters(argvalues, force_tuple):
- return [
- ParameterSet.extract_from(x, force_tuple=force_tuple) for x in argvalues
+ return argnames, force_tuple
+
+ @staticmethod
+ def _parse_parametrize_parameters(argvalues, force_tuple):
+ return [
+ ParameterSet.extract_from(x, force_tuple=force_tuple) for x in argvalues
]
-
- @classmethod
- def _for_parametrize(cls, argnames, argvalues, func, config, function_definition):
- argnames, force_tuple = cls._parse_parametrize_args(argnames, argvalues)
- parameters = cls._parse_parametrize_parameters(argvalues, force_tuple)
+
+ @classmethod
+ def _for_parametrize(cls, argnames, argvalues, func, config, function_definition):
+ argnames, force_tuple = cls._parse_parametrize_args(argnames, argvalues)
+ parameters = cls._parse_parametrize_parameters(argvalues, force_tuple)
del argvalues
if parameters:
# check all parameter sets have the correct number of values
for param in parameters:
if len(param.values) != len(argnames):
- msg = (
- '{nodeid}: in "parametrize" the number of names ({names_len}):\n'
- " {names}\n"
- "must be equal to the number of values ({values_len}):\n"
- " {values}"
- )
- fail(
- msg.format(
- nodeid=function_definition.nodeid,
- values=param.values,
- names=argnames,
- names_len=len(argnames),
- values_len=len(param.values),
- ),
- pytrace=False,
+ msg = (
+ '{nodeid}: in "parametrize" the number of names ({names_len}):\n'
+ " {names}\n"
+ "must be equal to the number of values ({values_len}):\n"
+ " {values}"
)
+ fail(
+ msg.format(
+ nodeid=function_definition.nodeid,
+ values=param.values,
+ names=argnames,
+ names_len=len(argnames),
+ values_len=len(param.values),
+ ),
+ pytrace=False,
+ )
else:
# empty parameter set (likely computed at runtime): create a single
- # parameter set with NOTSET values, with the "empty parameter set" mark applied to it
+ # parameter set with NOTSET values, with the "empty parameter set" mark applied to it
mark = get_empty_parameterset_mark(config, argnames, func)
parameters.append(
ParameterSet(values=(NOTSET,) * len(argnames), marks=[mark], id=None)
@@ -160,9 +160,9 @@ class Mark(object):
#: name of the mark
name = attr.ib(type=str)
#: positional arguments of the mark decorator
- args = attr.ib() # List[object]
+ args = attr.ib() # List[object]
#: keyword arguments of the mark decorator
- kwargs = attr.ib() # Dict[str, object]
+ kwargs = attr.ib() # Dict[str, object]
def combined_with(self, other):
"""
@@ -170,7 +170,7 @@ class Mark(object):
:type other: Mark
:rtype: Mark
- combines by appending args and merging the mappings
+ combines by appending args and merging the mappings
"""
assert self.name == other.name
return Mark(
@@ -247,7 +247,7 @@ class MarkDecorator(object):
func = args[0]
is_class = inspect.isclass(func)
if len(args) == 1 and (istestfunc(func) or is_class):
- store_mark(func, self.mark)
+ store_mark(func, self.mark)
return func
return self.with_args(*args, **kwargs)
@@ -269,13 +269,13 @@ def normalize_mark_list(mark_list):
:type mark_list: List[Union[Mark, Markdecorator]]
:rtype: List[Mark]
"""
- extracted = [
- getattr(mark, "mark", mark) for mark in mark_list
- ] # unpack MarkDecorator
- for mark in extracted:
- if not isinstance(mark, Mark):
- raise TypeError("got {!r} instead of Mark".format(mark))
- return [x for x in extracted if isinstance(x, Mark)]
+ extracted = [
+ getattr(mark, "mark", mark) for mark in mark_list
+ ] # unpack MarkDecorator
+ for mark in extracted:
+ if not isinstance(mark, Mark):
+ raise TypeError("got {!r} instead of Mark".format(mark))
+ return [x for x in extracted if isinstance(x, Mark)]
def store_mark(obj, mark):
@@ -301,43 +301,43 @@ class MarkGenerator(object):
on the ``test_function`` object. """
_config = None
- _markers = set()
+ _markers = set()
def __getattr__(self, name):
if name[0] == "_":
raise AttributeError("Marker name must NOT start with underscore")
-
+
if self._config is not None:
- # We store a set of markers as a performance optimisation - if a mark
- # name is in the set we definitely know it, but a mark may be known and
- # not in the set. We therefore start by updating the set!
- if name not in self._markers:
- for line in self._config.getini("markers"):
- # example lines: "skipif(condition): skip the given test if..."
- # or "hypothesis: tests which use Hypothesis", so to get the
- # marker name we split on both `:` and `(`.
- if line == "ya:external":
- marker = line
- else:
- marker = line.split(":")[0].split("(")[0].strip()
- self._markers.add(marker)
-
- # If the name is not in the set of known marks after updating,
- # then it really is time to issue a warning or an error.
- if name not in self._markers:
- if self._config.option.strict_markers:
- fail(
- "{!r} not found in `markers` configuration option".format(name),
- pytrace=False,
- )
- else:
- warnings.warn(
- "Unknown pytest.mark.%s - is this a typo? You can register "
- "custom marks to avoid this warning - for details, see "
- "https://docs.pytest.org/en/latest/mark.html" % name,
- PytestUnknownMarkWarning,
- )
-
+ # We store a set of markers as a performance optimisation - if a mark
+ # name is in the set we definitely know it, but a mark may be known and
+ # not in the set. We therefore start by updating the set!
+ if name not in self._markers:
+ for line in self._config.getini("markers"):
+ # example lines: "skipif(condition): skip the given test if..."
+ # or "hypothesis: tests which use Hypothesis", so to get the
+ # marker name we split on both `:` and `(`.
+ if line == "ya:external":
+ marker = line
+ else:
+ marker = line.split(":")[0].split("(")[0].strip()
+ self._markers.add(marker)
+
+ # If the name is not in the set of known marks after updating,
+ # then it really is time to issue a warning or an error.
+ if name not in self._markers:
+ if self._config.option.strict_markers:
+ fail(
+ "{!r} not found in `markers` configuration option".format(name),
+ pytrace=False,
+ )
+ else:
+ warnings.warn(
+ "Unknown pytest.mark.%s - is this a typo? You can register "
+ "custom marks to avoid this warning - for details, see "
+ "https://docs.pytest.org/en/latest/mark.html" % name,
+ PytestUnknownMarkWarning,
+ )
+
return MarkDecorator(Mark(name, (), {}))
@@ -381,8 +381,8 @@ class NodeKeywords(MappingMixin):
return "<NodeKeywords for node %s>" % (self.node,)
-# mypy cannot find this overload, remove when on attrs>=19.2
-@attr.s(hash=False, **{ATTRS_EQ_FIELD: False}) # type: ignore
+# mypy cannot find this overload, remove when on attrs>=19.2
+@attr.s(hash=False, **{ATTRS_EQ_FIELD: False}) # type: ignore
class NodeMarkers(object):
"""
internal structure for storing marks belonging to a node
diff --git a/contrib/python/pytest/py2/_pytest/monkeypatch.py b/contrib/python/pytest/py2/_pytest/monkeypatch.py
index e8671b0c70..f3bbb62e31 100644
--- a/contrib/python/pytest/py2/_pytest/monkeypatch.py
+++ b/contrib/python/pytest/py2/_pytest/monkeypatch.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" monkeypatching and mocking functionality. """
from __future__ import absolute_import
from __future__ import division
@@ -182,8 +182,8 @@ class MonkeyPatch(object):
attribute is missing.
"""
__tracebackhide__ = True
- import inspect
-
+ import inspect
+
if name is notset:
if not isinstance(target, six.string_types):
raise TypeError(
@@ -197,11 +197,11 @@ class MonkeyPatch(object):
if raising:
raise AttributeError(name)
else:
- oldval = getattr(target, name, notset)
- # Avoid class descriptors like staticmethod/classmethod.
- if inspect.isclass(target):
- oldval = target.__dict__.get(name, notset)
- self._setattr.append((target, name, oldval))
+ oldval = getattr(target, name, notset)
+ # Avoid class descriptors like staticmethod/classmethod.
+ if inspect.isclass(target):
+ oldval = target.__dict__.get(name, notset)
+ self._setattr.append((target, name, oldval))
delattr(target, name)
def setitem(self, dic, name, value):
@@ -263,27 +263,27 @@ class MonkeyPatch(object):
def syspath_prepend(self, path):
""" Prepend ``path`` to ``sys.path`` list of import locations. """
- from pkg_resources import fixup_namespace_packages
-
+ from pkg_resources import fixup_namespace_packages
+
if self._savesyspath is None:
self._savesyspath = sys.path[:]
sys.path.insert(0, str(path))
- # https://github.com/pypa/setuptools/blob/d8b901bc/docs/pkg_resources.txt#L162-L171
- fixup_namespace_packages(str(path))
-
- # A call to syspathinsert() usually means that the caller wants to
- # import some dynamically created files, thus with python3 we
- # invalidate its import caches.
- # This is especially important when any namespace package is in used,
- # since then the mtime based FileFinder cache (that gets created in
- # this case already) gets not invalidated when writing the new files
- # quickly afterwards.
- if sys.version_info >= (3, 3):
- from importlib import invalidate_caches
-
- invalidate_caches()
-
+ # https://github.com/pypa/setuptools/blob/d8b901bc/docs/pkg_resources.txt#L162-L171
+ fixup_namespace_packages(str(path))
+
+ # A call to syspathinsert() usually means that the caller wants to
+ # import some dynamically created files, thus with python3 we
+ # invalidate its import caches.
+ # This is especially important when any namespace package is in used,
+ # since then the mtime based FileFinder cache (that gets created in
+ # this case already) gets not invalidated when writing the new files
+ # quickly afterwards.
+ if sys.version_info >= (3, 3):
+ from importlib import invalidate_caches
+
+ invalidate_caches()
+
def chdir(self, path):
""" Change the current working directory to the specified path.
Path can be a string or a py.path.local object.
diff --git a/contrib/python/pytest/py2/_pytest/nodes.py b/contrib/python/pytest/py2/_pytest/nodes.py
index 206e9ae163..a68a2cc65d 100644
--- a/contrib/python/pytest/py2/_pytest/nodes.py
+++ b/contrib/python/pytest/py2/_pytest/nodes.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -103,18 +103,18 @@ class Node(object):
return self.session.gethookproxy(self.fspath)
def __repr__(self):
- return "<%s %s>" % (self.__class__.__name__, getattr(self, "name", None))
+ return "<%s %s>" % (self.__class__.__name__, getattr(self, "name", None))
- def warn(self, warning):
+ def warn(self, warning):
"""Issue a warning for this item.
- Warnings will be displayed after the test session, unless explicitly suppressed
+ Warnings will be displayed after the test session, unless explicitly suppressed
- :param Warning warning: the warning instance to issue. Must be a subclass of PytestWarning.
+ :param Warning warning: the warning instance to issue. Must be a subclass of PytestWarning.
- :raise ValueError: if ``warning`` instance is not a subclass of PytestWarning.
+ :raise ValueError: if ``warning`` instance is not a subclass of PytestWarning.
- Example usage:
+ Example usage:
.. code-block:: python
@@ -249,7 +249,7 @@ class Node(object):
if excinfo.errisinstance(fm.FixtureLookupError):
return excinfo.value.formatrepr()
tbfilter = True
- if self.config.getoption("fulltrace", False):
+ if self.config.getoption("fulltrace", False):
style = "long"
else:
tb = _pytest._code.Traceback([excinfo.traceback[-1]])
@@ -261,12 +261,12 @@ class Node(object):
style = "long"
# XXX should excinfo.getrepr record all data and toterminal() process it?
if style is None:
- if self.config.getoption("tbstyle", "auto") == "short":
+ if self.config.getoption("tbstyle", "auto") == "short":
style = "short"
else:
style = "long"
- if self.config.getoption("verbose", 0) > 1:
+ if self.config.getoption("verbose", 0) > 1:
truncate_locals = False
else:
truncate_locals = True
@@ -280,7 +280,7 @@ class Node(object):
return excinfo.getrepr(
funcargs=True,
abspath=abspath,
- showlocals=self.config.getoption("showlocals", False),
+ showlocals=self.config.getoption("showlocals", False),
style=style,
tbfilter=tbfilter,
truncate_locals=truncate_locals,
@@ -327,14 +327,14 @@ class Collector(Node):
exc = excinfo.value
return str(exc.args[0])
- # Respect explicit tbstyle option, but default to "short"
- # (None._repr_failure_py defaults to "long" without "fulltrace" option).
- tbstyle = self.config.getoption("tbstyle", "auto")
- if tbstyle == "auto":
- tbstyle = "short"
-
- return self._repr_failure_py(excinfo, style=tbstyle)
-
+ # Respect explicit tbstyle option, but default to "short"
+ # (None._repr_failure_py defaults to "long" without "fulltrace" option).
+ tbstyle = self.config.getoption("tbstyle", "auto")
+ if tbstyle == "auto":
+ tbstyle = "short"
+
+ return self._repr_failure_py(excinfo, style=tbstyle)
+
def _prunetraceback(self, excinfo):
if hasattr(self, "fspath"):
traceback = excinfo.traceback
diff --git a/contrib/python/pytest/py2/_pytest/nose.py b/contrib/python/pytest/py2/_pytest/nose.py
index fbab91da24..3dd41e44eb 100644
--- a/contrib/python/pytest/py2/_pytest/nose.py
+++ b/contrib/python/pytest/py2/_pytest/nose.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" run test suites written for nose. """
from __future__ import absolute_import
from __future__ import division
@@ -6,9 +6,9 @@ from __future__ import print_function
import sys
-import six
-
-import pytest
+import six
+
+import pytest
from _pytest import python
from _pytest import runner
from _pytest import unittest
@@ -27,9 +27,9 @@ def get_skip_exceptions():
def pytest_runtest_makereport(item, call):
if call.excinfo and call.excinfo.errisinstance(get_skip_exceptions()):
# let's substitute the excinfo with a pytest.skip one
- call2 = runner.CallInfo.from_call(
- lambda: pytest.skip(six.text_type(call.excinfo.value)), call.when
- )
+ call2 = runner.CallInfo.from_call(
+ lambda: pytest.skip(six.text_type(call.excinfo.value)), call.when
+ )
call.excinfo = call2.excinfo
diff --git a/contrib/python/pytest/py2/_pytest/outcomes.py b/contrib/python/pytest/py2/_pytest/outcomes.py
index 4620f957c7..2246ba1413 100644
--- a/contrib/python/pytest/py2/_pytest/outcomes.py
+++ b/contrib/python/pytest/py2/_pytest/outcomes.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""
exception classes and constants handling test outcomes
as well as functions creating them
@@ -9,9 +9,9 @@ from __future__ import print_function
import sys
-from packaging.version import Version
-
+from packaging.version import Version
+
class OutcomeException(BaseException):
""" OutcomeException and its subclass instances indicate and
contain info about test and collection outcomes.
@@ -52,13 +52,13 @@ class Failed(OutcomeException):
__module__ = "builtins"
-class Exit(Exception):
+class Exit(Exception):
""" raised for immediate program exits (no tracebacks/summaries)"""
def __init__(self, msg="unknown reason", returncode=None):
self.msg = msg
self.returncode = returncode
- super(Exit, self).__init__(msg)
+ super(Exit, self).__init__(msg)
# exposed helper methods
@@ -66,7 +66,7 @@ class Exit(Exception):
def exit(msg, returncode=None):
"""
- Exit testing process.
+ Exit testing process.
:param str msg: message to display upon exit.
:param int returncode: return code to be used when exiting pytest.
@@ -83,8 +83,8 @@ def skip(msg="", **kwargs):
Skip an executing test with the given message.
This function should be called only during testing (setup, call or teardown) or
- during collection by using the ``allow_module_level`` flag. This function can
- be called in doctests as well.
+ during collection by using the ``allow_module_level`` flag. This function can
+ be called in doctests as well.
:kwarg bool allow_module_level: allows this function to be called at
module level, skipping the rest of the module. Default to False.
@@ -93,14 +93,14 @@ def skip(msg="", **kwargs):
It is better to use the :ref:`pytest.mark.skipif ref` marker when possible to declare a test to be
skipped under certain conditions like mismatching platforms or
dependencies.
- Similarly, use the ``# doctest: +SKIP`` directive (see `doctest.SKIP
- <https://docs.python.org/3/library/doctest.html#doctest.SKIP>`_)
- to skip a doctest statically.
+ Similarly, use the ``# doctest: +SKIP`` directive (see `doctest.SKIP
+ <https://docs.python.org/3/library/doctest.html#doctest.SKIP>`_)
+ to skip a doctest statically.
"""
__tracebackhide__ = True
allow_module_level = kwargs.pop("allow_module_level", False)
if kwargs:
- raise TypeError("unexpected keyword arguments: {}".format(sorted(kwargs)))
+ raise TypeError("unexpected keyword arguments: {}".format(sorted(kwargs)))
raise Skipped(msg=msg, allow_module_level=allow_module_level)
@@ -143,21 +143,21 @@ def xfail(reason=""):
xfail.Exception = XFailed
-def importorskip(modname, minversion=None, reason=None):
- """Imports and returns the requested module ``modname``, or skip the current test
- if the module cannot be imported.
-
- :param str modname: the name of the module to import
- :param str minversion: if given, the imported module ``__version__`` attribute must be
- at least this minimal version, otherwise the test is still skipped.
- :param str reason: if given, this reason is shown as the message when the module
- cannot be imported.
+def importorskip(modname, minversion=None, reason=None):
+ """Imports and returns the requested module ``modname``, or skip the current test
+ if the module cannot be imported.
+
+ :param str modname: the name of the module to import
+ :param str minversion: if given, the imported module ``__version__`` attribute must be
+ at least this minimal version, otherwise the test is still skipped.
+ :param str reason: if given, this reason is shown as the message when the module
+ cannot be imported.
"""
import warnings
__tracebackhide__ = True
compile(modname, "", "eval") # to catch syntaxerrors
- import_exc = None
+ import_exc = None
with warnings.catch_warnings():
# make sure to ignore ImportWarnings that might happen because
@@ -166,19 +166,19 @@ def importorskip(modname, minversion=None, reason=None):
warnings.simplefilter("ignore")
try:
__import__(modname)
- except ImportError as exc:
+ except ImportError as exc:
# Do not raise chained exception here(#1485)
- import_exc = exc
- if import_exc:
- if reason is None:
- reason = "could not import %r: %s" % (modname, import_exc)
- raise Skipped(reason, allow_module_level=True)
+ import_exc = exc
+ if import_exc:
+ if reason is None:
+ reason = "could not import %r: %s" % (modname, import_exc)
+ raise Skipped(reason, allow_module_level=True)
mod = sys.modules[modname]
if minversion is None:
return mod
verattr = getattr(mod, "__version__", None)
if minversion is not None:
- if verattr is None or Version(verattr) < Version(minversion):
+ if verattr is None or Version(verattr) < Version(minversion):
raise Skipped(
"module %r has __version__ %r, required is: %r"
% (modname, verattr, minversion),
diff --git a/contrib/python/pytest/py2/_pytest/pastebin.py b/contrib/python/pytest/py2/_pytest/pastebin.py
index 7a3e80231c..85ff3f8d29 100644
--- a/contrib/python/pytest/py2/_pytest/pastebin.py
+++ b/contrib/python/pytest/py2/_pytest/pastebin.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" submit failure or test session information to a pastebin service. """
from __future__ import absolute_import
from __future__ import division
@@ -77,7 +77,7 @@ def create_new_paste(contents):
from urllib.request import urlopen
from urllib.parse import urlencode
- params = {"code": contents, "lexer": "text", "expiry": "1week"}
+ params = {"code": contents, "lexer": "text", "expiry": "1week"}
url = "https://bpaste.net"
response = urlopen(url, data=urlencode(params).encode("ascii")).read()
m = re.search(r'href="/raw/(\w+)"', response.decode("utf-8"))
diff --git a/contrib/python/pytest/py2/_pytest/pathlib.py b/contrib/python/pytest/py2/_pytest/pathlib.py
index 42071f4310..2e5bc362b9 100644
--- a/contrib/python/pytest/py2/_pytest/pathlib.py
+++ b/contrib/python/pytest/py2/_pytest/pathlib.py
@@ -1,6 +1,6 @@
-# -*- coding: utf-8 -*-
-from __future__ import absolute_import
-
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import
+
import atexit
import errno
import fnmatch
@@ -10,8 +10,8 @@ import os
import shutil
import sys
import uuid
-import warnings
-from functools import partial
+import warnings
+from functools import partial
from functools import reduce
from os.path import expanduser
from os.path import expandvars
@@ -23,7 +23,7 @@ import six
from six.moves import map
from .compat import PY36
-from _pytest.warning_types import PytestWarning
+from _pytest.warning_types import PytestWarning
if PY36:
from pathlib import Path, PurePath
@@ -43,74 +43,74 @@ def ensure_reset_dir(path):
ensures the given path is an empty directory
"""
if path.exists():
- rm_rf(path)
+ rm_rf(path)
path.mkdir()
-def on_rm_rf_error(func, path, exc, **kwargs):
- """Handles known read-only errors during rmtree.
-
- The returned value is used only by our own tests.
- """
- start_path = kwargs["start_path"]
- exctype, excvalue = exc[:2]
-
- # another process removed the file in the middle of the "rm_rf" (xdist for example)
- # more context: https://github.com/pytest-dev/pytest/issues/5974#issuecomment-543799018
- if isinstance(excvalue, OSError) and excvalue.errno == errno.ENOENT:
- return False
-
- if not isinstance(excvalue, OSError) or excvalue.errno not in (
- errno.EACCES,
- errno.EPERM,
- ):
- warnings.warn(
- PytestWarning(
- "(rm_rf) error removing {}\n{}: {}".format(path, exctype, excvalue)
- )
- )
- return False
-
- if func not in (os.rmdir, os.remove, os.unlink):
- warnings.warn(
- PytestWarning(
- "(rm_rf) unknown function {} when removing {}:\n{}: {}".format(
- path, func, exctype, excvalue
- )
- )
- )
- return False
-
- # Chmod + retry.
- import stat
-
- def chmod_rw(p):
- mode = os.stat(p).st_mode
- os.chmod(p, mode | stat.S_IRUSR | stat.S_IWUSR)
-
- # For files, we need to recursively go upwards in the directories to
- # ensure they all are also writable.
- p = Path(path)
- if p.is_file():
- for parent in p.parents:
- chmod_rw(str(parent))
- # stop when we reach the original path passed to rm_rf
- if parent == start_path:
- break
- chmod_rw(str(path))
-
- func(path)
- return True
-
-
-def rm_rf(path):
- """Remove the path contents recursively, even if some elements
- are read-only.
- """
- onerror = partial(on_rm_rf_error, start_path=path)
- shutil.rmtree(str(path), onerror=onerror)
-
-
+def on_rm_rf_error(func, path, exc, **kwargs):
+ """Handles known read-only errors during rmtree.
+
+ The returned value is used only by our own tests.
+ """
+ start_path = kwargs["start_path"]
+ exctype, excvalue = exc[:2]
+
+ # another process removed the file in the middle of the "rm_rf" (xdist for example)
+ # more context: https://github.com/pytest-dev/pytest/issues/5974#issuecomment-543799018
+ if isinstance(excvalue, OSError) and excvalue.errno == errno.ENOENT:
+ return False
+
+ if not isinstance(excvalue, OSError) or excvalue.errno not in (
+ errno.EACCES,
+ errno.EPERM,
+ ):
+ warnings.warn(
+ PytestWarning(
+ "(rm_rf) error removing {}\n{}: {}".format(path, exctype, excvalue)
+ )
+ )
+ return False
+
+ if func not in (os.rmdir, os.remove, os.unlink):
+ warnings.warn(
+ PytestWarning(
+ "(rm_rf) unknown function {} when removing {}:\n{}: {}".format(
+ path, func, exctype, excvalue
+ )
+ )
+ )
+ return False
+
+ # Chmod + retry.
+ import stat
+
+ def chmod_rw(p):
+ mode = os.stat(p).st_mode
+ os.chmod(p, mode | stat.S_IRUSR | stat.S_IWUSR)
+
+ # For files, we need to recursively go upwards in the directories to
+ # ensure they all are also writable.
+ p = Path(path)
+ if p.is_file():
+ for parent in p.parents:
+ chmod_rw(str(parent))
+ # stop when we reach the original path passed to rm_rf
+ if parent == start_path:
+ break
+ chmod_rw(str(path))
+
+ func(path)
+ return True
+
+
+def rm_rf(path):
+ """Remove the path contents recursively, even if some elements
+ are read-only.
+ """
+ onerror = partial(on_rm_rf_error, start_path=path)
+ shutil.rmtree(str(path), onerror=onerror)
+
+
def find_prefixed(root, prefix):
"""finds all elements in root that begin with the prefix, case insensitive"""
l_prefix = prefix.lower()
@@ -246,7 +246,7 @@ def maybe_delete_a_numbered_dir(path):
garbage = parent.joinpath("garbage-{}".format(uuid.uuid4()))
path.rename(garbage)
- rm_rf(garbage)
+ rm_rf(garbage)
except (OSError, EnvironmentError):
# known races:
# * other process did a cleanup at the same time
diff --git a/contrib/python/pytest/py2/_pytest/pytester.py b/contrib/python/pytest/py2/_pytest/pytester.py
index f1d739c991..c2101e68d3 100644
--- a/contrib/python/pytest/py2/_pytest/pytester.py
+++ b/contrib/python/pytest/py2/_pytest/pytester.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""(disabled by default) support for testing pytest and pytest plugins."""
from __future__ import absolute_import
from __future__ import division
@@ -21,16 +21,16 @@ import six
import pytest
from _pytest._code import Source
-from _pytest._io.saferepr import saferepr
+from _pytest._io.saferepr import saferepr
from _pytest.assertion.rewrite import AssertionRewritingHook
from _pytest.capture import MultiCapture
from _pytest.capture import SysCapture
from _pytest.compat import safe_str
-from _pytest.compat import Sequence
+from _pytest.compat import Sequence
from _pytest.main import EXIT_INTERRUPTED
from _pytest.main import EXIT_OK
from _pytest.main import Session
-from _pytest.monkeypatch import MonkeyPatch
+from _pytest.monkeypatch import MonkeyPatch
from _pytest.pathlib import Path
IGNORE_PAM = [ # filenames added when obtaining details about the current user
@@ -69,19 +69,19 @@ def pytest_configure(config):
if checker.matching_platform():
config.pluginmanager.register(checker)
- config.addinivalue_line(
- "markers",
- "pytester_example_path(*path_segments): join the given path "
- "segments to `pytester_example_dir` for this test.",
- )
-
+ config.addinivalue_line(
+ "markers",
+ "pytester_example_path(*path_segments): join the given path "
+ "segments to `pytester_example_dir` for this test.",
+ )
+
def raise_on_kwargs(kwargs):
- __tracebackhide__ = True
- if kwargs: # pragma: no branch
- raise TypeError(
- "Unexpected keyword arguments: {}".format(", ".join(sorted(kwargs)))
- )
+ __tracebackhide__ = True
+ if kwargs: # pragma: no branch
+ raise TypeError(
+ "Unexpected keyword arguments: {}".format(", ".join(sorted(kwargs)))
+ )
class LsofFdLeakChecker(object):
@@ -92,11 +92,11 @@ class LsofFdLeakChecker(object):
def _exec_lsof(self):
pid = os.getpid()
- # py3: use subprocess.DEVNULL directly.
- with open(os.devnull, "wb") as devnull:
- return subprocess.check_output(
- ("lsof", "-Ffn0", "-p", str(pid)), stderr=devnull
- ).decode()
+ # py3: use subprocess.DEVNULL directly.
+ with open(os.devnull, "wb") as devnull:
+ return subprocess.check_output(
+ ("lsof", "-Ffn0", "-p", str(pid)), stderr=devnull
+ ).decode()
def _parse_lsof_output(self, out):
def isopen(line):
@@ -123,8 +123,8 @@ class LsofFdLeakChecker(object):
def matching_platform(self):
try:
- subprocess.check_output(("lsof", "-v"))
- except (OSError, subprocess.CalledProcessError):
+ subprocess.check_output(("lsof", "-v"))
+ except (OSError, subprocess.CalledProcessError):
return False
else:
return True
@@ -270,11 +270,11 @@ class HookRecorder(object):
"""return a testreport whose dotted import path matches"""
values = []
for rep in self.getreports(names=names):
- if not when and rep.when != "call" and rep.passed:
- # setup/teardown passing reports - let's ignore those
- continue
- if when and rep.when != when:
+ if not when and rep.when != "call" and rep.passed:
+ # setup/teardown passing reports - let's ignore those
continue
+ if when and rep.when != when:
+ continue
if not inamepart or inamepart in rep.nodeid.split("::"):
values.append(rep)
if not values:
@@ -300,12 +300,12 @@ class HookRecorder(object):
failed = []
for rep in self.getreports("pytest_collectreport pytest_runtest_logreport"):
if rep.passed:
- if rep.when == "call":
+ if rep.when == "call":
passed.append(rep)
elif rep.skipped:
skipped.append(rep)
- else:
- assert rep.failed, "Unexpected outcome: {!r}".format(rep)
+ else:
+ assert rep.failed, "Unexpected outcome: {!r}".format(rep)
failed.append(rep)
return passed, skipped, failed
@@ -337,24 +337,24 @@ def testdir(request, tmpdir_factory):
return Testdir(request, tmpdir_factory)
-@pytest.fixture
-def _sys_snapshot():
- snappaths = SysPathsSnapshot()
- snapmods = SysModulesSnapshot()
- yield
- snapmods.restore()
- snappaths.restore()
-
-
-@pytest.fixture
-def _config_for_test():
- from _pytest.config import get_config
-
- config = get_config()
- yield config
- config._ensure_unconfigure() # cleanup, e.g. capman closing tmpfiles.
-
-
+@pytest.fixture
+def _sys_snapshot():
+ snappaths = SysPathsSnapshot()
+ snapmods = SysModulesSnapshot()
+ yield
+ snapmods.restore()
+ snappaths.restore()
+
+
+@pytest.fixture
+def _config_for_test():
+ from _pytest.config import get_config
+
+ config = get_config()
+ yield config
+ config._ensure_unconfigure() # cleanup, e.g. capman closing tmpfiles.
+
+
rex_outcome = re.compile(r"(\d+) ([\w-]+)")
@@ -382,12 +382,12 @@ class RunResult(object):
self.stderr = LineMatcher(errlines)
self.duration = duration
- def __repr__(self):
- return (
- "<RunResult ret=%r len(stdout.lines)=%d len(stderr.lines)=%d duration=%.2fs>"
- % (self.ret, len(self.stdout.lines), len(self.stderr.lines), self.duration)
- )
-
+ def __repr__(self):
+ return (
+ "<RunResult ret=%r len(stdout.lines)=%d len(stderr.lines)=%d duration=%.2fs>"
+ % (self.ret, len(self.stdout.lines), len(self.stderr.lines), self.duration)
+ )
+
def parseoutcomes(self):
"""Return a dictionary of outcomestring->num from parsing the terminal
output that the test process produced.
@@ -478,8 +478,8 @@ class Testdir(object):
"""
- CLOSE_STDIN = object
-
+ CLOSE_STDIN = object
+
class TimeoutExpired(Exception):
pass
@@ -501,17 +501,17 @@ class Testdir(object):
elif method == "subprocess":
self._runpytest_method = self.runpytest_subprocess
- mp = self.monkeypatch = MonkeyPatch()
- mp.setenv("PYTEST_DEBUG_TEMPROOT", str(self.test_tmproot))
- # Ensure no unexpected caching via tox.
- mp.delenv("TOX_ENV_DIR", raising=False)
- # Discard outer pytest options.
- mp.delenv("PYTEST_ADDOPTS", raising=False)
-
- # Environment (updates) for inner runs.
- tmphome = str(self.tmpdir)
- self._env_run_update = {"HOME": tmphome, "USERPROFILE": tmphome}
-
+ mp = self.monkeypatch = MonkeyPatch()
+ mp.setenv("PYTEST_DEBUG_TEMPROOT", str(self.test_tmproot))
+ # Ensure no unexpected caching via tox.
+ mp.delenv("TOX_ENV_DIR", raising=False)
+ # Discard outer pytest options.
+ mp.delenv("PYTEST_ADDOPTS", raising=False)
+
+ # Environment (updates) for inner runs.
+ tmphome = str(self.tmpdir)
+ self._env_run_update = {"HOME": tmphome, "USERPROFILE": tmphome}
+
def __repr__(self):
return "<Testdir %r>" % (self.tmpdir,)
@@ -529,7 +529,7 @@ class Testdir(object):
self._sys_modules_snapshot.restore()
self._sys_path_snapshot.restore()
self._cwd_snapshot.restore()
- self.monkeypatch.undo()
+ self.monkeypatch.undo()
def __take_sys_modules_snapshot(self):
# some zope modules used by twisted-related tests keep internal state
@@ -627,7 +627,7 @@ class Testdir(object):
if path is None:
path = self.tmpdir
- self.monkeypatch.syspath_prepend(str(path))
+ self.monkeypatch.syspath_prepend(str(path))
def mkdir(self, name):
"""Create a new (sub)directory."""
@@ -670,7 +670,7 @@ class Testdir(object):
else:
raise LookupError(
"{} cant be found as module or package in {}".format(
- func_name, example_dir.bestrelpath(self.request.config.rootdir)
+ func_name, example_dir.bestrelpath(self.request.config.rootdir)
)
)
else:
@@ -795,23 +795,23 @@ class Testdir(object):
:param args: command line arguments to pass to :py:func:`pytest.main`
- :param plugins: (keyword-only) extra plugin instances the
+ :param plugins: (keyword-only) extra plugin instances the
``pytest.main()`` instance should use
:return: a :py:class:`HookRecorder` instance
- """
- plugins = kwargs.pop("plugins", [])
- no_reraise_ctrlc = kwargs.pop("no_reraise_ctrlc", None)
- raise_on_kwargs(kwargs)
+ """
+ plugins = kwargs.pop("plugins", [])
+ no_reraise_ctrlc = kwargs.pop("no_reraise_ctrlc", None)
+ raise_on_kwargs(kwargs)
finalizers = []
try:
- # Do not load user config (during runs only).
- mp_run = MonkeyPatch()
- for k, v in self._env_run_update.items():
- mp_run.setenv(k, v)
- finalizers.append(mp_run.undo)
-
+ # Do not load user config (during runs only).
+ mp_run = MonkeyPatch()
+ for k, v in self._env_run_update.items():
+ mp_run.setenv(k, v)
+ finalizers.append(mp_run.undo)
+
# When running pytest inline any plugins active in the main test
# process are already imported. So this disables the warning which
# will trigger to say they can no longer be rewritten, which is
@@ -856,7 +856,7 @@ class Testdir(object):
# typically we reraise keyboard interrupts from the child run
# because it's our user requesting interruption of the testing
- if ret == EXIT_INTERRUPTED and not no_reraise_ctrlc:
+ if ret == EXIT_INTERRUPTED and not no_reraise_ctrlc:
calls = reprec.getcalls("pytest_keyboard_interrupt")
if calls and calls[-1].excinfo.type == KeyboardInterrupt:
raise KeyboardInterrupt()
@@ -868,10 +868,10 @@ class Testdir(object):
def runpytest_inprocess(self, *args, **kwargs):
"""Return result of running pytest in-process, providing a similar
interface to what self.runpytest() provides.
- """
- syspathinsert = kwargs.pop("syspathinsert", False)
+ """
+ syspathinsert = kwargs.pop("syspathinsert", False)
- if syspathinsert:
+ if syspathinsert:
self.syspathinsert()
now = time.time()
capture = MultiCapture(Capture=SysCapture)
@@ -1029,14 +1029,14 @@ class Testdir(object):
if colitem.name == name:
return colitem
- def popen(
- self,
- cmdargs,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- stdin=CLOSE_STDIN,
- **kw
- ):
+ def popen(
+ self,
+ cmdargs,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ stdin=CLOSE_STDIN,
+ **kw
+ ):
"""Invoke subprocess.Popen.
This calls subprocess.Popen making sure the current working directory
@@ -1049,22 +1049,22 @@ class Testdir(object):
env["PYTHONPATH"] = os.pathsep.join(
filter(None, [os.getcwd(), env.get("PYTHONPATH", "")])
)
- env.update(self._env_run_update)
+ env.update(self._env_run_update)
kw["env"] = env
- if stdin is Testdir.CLOSE_STDIN:
- kw["stdin"] = subprocess.PIPE
- elif isinstance(stdin, bytes):
- kw["stdin"] = subprocess.PIPE
- else:
- kw["stdin"] = stdin
-
- popen = subprocess.Popen(cmdargs, stdout=stdout, stderr=stderr, **kw)
- if stdin is Testdir.CLOSE_STDIN:
- popen.stdin.close()
- elif isinstance(stdin, bytes):
- popen.stdin.write(stdin)
-
+ if stdin is Testdir.CLOSE_STDIN:
+ kw["stdin"] = subprocess.PIPE
+ elif isinstance(stdin, bytes):
+ kw["stdin"] = subprocess.PIPE
+ else:
+ kw["stdin"] = stdin
+
+ popen = subprocess.Popen(cmdargs, stdout=stdout, stderr=stderr, **kw)
+ if stdin is Testdir.CLOSE_STDIN:
+ popen.stdin.close()
+ elif isinstance(stdin, bytes):
+ popen.stdin.write(stdin)
+
return popen
def run(self, *cmdargs, **kwargs):
@@ -1075,10 +1075,10 @@ class Testdir(object):
:param args: the sequence of arguments to pass to `subprocess.Popen()`
:param timeout: the period in seconds after which to timeout and raise
:py:class:`Testdir.TimeoutExpired`
- :param stdin: optional standard input. Bytes are being send, closing
- the pipe, otherwise it is passed through to ``popen``.
- Defaults to ``CLOSE_STDIN``, which translates to using a pipe
- (``subprocess.PIPE``) that gets closed.
+ :param stdin: optional standard input. Bytes are being send, closing
+ the pipe, otherwise it is passed through to ``popen``.
+ Defaults to ``CLOSE_STDIN``, which translates to using a pipe
+ (``subprocess.PIPE``) that gets closed.
Returns a :py:class:`RunResult`.
@@ -1086,7 +1086,7 @@ class Testdir(object):
__tracebackhide__ = True
timeout = kwargs.pop("timeout", None)
- stdin = kwargs.pop("stdin", Testdir.CLOSE_STDIN)
+ stdin = kwargs.pop("stdin", Testdir.CLOSE_STDIN)
raise_on_kwargs(kwargs)
cmdargs = [
@@ -1101,14 +1101,14 @@ class Testdir(object):
try:
now = time.time()
popen = self.popen(
- cmdargs,
- stdin=stdin,
- stdout=f1,
- stderr=f2,
- close_fds=(sys.platform != "win32"),
+ cmdargs,
+ stdin=stdin,
+ stdout=f1,
+ stderr=f2,
+ close_fds=(sys.platform != "win32"),
)
- if isinstance(stdin, bytes):
- popen.stdin.close()
+ if isinstance(stdin, bytes):
+ popen.stdin.close()
def handle_timeout():
__tracebackhide__ = True
@@ -1124,7 +1124,7 @@ class Testdir(object):
if timeout is None:
ret = popen.wait()
- elif not six.PY2:
+ elif not six.PY2:
try:
ret = popen.wait(timeout)
except subprocess.TimeoutExpired:
@@ -1196,8 +1196,8 @@ class Testdir(object):
Returns a :py:class:`RunResult`.
"""
__tracebackhide__ = True
- timeout = kwargs.pop("timeout", None)
- raise_on_kwargs(kwargs)
+ timeout = kwargs.pop("timeout", None)
+ raise_on_kwargs(kwargs)
p = py.path.local.make_numbered_dir(
prefix="runpytest-", keep=None, rootdir=self.tmpdir
@@ -1207,7 +1207,7 @@ class Testdir(object):
if plugins:
args = ("-p", plugins[0]) + args
args = self._getpytestargs() + args
- return self.run(*args, timeout=timeout)
+ return self.run(*args, timeout=timeout)
def spawn_pytest(self, string, expect_timeout=10.0):
"""Run pytest using pexpect.
@@ -1235,12 +1235,12 @@ class Testdir(object):
if sys.platform.startswith("freebsd"):
pytest.xfail("pexpect does not work reliably on freebsd")
logfile = self.tmpdir.join("spawn.out").open("wb")
-
- # Do not load user config.
- env = os.environ.copy()
- env.update(self._env_run_update)
-
- child = pexpect.spawn(cmd, logfile=logfile, env=env)
+
+ # Do not load user config.
+ env = os.environ.copy()
+ env.update(self._env_run_update)
+
+ child = pexpect.spawn(cmd, logfile=logfile, env=env)
self.request.addfinalizer(logfile.close)
child.timeout = expect_timeout
return child
@@ -1250,7 +1250,7 @@ def getdecoded(out):
try:
return out.decode("utf-8")
except UnicodeDecodeError:
- return "INTERNAL not-utf8-decodeable, truncated string:\n%s" % (saferepr(out),)
+ return "INTERNAL not-utf8-decodeable, truncated string:\n%s" % (saferepr(out),)
class LineComp(object):
@@ -1344,7 +1344,7 @@ class LineMatcher(object):
raise ValueError("line %r not found in output" % fnline)
def _log(self, *args):
- self._log_output.append(" ".join(str(x) for x in args))
+ self._log_output.append(" ".join(str(x) for x in args))
@property
def _log_text(self):
@@ -1385,7 +1385,7 @@ class LineMatcher(object):
will be logged to stdout when a match occurs
"""
- assert isinstance(lines2, Sequence)
+ assert isinstance(lines2, Sequence)
lines2 = self._getlines(lines2)
lines1 = self.lines[:]
nextline = None
diff --git a/contrib/python/pytest/py2/_pytest/python.py b/contrib/python/pytest/py2/_pytest/python.py
index f7c368b0c4..244c22e191 100644
--- a/contrib/python/pytest/py2/_pytest/python.py
+++ b/contrib/python/pytest/py2/_pytest/python.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" Python test discovery, setup and run of test functions. """
from __future__ import absolute_import
from __future__ import division
@@ -10,7 +10,7 @@ import inspect
import os
import sys
import warnings
-from functools import partial
+from functools import partial
from textwrap import dedent
import py
@@ -39,14 +39,14 @@ from _pytest.compat import safe_str
from _pytest.compat import STRING_TYPES
from _pytest.config import hookimpl
from _pytest.main import FSHookProxy
-from _pytest.mark import MARK_GEN
+from _pytest.mark import MARK_GEN
from _pytest.mark.structures import get_unpacked_marks
from _pytest.mark.structures import normalize_mark_list
from _pytest.outcomes import fail
-from _pytest.outcomes import skip
+from _pytest.outcomes import skip
from _pytest.pathlib import parts
-from _pytest.warning_types import PytestCollectionWarning
-from _pytest.warning_types import PytestUnhandledCoroutineWarning
+from _pytest.warning_types import PytestCollectionWarning
+from _pytest.warning_types import PytestUnhandledCoroutineWarning
def pyobj_property(name):
@@ -82,7 +82,7 @@ def pytest_addoption(parser):
parser.addini(
"python_files",
type="args",
- # NOTE: default is also used in AssertionRewritingHook.
+ # NOTE: default is also used in AssertionRewritingHook.
default=["test_*.py", "*_test.py"],
help="glob-style file patterns for Python test module discovery",
)
@@ -98,13 +98,13 @@ def pytest_addoption(parser):
default=["test"],
help="prefixes or glob names for Python test function and method discovery",
)
- parser.addini(
- "disable_test_id_escaping_and_forfeit_all_rights_to_community_support",
- type="bool",
- default=False,
- help="disable string escape non-ascii characters, might cause unwanted "
- "side effects(use at your own risk)",
- )
+ parser.addini(
+ "disable_test_id_escaping_and_forfeit_all_rights_to_community_support",
+ type="bool",
+ default=False,
+ help="disable string escape non-ascii characters, might cause unwanted "
+ "side effects(use at your own risk)",
+ )
group.addoption(
"--import-mode",
@@ -129,10 +129,10 @@ def pytest_generate_tests(metafunc):
# those alternative spellings are common - raise a specific error to alert
# the user
alt_spellings = ["parameterize", "parametrise", "parameterise"]
- for mark_name in alt_spellings:
- if metafunc.definition.get_closest_marker(mark_name):
+ for mark_name in alt_spellings:
+ if metafunc.definition.get_closest_marker(mark_name):
msg = "{0} has '{1}' mark, spelling should be 'parametrize'"
- fail(msg.format(metafunc.function.__name__, mark_name), pytrace=False)
+ fail(msg.format(metafunc.function.__name__, mark_name), pytrace=False)
for marker in metafunc.definition.iter_markers(name="parametrize"):
metafunc.parametrize(*marker.args, **marker.kwargs)
@@ -160,18 +160,18 @@ def pytest_configure(config):
@hookimpl(trylast=True)
def pytest_pyfunc_call(pyfuncitem):
testfunction = pyfuncitem.obj
- iscoroutinefunction = getattr(inspect, "iscoroutinefunction", None)
- if iscoroutinefunction is not None and iscoroutinefunction(testfunction):
- msg = "Coroutine functions are not natively supported and have been skipped.\n"
- msg += "You need to install a suitable plugin for your async framework, for example:\n"
- msg += " - pytest-asyncio\n"
- msg += " - pytest-trio\n"
- msg += " - pytest-tornasync"
- warnings.warn(PytestUnhandledCoroutineWarning(msg.format(pyfuncitem.nodeid)))
- skip(msg="coroutine function and no async plugin installed (see warnings)")
- funcargs = pyfuncitem.funcargs
- testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames}
- testfunction(**testargs)
+ iscoroutinefunction = getattr(inspect, "iscoroutinefunction", None)
+ if iscoroutinefunction is not None and iscoroutinefunction(testfunction):
+ msg = "Coroutine functions are not natively supported and have been skipped.\n"
+ msg += "You need to install a suitable plugin for your async framework, for example:\n"
+ msg += " - pytest-asyncio\n"
+ msg += " - pytest-trio\n"
+ msg += " - pytest-tornasync"
+ warnings.warn(PytestUnhandledCoroutineWarning(msg.format(pyfuncitem.nodeid)))
+ skip(msg="coroutine function and no async plugin installed (see warnings)")
+ funcargs = pyfuncitem.funcargs
+ testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames}
+ testfunction(**testargs)
return True
@@ -217,7 +217,7 @@ def pytest_pycollect_makeitem(collector, name, obj):
if not (isfunction(obj) or isfunction(get_real_func(obj))):
filename, lineno = getfslineno(obj)
warnings.warn_explicit(
- message=PytestCollectionWarning(
+ message=PytestCollectionWarning(
"cannot collect %r because it is not a function." % name
),
category=None,
@@ -226,10 +226,10 @@ def pytest_pycollect_makeitem(collector, name, obj):
)
elif getattr(obj, "__test__", True):
if is_generator(obj):
- res = Function(name, parent=collector)
- reason = deprecated.YIELD_TESTS.format(name=name)
- res.add_marker(MARK_GEN.xfail(run=False, reason=reason))
- res.warn(PytestCollectionWarning(reason))
+ res = Function(name, parent=collector)
+ reason = deprecated.YIELD_TESTS.format(name=name)
+ res.add_marker(MARK_GEN.xfail(run=False, reason=reason))
+ res.warn(PytestCollectionWarning(reason))
else:
res = list(collector._genfunctions(name, obj))
outcome.force_result(res)
@@ -251,24 +251,24 @@ class PyobjMixin(PyobjContext):
def __init__(self, *k, **kw):
super(PyobjMixin, self).__init__(*k, **kw)
- @property
- def obj(self):
- """Underlying Python object."""
- obj = getattr(self, "_obj", None)
- if obj is None:
- self._obj = obj = self._getobj()
- # XXX evil hack
- # used to avoid Instance collector marker duplication
- if self._ALLOW_MARKERS:
- self.own_markers.extend(get_unpacked_marks(self.obj))
- return obj
-
- @obj.setter
- def obj(self, value):
- self._obj = value
+ @property
+ def obj(self):
+ """Underlying Python object."""
+ obj = getattr(self, "_obj", None)
+ if obj is None:
+ self._obj = obj = self._getobj()
+ # XXX evil hack
+ # used to avoid Instance collector marker duplication
+ if self._ALLOW_MARKERS:
+ self.own_markers.extend(get_unpacked_marks(self.obj))
+ return obj
+
+ @obj.setter
+ def obj(self, value):
+ self._obj = value
def _getobj(self):
- """Gets the underlying Python object. May be overwritten by subclasses."""
+ """Gets the underlying Python object. May be overwritten by subclasses."""
return getattr(self.parent.obj, self.name)
def getmodpath(self, stopatmodule=True, includemodule=False):
@@ -440,66 +440,66 @@ class Module(nodes.File, PyCollector):
return self._importtestmodule()
def collect(self):
- self._inject_setup_module_fixture()
- self._inject_setup_function_fixture()
+ self._inject_setup_module_fixture()
+ self._inject_setup_function_fixture()
self.session._fixturemanager.parsefactories(self)
return super(Module, self).collect()
- def _inject_setup_module_fixture(self):
- """Injects a hidden autouse, module scoped fixture into the collected module object
- that invokes setUpModule/tearDownModule if either or both are available.
-
- Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with
- other fixtures (#517).
- """
- setup_module = _get_non_fixture_func(self.obj, "setUpModule")
- if setup_module is None:
- setup_module = _get_non_fixture_func(self.obj, "setup_module")
-
- teardown_module = _get_non_fixture_func(self.obj, "tearDownModule")
- if teardown_module is None:
- teardown_module = _get_non_fixture_func(self.obj, "teardown_module")
-
- if setup_module is None and teardown_module is None:
- return
-
- @fixtures.fixture(autouse=True, scope="module")
- def xunit_setup_module_fixture(request):
- if setup_module is not None:
- _call_with_optional_argument(setup_module, request.module)
- yield
- if teardown_module is not None:
- _call_with_optional_argument(teardown_module, request.module)
-
- self.obj.__pytest_setup_module = xunit_setup_module_fixture
-
- def _inject_setup_function_fixture(self):
- """Injects a hidden autouse, function scoped fixture into the collected module object
- that invokes setup_function/teardown_function if either or both are available.
-
- Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with
- other fixtures (#517).
- """
- setup_function = _get_non_fixture_func(self.obj, "setup_function")
- teardown_function = _get_non_fixture_func(self.obj, "teardown_function")
- if setup_function is None and teardown_function is None:
- return
-
- @fixtures.fixture(autouse=True, scope="function")
- def xunit_setup_function_fixture(request):
- if request.instance is not None:
- # in this case we are bound to an instance, so we need to let
- # setup_method handle this
- yield
- return
- if setup_function is not None:
- _call_with_optional_argument(setup_function, request.function)
- yield
- if teardown_function is not None:
- _call_with_optional_argument(teardown_function, request.function)
-
- self.obj.__pytest_setup_function = xunit_setup_function_fixture
-
+ def _inject_setup_module_fixture(self):
+ """Injects a hidden autouse, module scoped fixture into the collected module object
+ that invokes setUpModule/tearDownModule if either or both are available.
+
+ Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with
+ other fixtures (#517).
+ """
+ setup_module = _get_non_fixture_func(self.obj, "setUpModule")
+ if setup_module is None:
+ setup_module = _get_non_fixture_func(self.obj, "setup_module")
+
+ teardown_module = _get_non_fixture_func(self.obj, "tearDownModule")
+ if teardown_module is None:
+ teardown_module = _get_non_fixture_func(self.obj, "teardown_module")
+
+ if setup_module is None and teardown_module is None:
+ return
+
+ @fixtures.fixture(autouse=True, scope="module")
+ def xunit_setup_module_fixture(request):
+ if setup_module is not None:
+ _call_with_optional_argument(setup_module, request.module)
+ yield
+ if teardown_module is not None:
+ _call_with_optional_argument(teardown_module, request.module)
+
+ self.obj.__pytest_setup_module = xunit_setup_module_fixture
+
+ def _inject_setup_function_fixture(self):
+ """Injects a hidden autouse, function scoped fixture into the collected module object
+ that invokes setup_function/teardown_function if either or both are available.
+
+ Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with
+ other fixtures (#517).
+ """
+ setup_function = _get_non_fixture_func(self.obj, "setup_function")
+ teardown_function = _get_non_fixture_func(self.obj, "teardown_function")
+ if setup_function is None and teardown_function is None:
+ return
+
+ @fixtures.fixture(autouse=True, scope="function")
+ def xunit_setup_function_fixture(request):
+ if request.instance is not None:
+ # in this case we are bound to an instance, so we need to let
+ # setup_method handle this
+ yield
+ return
+ if setup_function is not None:
+ _call_with_optional_argument(setup_function, request.function)
+ yield
+ if teardown_function is not None:
+ _call_with_optional_argument(teardown_function, request.function)
+
+ self.obj.__pytest_setup_function = xunit_setup_function_fixture
+
def _importtestmodule(self):
# we assume we are only called once per module
importmode = self.config.getoption("--import-mode")
@@ -507,7 +507,7 @@ class Module(nodes.File, PyCollector):
mod = self.fspath.pyimport(ensuresyspath=importmode)
except SyntaxError:
raise self.CollectError(
- _pytest._code.ExceptionInfo.from_current().getrepr(style="short")
+ _pytest._code.ExceptionInfo.from_current().getrepr(style="short")
)
except self.fspath.ImportMismatchError:
e = sys.exc_info()[1]
@@ -523,7 +523,7 @@ class Module(nodes.File, PyCollector):
except ImportError:
from _pytest._code.code import ExceptionInfo
- exc_info = ExceptionInfo.from_current()
+ exc_info = ExceptionInfo.from_current()
if self.config.getoption("verbose") < 2:
exc_info.traceback = exc_info.traceback.filter(filter_traceback)
exc_repr = (
@@ -562,22 +562,22 @@ class Package(Module):
self._norecursepatterns = session._norecursepatterns
self.fspath = fspath
- def setup(self):
- # not using fixtures to call setup_module here because autouse fixtures
- # from packages are not called automatically (#4085)
- setup_module = _get_non_fixture_func(self.obj, "setUpModule")
- if setup_module is None:
- setup_module = _get_non_fixture_func(self.obj, "setup_module")
- if setup_module is not None:
- _call_with_optional_argument(setup_module, self.obj)
-
- teardown_module = _get_non_fixture_func(self.obj, "tearDownModule")
- if teardown_module is None:
- teardown_module = _get_non_fixture_func(self.obj, "teardown_module")
- if teardown_module is not None:
- func = partial(_call_with_optional_argument, teardown_module, self.obj)
- self.addfinalizer(func)
-
+ def setup(self):
+ # not using fixtures to call setup_module here because autouse fixtures
+ # from packages are not called automatically (#4085)
+ setup_module = _get_non_fixture_func(self.obj, "setUpModule")
+ if setup_module is None:
+ setup_module = _get_non_fixture_func(self.obj, "setup_module")
+ if setup_module is not None:
+ _call_with_optional_argument(setup_module, self.obj)
+
+ teardown_module = _get_non_fixture_func(self.obj, "tearDownModule")
+ if teardown_module is None:
+ teardown_module = _get_non_fixture_func(self.obj, "teardown_module")
+ if teardown_module is not None:
+ func = partial(_call_with_optional_argument, teardown_module, self.obj)
+ self.addfinalizer(func)
+
def _recurse(self, dirpath):
if dirpath.basename == "__pycache__":
return False
@@ -606,12 +606,12 @@ class Package(Module):
return proxy
def _collectfile(self, path, handle_dupes=True):
- assert path.isfile(), "%r is not a file (isdir=%r, exists=%r, islink=%r)" % (
- path,
- path.isdir(),
- path.exists(),
- path.islink(),
- )
+ assert path.isfile(), "%r is not a file (isdir=%r, exists=%r, islink=%r)" % (
+ path,
+ path.isdir(),
+ path.exists(),
+ path.islink(),
+ )
ihook = self.gethookproxy(path)
if not self.isinitpath(path):
if ihook.pytest_ignore_collect(path=path, config=self.config):
@@ -644,8 +644,8 @@ class Package(Module):
pkg_prefixes = set()
for path in this_path.visit(rec=self._recurse, bf=True, sort=True):
# We will visit our own __init__.py file, in which case we skip it.
- is_file = path.isfile()
- if is_file:
+ is_file = path.isfile()
+ if is_file:
if path.basename == "__init__.py" and path.dirpath() == this_path:
continue
@@ -656,13 +656,13 @@ class Package(Module):
):
continue
- if is_file:
- for x in self._collectfile(path):
- yield x
- elif not path.isdir():
- # Broken symlink or invalid/missing file.
- continue
- elif path.join("__init__.py").check(file=1):
+ if is_file:
+ for x in self._collectfile(path):
+ yield x
+ elif not path.isdir():
+ # Broken symlink or invalid/missing file.
+ continue
+ elif path.join("__init__.py").check(file=1):
pkg_prefixes.add(path)
@@ -674,9 +674,9 @@ def _get_xunit_setup_teardown(holder, attr_name, param_obj=None):
when the callable is called without arguments, defaults to the ``holder`` object.
Return ``None`` if a suitable callable is not found.
"""
- # TODO: only needed because of Package!
+ # TODO: only needed because of Package!
param_obj = param_obj if param_obj is not None else holder
- result = _get_non_fixture_func(holder, attr_name)
+ result = _get_non_fixture_func(holder, attr_name)
if result is not None:
arg_count = result.__code__.co_argcount
if inspect.ismethod(result):
@@ -687,19 +687,19 @@ def _get_xunit_setup_teardown(holder, attr_name, param_obj=None):
return result
-def _call_with_optional_argument(func, arg):
- """Call the given function with the given argument if func accepts one argument, otherwise
- calls func without arguments"""
- arg_count = func.__code__.co_argcount
- if inspect.ismethod(func):
- arg_count -= 1
- if arg_count:
- func(arg)
- else:
- func()
-
-
-def _get_non_fixture_func(obj, name):
+def _call_with_optional_argument(func, arg):
+ """Call the given function with the given argument if func accepts one argument, otherwise
+ calls func without arguments"""
+ arg_count = func.__code__.co_argcount
+ if inspect.ismethod(func):
+ arg_count -= 1
+ if arg_count:
+ func(arg)
+ else:
+ func()
+
+
+def _get_non_fixture_func(obj, name):
"""Return the attribute from the given object to be used as a setup/teardown
xunit-style function, but only if not marked as a fixture to
avoid calling it twice.
@@ -717,78 +717,78 @@ class Class(PyCollector):
return []
if hasinit(self.obj):
self.warn(
- PytestCollectionWarning(
+ PytestCollectionWarning(
"cannot collect test class %r because it has a "
- "__init__ constructor (from: %s)"
- % (self.obj.__name__, self.parent.nodeid)
+ "__init__ constructor (from: %s)"
+ % (self.obj.__name__, self.parent.nodeid)
)
)
return []
elif hasnew(self.obj):
self.warn(
- PytestCollectionWarning(
+ PytestCollectionWarning(
"cannot collect test class %r because it has a "
- "__new__ constructor (from: %s)"
- % (self.obj.__name__, self.parent.nodeid)
+ "__new__ constructor (from: %s)"
+ % (self.obj.__name__, self.parent.nodeid)
)
)
return []
- self._inject_setup_class_fixture()
- self._inject_setup_method_fixture()
-
- return [Instance(name="()", parent=self)]
-
- def _inject_setup_class_fixture(self):
- """Injects a hidden autouse, class scoped fixture into the collected class object
- that invokes setup_class/teardown_class if either or both are available.
-
- Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with
- other fixtures (#517).
- """
- setup_class = _get_non_fixture_func(self.obj, "setup_class")
- teardown_class = getattr(self.obj, "teardown_class", None)
- if setup_class is None and teardown_class is None:
- return
-
- @fixtures.fixture(autouse=True, scope="class")
- def xunit_setup_class_fixture(cls):
- if setup_class is not None:
- func = getimfunc(setup_class)
- _call_with_optional_argument(func, self.obj)
- yield
- if teardown_class is not None:
- func = getimfunc(teardown_class)
- _call_with_optional_argument(func, self.obj)
-
- self.obj.__pytest_setup_class = xunit_setup_class_fixture
-
- def _inject_setup_method_fixture(self):
- """Injects a hidden autouse, function scoped fixture into the collected class object
- that invokes setup_method/teardown_method if either or both are available.
-
- Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with
- other fixtures (#517).
- """
- setup_method = _get_non_fixture_func(self.obj, "setup_method")
- teardown_method = getattr(self.obj, "teardown_method", None)
- if setup_method is None and teardown_method is None:
- return
-
- @fixtures.fixture(autouse=True, scope="function")
- def xunit_setup_method_fixture(self, request):
- method = request.function
- if setup_method is not None:
- func = getattr(self, "setup_method")
- _call_with_optional_argument(func, method)
- yield
- if teardown_method is not None:
- func = getattr(self, "teardown_method")
- _call_with_optional_argument(func, method)
-
- self.obj.__pytest_setup_method = xunit_setup_method_fixture
-
-
+ self._inject_setup_class_fixture()
+ self._inject_setup_method_fixture()
+
+ return [Instance(name="()", parent=self)]
+
+ def _inject_setup_class_fixture(self):
+ """Injects a hidden autouse, class scoped fixture into the collected class object
+ that invokes setup_class/teardown_class if either or both are available.
+
+ Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with
+ other fixtures (#517).
+ """
+ setup_class = _get_non_fixture_func(self.obj, "setup_class")
+ teardown_class = getattr(self.obj, "teardown_class", None)
+ if setup_class is None and teardown_class is None:
+ return
+
+ @fixtures.fixture(autouse=True, scope="class")
+ def xunit_setup_class_fixture(cls):
+ if setup_class is not None:
+ func = getimfunc(setup_class)
+ _call_with_optional_argument(func, self.obj)
+ yield
+ if teardown_class is not None:
+ func = getimfunc(teardown_class)
+ _call_with_optional_argument(func, self.obj)
+
+ self.obj.__pytest_setup_class = xunit_setup_class_fixture
+
+ def _inject_setup_method_fixture(self):
+ """Injects a hidden autouse, function scoped fixture into the collected class object
+ that invokes setup_method/teardown_method if either or both are available.
+
+ Using a fixture to invoke this methods ensures we play nicely and unsurprisingly with
+ other fixtures (#517).
+ """
+ setup_method = _get_non_fixture_func(self.obj, "setup_method")
+ teardown_method = getattr(self.obj, "teardown_method", None)
+ if setup_method is None and teardown_method is None:
+ return
+
+ @fixtures.fixture(autouse=True, scope="function")
+ def xunit_setup_method_fixture(self, request):
+ method = request.function
+ if setup_method is not None:
+ func = getattr(self, "setup_method")
+ _call_with_optional_argument(func, method)
+ yield
+ if teardown_method is not None:
+ func = getattr(self, "teardown_method")
+ _call_with_optional_argument(func, method)
+
+ self.obj.__pytest_setup_method = xunit_setup_method_fixture
+
+
class Instance(PyCollector):
_ALLOW_MARKERS = False # hack, destroy later
# instances share the object with their parents in a way
@@ -813,12 +813,12 @@ class FunctionMixin(PyobjMixin):
def setup(self):
""" perform setup for this test function. """
- if isinstance(self.parent, Instance):
- self.parent.newinstance()
+ if isinstance(self.parent, Instance):
+ self.parent.newinstance()
self.obj = self._getobj()
def _prunetraceback(self, excinfo):
- if hasattr(self, "_obj") and not self.config.getoption("fulltrace", False):
+ if hasattr(self, "_obj") and not self.config.getoption("fulltrace", False):
code = _pytest._code.Code(get_real_func(self.obj))
path, firstlineno = code.path, code.firstlineno
traceback = excinfo.traceback
@@ -833,14 +833,14 @@ class FunctionMixin(PyobjMixin):
excinfo.traceback = ntraceback.filter()
# issue364: mark all but first and last frames to
# only show a single-line message for each frame
- if self.config.getoption("tbstyle", "auto") == "auto":
+ if self.config.getoption("tbstyle", "auto") == "auto":
if len(excinfo.traceback) > 2:
for entry in excinfo.traceback[1:-1]:
entry.set_repr_style("short")
def repr_failure(self, excinfo, outerr=None):
assert outerr is None, "XXX outerr usage is deprecated"
- style = self.config.getoption("tbstyle", "auto")
+ style = self.config.getoption("tbstyle", "auto")
if style == "auto":
style = "long"
return self._repr_failure_py(excinfo, style=style)
@@ -1048,7 +1048,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
:rtype: List[str]
:return: the list of ids for each argname given
"""
- from _pytest._io.saferepr import saferepr
+ from _pytest._io.saferepr import saferepr
idfn = None
if callable(ids):
@@ -1161,30 +1161,30 @@ def _find_parametrized_scope(argnames, arg2fixturedefs, indirect):
return "function"
-def _ascii_escaped_by_config(val, config):
- if config is None:
- escape_option = False
- else:
- escape_option = config.getini(
- "disable_test_id_escaping_and_forfeit_all_rights_to_community_support"
- )
- return val if escape_option else ascii_escaped(val)
-
-
+def _ascii_escaped_by_config(val, config):
+ if config is None:
+ escape_option = False
+ else:
+ escape_option = config.getini(
+ "disable_test_id_escaping_and_forfeit_all_rights_to_community_support"
+ )
+ return val if escape_option else ascii_escaped(val)
+
+
def _idval(val, argname, idx, idfn, item, config):
if idfn:
try:
- generated_id = idfn(val)
- if generated_id is not None:
- val = generated_id
+ generated_id = idfn(val)
+ if generated_id is not None:
+ val = generated_id
except Exception as e:
# See issue https://github.com/pytest-dev/pytest/issues/2169
- msg = "{}: error raised while trying to determine id of parameter '{}' at position {}\n"
- msg = msg.format(item.nodeid, argname, idx)
- # we only append the exception type and message because on Python 2 reraise does nothing
+ msg = "{}: error raised while trying to determine id of parameter '{}' at position {}\n"
+ msg = msg.format(item.nodeid, argname, idx)
+ # we only append the exception type and message because on Python 2 reraise does nothing
msg += " {}: {}\n".format(type(e).__name__, e)
- six.raise_from(ValueError(msg), e)
- elif config:
+ six.raise_from(ValueError(msg), e)
+ elif config:
hook_id = config.hook.pytest_make_parametrize_id(
config=config, val=val, argname=argname
)
@@ -1192,8 +1192,8 @@ def _idval(val, argname, idx, idfn, item, config):
return hook_id
if isinstance(val, STRING_TYPES):
- return _ascii_escaped_by_config(val, config)
- elif val is None or isinstance(val, (float, int, bool)):
+ return _ascii_escaped_by_config(val, config)
+ elif val is None or isinstance(val, (float, int, bool)):
return str(val)
elif isinstance(val, REGEX_TYPE):
return ascii_escaped(val.pattern)
@@ -1218,10 +1218,10 @@ def limit_idval(limit):
if len(idval) > limit:
prefix = idval[:limit]
# There might be same prefix for the different test cases - take item into account
- name = "{}-{}".format(kw.get('item', ''), safe_str(prefix))
+ name = "{}-{}".format(kw.get('item', ''), safe_str(prefix))
idx = names.setdefault(name, -1) + 1
names[name] = idx
- idval = "{}-{}".format(safe_str(prefix), idx)
+ idval = "{}-{}".format(safe_str(prefix), idx)
return idval
return wrapper
@@ -1241,7 +1241,7 @@ def _idvalset(idx, parameterset, argnames, idfn, ids, item, config):
]
return "-".join(this_id)
else:
- return _ascii_escaped_by_config(ids[idx], config)
+ return _ascii_escaped_by_config(ids[idx], config)
def idmaker(argnames, parametersets, idfn=None, ids=None, config=None, item=None):
@@ -1366,22 +1366,22 @@ def _showfixtures_main(config, session):
currentmodule = module
if verbose <= 0 and argname[0] == "_":
continue
- tw.write(argname, green=True)
- if fixturedef.scope != "function":
- tw.write(" [%s scope]" % fixturedef.scope, cyan=True)
+ tw.write(argname, green=True)
+ if fixturedef.scope != "function":
+ tw.write(" [%s scope]" % fixturedef.scope, cyan=True)
if verbose > 0:
- tw.write(" -- %s" % bestrel, yellow=True)
- tw.write("\n")
+ tw.write(" -- %s" % bestrel, yellow=True)
+ tw.write("\n")
loc = getlocation(fixturedef.func, curdir)
doc = fixturedef.func.__doc__ or ""
if doc:
write_docstring(tw, doc)
else:
tw.line(" %s: no docstring available" % (loc,), red=True)
- tw.line()
+ tw.line()
-def write_docstring(tw, doc, indent=" "):
+def write_docstring(tw, doc, indent=" "):
doc = doc.rstrip()
if "\n" in doc:
firstline, rest = doc.split("\n", 1)
@@ -1389,11 +1389,11 @@ def write_docstring(tw, doc, indent=" "):
firstline, rest = doc, ""
if firstline.strip():
- tw.line(indent + firstline.strip())
+ tw.line(indent + firstline.strip())
if rest:
for line in dedent(rest).split("\n"):
- tw.write(indent + line + "\n")
+ tw.write(indent + line + "\n")
class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr):
@@ -1437,23 +1437,23 @@ class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr):
if keywords:
self.keywords.update(keywords)
- # todo: this is a hell of a hack
- # https://github.com/pytest-dev/pytest/issues/4569
-
- self.keywords.update(
- dict.fromkeys(
- [
- mark.name
- for mark in self.iter_markers()
- if mark.name not in self.keywords
- ],
- True,
- )
- )
-
+ # todo: this is a hell of a hack
+ # https://github.com/pytest-dev/pytest/issues/4569
+
+ self.keywords.update(
+ dict.fromkeys(
+ [
+ mark.name
+ for mark in self.iter_markers()
+ if mark.name not in self.keywords
+ ],
+ True,
+ )
+ )
+
if fixtureinfo is None:
fixtureinfo = self.session._fixturemanager.getfixtureinfo(
- self, self.obj, self.cls, funcargs=True
+ self, self.obj, self.cls, funcargs=True
)
self._fixtureinfo = fixtureinfo
self.fixturenames = fixtureinfo.names_closure
diff --git a/contrib/python/pytest/py2/_pytest/python_api.py b/contrib/python/pytest/py2/_pytest/python_api.py
index f6e475c3a2..11e6bc98ae 100644
--- a/contrib/python/pytest/py2/_pytest/python_api.py
+++ b/contrib/python/pytest/py2/_pytest/python_api.py
@@ -1,10 +1,10 @@
-# -*- coding: utf-8 -*-
-from __future__ import absolute_import
-
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import
+
import math
import pprint
import sys
-import warnings
+import warnings
from decimal import Decimal
from numbers import Number
@@ -13,11 +13,11 @@ from six.moves import filterfalse
from six.moves import zip
import _pytest._code
-from _pytest import deprecated
+from _pytest import deprecated
from _pytest.compat import isclass
-from _pytest.compat import Iterable
+from _pytest.compat import Iterable
from _pytest.compat import Mapping
-from _pytest.compat import Sized
+from _pytest.compat import Sized
from _pytest.compat import STRING_TYPES
from _pytest.outcomes import fail
@@ -150,10 +150,10 @@ class ApproxNumpy(ApproxBase):
if np.isscalar(actual):
for i in np.ndindex(self.expected.shape):
- yield actual, self.expected[i].item()
+ yield actual, self.expected[i].item()
else:
for i in np.ndindex(self.expected.shape):
- yield actual[i].item(), self.expected[i].item()
+ yield actual[i].item(), self.expected[i].item()
class ApproxMapping(ApproxBase):
@@ -187,7 +187,7 @@ class ApproxMapping(ApproxBase):
raise _non_numeric_type_error(self.expected, at="key={!r}".format(key))
-class ApproxSequencelike(ApproxBase):
+class ApproxSequencelike(ApproxBase):
"""
Perform approximate comparisons where the expected value is a sequence of
numbers.
@@ -525,12 +525,12 @@ def approx(expected, rel=None, abs=None, nan_ok=False):
cls = ApproxMapping
elif _is_numpy_array(expected):
cls = ApproxNumpy
- elif (
- isinstance(expected, Iterable)
- and isinstance(expected, Sized)
- and not isinstance(expected, STRING_TYPES)
- ):
- cls = ApproxSequencelike
+ elif (
+ isinstance(expected, Iterable)
+ and isinstance(expected, Sized)
+ and not isinstance(expected, STRING_TYPES)
+ ):
+ cls = ApproxSequencelike
else:
raise _non_numeric_type_error(expected, at=None)
@@ -556,55 +556,55 @@ def _is_numpy_array(obj):
def raises(expected_exception, *args, **kwargs):
r"""
Assert that a code block/function call raises ``expected_exception``
- or raise a failure exception otherwise.
-
- :kwparam match: if specified, a string containing a regular expression,
- or a regular expression object, that is tested against the string
- representation of the exception using ``re.search``. To match a literal
- string that may contain `special characters`__, the pattern can
- first be escaped with ``re.escape``.
-
- __ https://docs.python.org/3/library/re.html#regular-expression-syntax
+ or raise a failure exception otherwise.
- :kwparam message: **(deprecated since 4.1)** if specified, provides a custom failure message
- if the exception is not raised. See :ref:`the deprecation docs <raises message deprecated>` for a workaround.
+ :kwparam match: if specified, a string containing a regular expression,
+ or a regular expression object, that is tested against the string
+ representation of the exception using ``re.search``. To match a literal
+ string that may contain `special characters`__, the pattern can
+ first be escaped with ``re.escape``.
- .. currentmodule:: _pytest._code
+ __ https://docs.python.org/3/library/re.html#regular-expression-syntax
- Use ``pytest.raises`` as a context manager, which will capture the exception of the given
- type::
+ :kwparam message: **(deprecated since 4.1)** if specified, provides a custom failure message
+ if the exception is not raised. See :ref:`the deprecation docs <raises message deprecated>` for a workaround.
+ .. currentmodule:: _pytest._code
+
+ Use ``pytest.raises`` as a context manager, which will capture the exception of the given
+ type::
+
>>> with raises(ZeroDivisionError):
... 1/0
- If the code block does not raise the expected exception (``ZeroDivisionError`` in the example
- above), or no exception at all, the check will fail instead.
-
- You can also use the keyword argument ``match`` to assert that the
- exception matches a text or regex::
-
- >>> with raises(ValueError, match='must be 0 or None'):
- ... raise ValueError("value must be 0 or None")
-
- >>> with raises(ValueError, match=r'must be \d+$'):
- ... raise ValueError("value must be 42")
-
- The context manager produces an :class:`ExceptionInfo` object which can be used to inspect the
- details of the captured exception::
-
- >>> with raises(ValueError) as exc_info:
- ... raise ValueError("value must be 42")
- >>> assert exc_info.type is ValueError
- >>> assert exc_info.value.args[0] == "value must be 42"
-
- .. deprecated:: 4.1
-
- In the context manager form you may use the keyword argument
- ``message`` to specify a custom failure message that will be displayed
- in case the ``pytest.raises`` check fails. This has been deprecated as it
- is considered error prone as users often mean to use ``match`` instead.
- See :ref:`the deprecation docs <raises message deprecated>` for a workaround.
-
+ If the code block does not raise the expected exception (``ZeroDivisionError`` in the example
+ above), or no exception at all, the check will fail instead.
+
+ You can also use the keyword argument ``match`` to assert that the
+ exception matches a text or regex::
+
+ >>> with raises(ValueError, match='must be 0 or None'):
+ ... raise ValueError("value must be 0 or None")
+
+ >>> with raises(ValueError, match=r'must be \d+$'):
+ ... raise ValueError("value must be 42")
+
+ The context manager produces an :class:`ExceptionInfo` object which can be used to inspect the
+ details of the captured exception::
+
+ >>> with raises(ValueError) as exc_info:
+ ... raise ValueError("value must be 42")
+ >>> assert exc_info.type is ValueError
+ >>> assert exc_info.value.args[0] == "value must be 42"
+
+ .. deprecated:: 4.1
+
+ In the context manager form you may use the keyword argument
+ ``message`` to specify a custom failure message that will be displayed
+ in case the ``pytest.raises`` check fails. This has been deprecated as it
+ is considered error prone as users often mean to use ``match`` instead.
+ See :ref:`the deprecation docs <raises message deprecated>` for a workaround.
+
.. note::
When using ``pytest.raises`` as a context manager, it's worthwhile to
@@ -617,7 +617,7 @@ def raises(expected_exception, *args, **kwargs):
>>> with raises(ValueError) as exc_info:
... if value > 10:
... raise ValueError("value must be <= 10")
- ... assert exc_info.type is ValueError # this will not execute
+ ... assert exc_info.type is ValueError # this will not execute
Instead, the following approach must be taken (note the difference in
scope)::
@@ -626,17 +626,17 @@ def raises(expected_exception, *args, **kwargs):
... if value > 10:
... raise ValueError("value must be <= 10")
...
- >>> assert exc_info.type is ValueError
+ >>> assert exc_info.type is ValueError
- **Using with** ``pytest.mark.parametrize``
+ **Using with** ``pytest.mark.parametrize``
- When using :ref:`pytest.mark.parametrize ref`
- it is possible to parametrize tests such that
- some runs raise an exception and others do not.
+ When using :ref:`pytest.mark.parametrize ref`
+ it is possible to parametrize tests such that
+ some runs raise an exception and others do not.
- See :ref:`parametrizing_conditional_raising` for an example.
+ See :ref:`parametrizing_conditional_raising` for an example.
- **Legacy form**
+ **Legacy form**
It is possible to specify a callable by passing a to-be-called lambda::
@@ -652,8 +652,8 @@ def raises(expected_exception, *args, **kwargs):
>>> raises(ZeroDivisionError, f, x=0)
<ExceptionInfo ...>
- The form above is fully supported but discouraged for new code because the
- context manager form is regarded as more readable and less error-prone.
+ The form above is fully supported but discouraged for new code because the
+ context manager form is regarded as more readable and less error-prone.
.. note::
Similar to caught exception objects in Python, explicitly clearing
@@ -684,35 +684,35 @@ def raises(expected_exception, *args, **kwargs):
if not args:
if "message" in kwargs:
message = kwargs.pop("message")
- warnings.warn(deprecated.RAISES_MESSAGE_PARAMETER, stacklevel=2)
+ warnings.warn(deprecated.RAISES_MESSAGE_PARAMETER, stacklevel=2)
if "match" in kwargs:
match_expr = kwargs.pop("match")
if kwargs:
msg = "Unexpected keyword arguments passed to pytest.raises: "
- msg += ", ".join(sorted(kwargs))
+ msg += ", ".join(sorted(kwargs))
raise TypeError(msg)
return RaisesContext(expected_exception, message, match_expr)
elif isinstance(args[0], str):
- warnings.warn(deprecated.RAISES_EXEC, stacklevel=2)
- (code,) = args
+ warnings.warn(deprecated.RAISES_EXEC, stacklevel=2)
+ (code,) = args
assert isinstance(code, str)
frame = sys._getframe(1)
loc = frame.f_locals.copy()
loc.update(kwargs)
# print "raises frame scope: %r" % frame.f_locals
try:
- code = _pytest._code.Source(code).compile(_genframe=frame)
- exec(code, frame.f_globals, loc)
+ code = _pytest._code.Source(code).compile(_genframe=frame)
+ exec(code, frame.f_globals, loc)
# XXX didn't mean f_globals == f_locals something special?
# this is destroyed here ...
except expected_exception:
- return _pytest._code.ExceptionInfo.from_current()
+ return _pytest._code.ExceptionInfo.from_current()
else:
func = args[0]
try:
func(*args[1:], **kwargs)
except expected_exception:
- return _pytest._code.ExceptionInfo.from_current()
+ return _pytest._code.ExceptionInfo.from_current()
fail(message)
@@ -727,7 +727,7 @@ class RaisesContext(object):
self.excinfo = None
def __enter__(self):
- self.excinfo = _pytest._code.ExceptionInfo.for_later()
+ self.excinfo = _pytest._code.ExceptionInfo.for_later()
return self.excinfo
def __exit__(self, *tp):
@@ -738,6 +738,6 @@ class RaisesContext(object):
suppress_exception = issubclass(self.excinfo.type, self.expected_exception)
if sys.version_info[0] == 2 and suppress_exception:
sys.exc_clear()
- if self.match_expr is not None and suppress_exception:
+ if self.match_expr is not None and suppress_exception:
self.excinfo.match(self.match_expr)
return suppress_exception
diff --git a/contrib/python/pytest/py2/_pytest/recwarn.py b/contrib/python/pytest/py2/_pytest/recwarn.py
index 7abf2e9355..e5fa9c6a50 100644
--- a/contrib/python/pytest/py2/_pytest/recwarn.py
+++ b/contrib/python/pytest/py2/_pytest/recwarn.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" recording warnings during test function execution. """
from __future__ import absolute_import
from __future__ import division
@@ -12,8 +12,8 @@ import warnings
import six
import _pytest._code
-from _pytest.deprecated import PYTEST_WARNS_UNKNOWN_KWARGS
-from _pytest.deprecated import WARNS_EXEC
+from _pytest.deprecated import PYTEST_WARNS_UNKNOWN_KWARGS
+from _pytest.deprecated import WARNS_EXEC
from _pytest.fixtures import yield_fixture
from _pytest.outcomes import fail
@@ -87,26 +87,26 @@ def warns(expected_warning, *args, **kwargs):
"""
__tracebackhide__ = True
if not args:
- match_expr = kwargs.pop("match", None)
- if kwargs:
- warnings.warn(
- PYTEST_WARNS_UNKNOWN_KWARGS.format(args=sorted(kwargs)), stacklevel=2
- )
+ match_expr = kwargs.pop("match", None)
+ if kwargs:
+ warnings.warn(
+ PYTEST_WARNS_UNKNOWN_KWARGS.format(args=sorted(kwargs)), stacklevel=2
+ )
return WarningsChecker(expected_warning, match_expr=match_expr)
elif isinstance(args[0], str):
- warnings.warn(WARNS_EXEC, stacklevel=2)
- (code,) = args
+ warnings.warn(WARNS_EXEC, stacklevel=2)
+ (code,) = args
assert isinstance(code, str)
frame = sys._getframe(1)
loc = frame.f_locals.copy()
loc.update(kwargs)
- with WarningsChecker(expected_warning):
+ with WarningsChecker(expected_warning):
code = _pytest._code.Source(code).compile()
- exec(code, frame.f_globals, loc)
+ exec(code, frame.f_globals, loc)
else:
func = args[0]
- with WarningsChecker(expected_warning):
+ with WarningsChecker(expected_warning):
return func(*args[1:], **kwargs)
@@ -196,11 +196,11 @@ class WarningsRecorder(warnings.catch_warnings):
warnings.warn = self._saved_warn
super(WarningsRecorder, self).__exit__(*exc_info)
- # Built-in catch_warnings does not reset entered state so we do it
- # manually here for this context manager to become reusable.
- self._entered = False
-
+ # Built-in catch_warnings does not reset entered state so we do it
+ # manually here for this context manager to become reusable.
+ self._entered = False
+
class WarningsChecker(WarningsRecorder):
def __init__(self, expected_warning=None, match_expr=None):
super(WarningsChecker, self).__init__()
diff --git a/contrib/python/pytest/py2/_pytest/reports.py b/contrib/python/pytest/py2/_pytest/reports.py
index 0bba6762c3..0310966b6d 100644
--- a/contrib/python/pytest/py2/_pytest/reports.py
+++ b/contrib/python/pytest/py2/_pytest/reports.py
@@ -1,20 +1,20 @@
-# -*- coding: utf-8 -*-
-from pprint import pprint
-
+# -*- coding: utf-8 -*-
+from pprint import pprint
+
import py
-import six
-
-from _pytest._code.code import ExceptionInfo
-from _pytest._code.code import ReprEntry
-from _pytest._code.code import ReprEntryNative
-from _pytest._code.code import ReprExceptionInfo
-from _pytest._code.code import ReprFileLocation
-from _pytest._code.code import ReprFuncArgs
-from _pytest._code.code import ReprLocals
-from _pytest._code.code import ReprTraceback
+import six
+
+from _pytest._code.code import ExceptionInfo
+from _pytest._code.code import ReprEntry
+from _pytest._code.code import ReprEntryNative
+from _pytest._code.code import ReprExceptionInfo
+from _pytest._code.code import ReprFileLocation
+from _pytest._code.code import ReprFuncArgs
+from _pytest._code.code import ReprLocals
+from _pytest._code.code import ReprTraceback
from _pytest._code.code import TerminalRepr
-from _pytest.outcomes import skip
-from _pytest.pathlib import Path
+from _pytest.outcomes import skip
+from _pytest.pathlib import Path
def getslaveinfoline(node):
@@ -33,9 +33,9 @@ def getslaveinfoline(node):
class BaseReport(object):
- when = None
- location = None
-
+ when = None
+ location = None
+
def __init__(self, **kw):
self.__dict__.update(kw)
@@ -112,179 +112,179 @@ class BaseReport(object):
def fspath(self):
return self.nodeid.split("::")[0]
- @property
- def count_towards_summary(self):
- """
- **Experimental**
-
- Returns True if this report should be counted towards the totals shown at the end of the
- test session: "1 passed, 1 failure, etc".
-
- .. note::
-
- This function is considered **experimental**, so beware that it is subject to changes
- even in patch releases.
- """
- return True
-
- @property
- def head_line(self):
- """
- **Experimental**
-
- Returns the head line shown with longrepr output for this report, more commonly during
- traceback representation during failures::
-
- ________ Test.foo ________
-
-
- In the example above, the head_line is "Test.foo".
-
- .. note::
-
- This function is considered **experimental**, so beware that it is subject to changes
- even in patch releases.
- """
- if self.location is not None:
- fspath, lineno, domain = self.location
- return domain
-
- def _get_verbose_word(self, config):
- _category, _short, verbose = config.hook.pytest_report_teststatus(
- report=self, config=config
- )
- return verbose
-
- def _to_json(self):
- """
- This was originally the serialize_report() function from xdist (ca03269).
-
- Returns the contents of this report as a dict of builtin entries, suitable for
- serialization.
-
- Experimental method.
- """
-
- def disassembled_report(rep):
- reprtraceback = rep.longrepr.reprtraceback.__dict__.copy()
- reprcrash = rep.longrepr.reprcrash.__dict__.copy()
-
- new_entries = []
- for entry in reprtraceback["reprentries"]:
- entry_data = {
- "type": type(entry).__name__,
- "data": entry.__dict__.copy(),
- }
- for key, value in entry_data["data"].items():
- if hasattr(value, "__dict__"):
- entry_data["data"][key] = value.__dict__.copy()
- new_entries.append(entry_data)
-
- reprtraceback["reprentries"] = new_entries
-
- return {
- "reprcrash": reprcrash,
- "reprtraceback": reprtraceback,
- "sections": rep.longrepr.sections,
- }
-
- d = self.__dict__.copy()
- if hasattr(self.longrepr, "toterminal"):
- if hasattr(self.longrepr, "reprtraceback") and hasattr(
- self.longrepr, "reprcrash"
- ):
- d["longrepr"] = disassembled_report(self)
- else:
- d["longrepr"] = six.text_type(self.longrepr)
- else:
- d["longrepr"] = self.longrepr
- for name in d:
- if isinstance(d[name], (py.path.local, Path)):
- d[name] = str(d[name])
- elif name == "result":
- d[name] = None # for now
- return d
-
- @classmethod
- def _from_json(cls, reportdict):
- """
- This was originally the serialize_report() function from xdist (ca03269).
-
- Factory method that returns either a TestReport or CollectReport, depending on the calling
- class. It's the callers responsibility to know which class to pass here.
-
- Experimental method.
- """
- if reportdict["longrepr"]:
- if (
- "reprcrash" in reportdict["longrepr"]
- and "reprtraceback" in reportdict["longrepr"]
- ):
-
- reprtraceback = reportdict["longrepr"]["reprtraceback"]
- reprcrash = reportdict["longrepr"]["reprcrash"]
-
- unserialized_entries = []
- reprentry = None
- for entry_data in reprtraceback["reprentries"]:
- data = entry_data["data"]
- entry_type = entry_data["type"]
- if entry_type == "ReprEntry":
- reprfuncargs = None
- reprfileloc = None
- reprlocals = None
- if data["reprfuncargs"]:
- reprfuncargs = ReprFuncArgs(**data["reprfuncargs"])
- if data["reprfileloc"]:
- reprfileloc = ReprFileLocation(**data["reprfileloc"])
- if data["reprlocals"]:
- reprlocals = ReprLocals(data["reprlocals"]["lines"])
-
- reprentry = ReprEntry(
- lines=data["lines"],
- reprfuncargs=reprfuncargs,
- reprlocals=reprlocals,
- filelocrepr=reprfileloc,
- style=data["style"],
- )
- elif entry_type == "ReprEntryNative":
- reprentry = ReprEntryNative(data["lines"])
- else:
- _report_unserialization_failure(entry_type, cls, reportdict)
- unserialized_entries.append(reprentry)
- reprtraceback["reprentries"] = unserialized_entries
-
- exception_info = ReprExceptionInfo(
- reprtraceback=ReprTraceback(**reprtraceback),
- reprcrash=ReprFileLocation(**reprcrash),
- )
-
- for section in reportdict["longrepr"]["sections"]:
- exception_info.addsection(*section)
- reportdict["longrepr"] = exception_info
-
- return cls(**reportdict)
-
-
-def _report_unserialization_failure(type_name, report_class, reportdict):
- url = "https://github.com/pytest-dev/pytest/issues"
- stream = py.io.TextIO()
- pprint("-" * 100, stream=stream)
- pprint("INTERNALERROR: Unknown entry type returned: %s" % type_name, stream=stream)
- pprint("report_name: %s" % report_class, stream=stream)
- pprint(reportdict, stream=stream)
- pprint("Please report this bug at %s" % url, stream=stream)
- pprint("-" * 100, stream=stream)
- raise RuntimeError(stream.getvalue())
-
-
+ @property
+ def count_towards_summary(self):
+ """
+ **Experimental**
+
+ Returns True if this report should be counted towards the totals shown at the end of the
+ test session: "1 passed, 1 failure, etc".
+
+ .. note::
+
+ This function is considered **experimental**, so beware that it is subject to changes
+ even in patch releases.
+ """
+ return True
+
+ @property
+ def head_line(self):
+ """
+ **Experimental**
+
+ Returns the head line shown with longrepr output for this report, more commonly during
+ traceback representation during failures::
+
+ ________ Test.foo ________
+
+
+ In the example above, the head_line is "Test.foo".
+
+ .. note::
+
+ This function is considered **experimental**, so beware that it is subject to changes
+ even in patch releases.
+ """
+ if self.location is not None:
+ fspath, lineno, domain = self.location
+ return domain
+
+ def _get_verbose_word(self, config):
+ _category, _short, verbose = config.hook.pytest_report_teststatus(
+ report=self, config=config
+ )
+ return verbose
+
+ def _to_json(self):
+ """
+ This was originally the serialize_report() function from xdist (ca03269).
+
+ Returns the contents of this report as a dict of builtin entries, suitable for
+ serialization.
+
+ Experimental method.
+ """
+
+ def disassembled_report(rep):
+ reprtraceback = rep.longrepr.reprtraceback.__dict__.copy()
+ reprcrash = rep.longrepr.reprcrash.__dict__.copy()
+
+ new_entries = []
+ for entry in reprtraceback["reprentries"]:
+ entry_data = {
+ "type": type(entry).__name__,
+ "data": entry.__dict__.copy(),
+ }
+ for key, value in entry_data["data"].items():
+ if hasattr(value, "__dict__"):
+ entry_data["data"][key] = value.__dict__.copy()
+ new_entries.append(entry_data)
+
+ reprtraceback["reprentries"] = new_entries
+
+ return {
+ "reprcrash": reprcrash,
+ "reprtraceback": reprtraceback,
+ "sections": rep.longrepr.sections,
+ }
+
+ d = self.__dict__.copy()
+ if hasattr(self.longrepr, "toterminal"):
+ if hasattr(self.longrepr, "reprtraceback") and hasattr(
+ self.longrepr, "reprcrash"
+ ):
+ d["longrepr"] = disassembled_report(self)
+ else:
+ d["longrepr"] = six.text_type(self.longrepr)
+ else:
+ d["longrepr"] = self.longrepr
+ for name in d:
+ if isinstance(d[name], (py.path.local, Path)):
+ d[name] = str(d[name])
+ elif name == "result":
+ d[name] = None # for now
+ return d
+
+ @classmethod
+ def _from_json(cls, reportdict):
+ """
+ This was originally the serialize_report() function from xdist (ca03269).
+
+ Factory method that returns either a TestReport or CollectReport, depending on the calling
+ class. It's the callers responsibility to know which class to pass here.
+
+ Experimental method.
+ """
+ if reportdict["longrepr"]:
+ if (
+ "reprcrash" in reportdict["longrepr"]
+ and "reprtraceback" in reportdict["longrepr"]
+ ):
+
+ reprtraceback = reportdict["longrepr"]["reprtraceback"]
+ reprcrash = reportdict["longrepr"]["reprcrash"]
+
+ unserialized_entries = []
+ reprentry = None
+ for entry_data in reprtraceback["reprentries"]:
+ data = entry_data["data"]
+ entry_type = entry_data["type"]
+ if entry_type == "ReprEntry":
+ reprfuncargs = None
+ reprfileloc = None
+ reprlocals = None
+ if data["reprfuncargs"]:
+ reprfuncargs = ReprFuncArgs(**data["reprfuncargs"])
+ if data["reprfileloc"]:
+ reprfileloc = ReprFileLocation(**data["reprfileloc"])
+ if data["reprlocals"]:
+ reprlocals = ReprLocals(data["reprlocals"]["lines"])
+
+ reprentry = ReprEntry(
+ lines=data["lines"],
+ reprfuncargs=reprfuncargs,
+ reprlocals=reprlocals,
+ filelocrepr=reprfileloc,
+ style=data["style"],
+ )
+ elif entry_type == "ReprEntryNative":
+ reprentry = ReprEntryNative(data["lines"])
+ else:
+ _report_unserialization_failure(entry_type, cls, reportdict)
+ unserialized_entries.append(reprentry)
+ reprtraceback["reprentries"] = unserialized_entries
+
+ exception_info = ReprExceptionInfo(
+ reprtraceback=ReprTraceback(**reprtraceback),
+ reprcrash=ReprFileLocation(**reprcrash),
+ )
+
+ for section in reportdict["longrepr"]["sections"]:
+ exception_info.addsection(*section)
+ reportdict["longrepr"] = exception_info
+
+ return cls(**reportdict)
+
+
+def _report_unserialization_failure(type_name, report_class, reportdict):
+ url = "https://github.com/pytest-dev/pytest/issues"
+ stream = py.io.TextIO()
+ pprint("-" * 100, stream=stream)
+ pprint("INTERNALERROR: Unknown entry type returned: %s" % type_name, stream=stream)
+ pprint("report_name: %s" % report_class, stream=stream)
+ pprint(reportdict, stream=stream)
+ pprint("Please report this bug at %s" % url, stream=stream)
+ pprint("-" * 100, stream=stream)
+ raise RuntimeError(stream.getvalue())
+
+
class TestReport(BaseReport):
""" Basic test report object (also used for setup and teardown calls if
they fail).
"""
- __test__ = False
-
+ __test__ = False
+
def __init__(
self,
nodeid,
@@ -335,59 +335,59 @@ class TestReport(BaseReport):
self.__dict__.update(extra)
def __repr__(self):
- return "<%s %r when=%r outcome=%r>" % (
- self.__class__.__name__,
+ return "<%s %r when=%r outcome=%r>" % (
+ self.__class__.__name__,
self.nodeid,
self.when,
self.outcome,
)
- @classmethod
- def from_item_and_call(cls, item, call):
- """
- Factory method to create and fill a TestReport with standard item and call info.
- """
- when = call.when
- duration = call.stop - call.start
- keywords = {x: 1 for x in item.keywords}
- excinfo = call.excinfo
- sections = []
- if not call.excinfo:
- outcome = "passed"
- longrepr = None
- else:
- if not isinstance(excinfo, ExceptionInfo):
- outcome = "failed"
- longrepr = excinfo
- elif excinfo.errisinstance(skip.Exception):
- outcome = "skipped"
- r = excinfo._getreprcrash()
- longrepr = (str(r.path), r.lineno, r.message)
- else:
- outcome = "failed"
- if call.when == "call":
- longrepr = item.repr_failure(excinfo)
- else: # exception in setup or teardown
- longrepr = item._repr_failure_py(
- excinfo, style=item.config.getoption("tbstyle", "auto")
- )
- for rwhen, key, content in item._report_sections:
- sections.append(("Captured %s %s" % (key, rwhen), content))
- return cls(
- item.nodeid,
- item.location,
- keywords,
- outcome,
- longrepr,
- when,
- sections,
- duration,
- user_properties=item.user_properties,
- )
-
-
-class CollectReport(BaseReport):
- when = "collect"
+ @classmethod
+ def from_item_and_call(cls, item, call):
+ """
+ Factory method to create and fill a TestReport with standard item and call info.
+ """
+ when = call.when
+ duration = call.stop - call.start
+ keywords = {x: 1 for x in item.keywords}
+ excinfo = call.excinfo
+ sections = []
+ if not call.excinfo:
+ outcome = "passed"
+ longrepr = None
+ else:
+ if not isinstance(excinfo, ExceptionInfo):
+ outcome = "failed"
+ longrepr = excinfo
+ elif excinfo.errisinstance(skip.Exception):
+ outcome = "skipped"
+ r = excinfo._getreprcrash()
+ longrepr = (str(r.path), r.lineno, r.message)
+ else:
+ outcome = "failed"
+ if call.when == "call":
+ longrepr = item.repr_failure(excinfo)
+ else: # exception in setup or teardown
+ longrepr = item._repr_failure_py(
+ excinfo, style=item.config.getoption("tbstyle", "auto")
+ )
+ for rwhen, key, content in item._report_sections:
+ sections.append(("Captured %s %s" % (key, rwhen), content))
+ return cls(
+ item.nodeid,
+ item.location,
+ keywords,
+ outcome,
+ longrepr,
+ when,
+ sections,
+ duration,
+ user_properties=item.user_properties,
+ )
+
+
+class CollectReport(BaseReport):
+ when = "collect"
def __init__(self, nodeid, outcome, longrepr, result, sections=(), **extra):
self.nodeid = nodeid
@@ -415,21 +415,21 @@ class CollectErrorRepr(TerminalRepr):
def toterminal(self, out):
out.line(self.longrepr, red=True)
-
-
-def pytest_report_to_serializable(report):
- if isinstance(report, (TestReport, CollectReport)):
- data = report._to_json()
- data["_report_type"] = report.__class__.__name__
- return data
-
-
-def pytest_report_from_serializable(data):
- if "_report_type" in data:
- if data["_report_type"] == "TestReport":
- return TestReport._from_json(data)
- elif data["_report_type"] == "CollectReport":
- return CollectReport._from_json(data)
- assert False, "Unknown report_type unserialize data: {}".format(
- data["_report_type"]
- )
+
+
+def pytest_report_to_serializable(report):
+ if isinstance(report, (TestReport, CollectReport)):
+ data = report._to_json()
+ data["_report_type"] = report.__class__.__name__
+ return data
+
+
+def pytest_report_from_serializable(data):
+ if "_report_type" in data:
+ if data["_report_type"] == "TestReport":
+ return TestReport._from_json(data)
+ elif data["_report_type"] == "CollectReport":
+ return CollectReport._from_json(data)
+ assert False, "Unknown report_type unserialize data: {}".format(
+ data["_report_type"]
+ )
diff --git a/contrib/python/pytest/py2/_pytest/resultlog.py b/contrib/python/pytest/py2/_pytest/resultlog.py
index bd30b5071e..1d86cf088e 100644
--- a/contrib/python/pytest/py2/_pytest/resultlog.py
+++ b/contrib/python/pytest/py2/_pytest/resultlog.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" log machine-parseable test session result information in a plain
text file.
"""
@@ -35,9 +35,9 @@ def pytest_configure(config):
config.pluginmanager.register(config._resultlog)
from _pytest.deprecated import RESULT_LOG
- from _pytest.warnings import _issue_warning_captured
+ from _pytest.warnings import _issue_warning_captured
- _issue_warning_captured(RESULT_LOG, config.hook, stacklevel=2)
+ _issue_warning_captured(RESULT_LOG, config.hook, stacklevel=2)
def pytest_unconfigure(config):
@@ -67,9 +67,9 @@ class ResultLog(object):
def pytest_runtest_logreport(self, report):
if report.when != "call" and report.passed:
return
- res = self.config.hook.pytest_report_teststatus(
- report=report, config=self.config
- )
+ res = self.config.hook.pytest_report_teststatus(
+ report=report, config=self.config
+ )
code = res[1]
if code == "x":
longrepr = str(report.longrepr)
diff --git a/contrib/python/pytest/py2/_pytest/runner.py b/contrib/python/pytest/py2/_pytest/runner.py
index 34ae917738..076fb0f1bb 100644
--- a/contrib/python/pytest/py2/_pytest/runner.py
+++ b/contrib/python/pytest/py2/_pytest/runner.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" basic collect and runtest protocol implementations """
from __future__ import absolute_import
from __future__ import division
@@ -9,15 +9,15 @@ import os
import sys
from time import time
-import attr
+import attr
import six
from .reports import CollectErrorRepr
from .reports import CollectReport
from .reports import TestReport
from _pytest._code.code import ExceptionInfo
-from _pytest.compat import safe_str
-from _pytest.outcomes import Exit
+from _pytest.compat import safe_str
+from _pytest.outcomes import Exit
from _pytest.outcomes import Skipped
from _pytest.outcomes import TEST_OUTCOME
@@ -88,9 +88,9 @@ def runtestprotocol(item, log=True, nextitem=None):
rep = call_and_report(item, "setup", log)
reports = [rep]
if rep.passed:
- if item.config.getoption("setupshow", False):
+ if item.config.getoption("setupshow", False):
show_test_item(item)
- if not item.config.getoption("setuponly", False):
+ if not item.config.getoption("setuponly", False):
reports.append(call_and_report(item, "call", log))
reports.append(call_and_report(item, "teardown", log, nextitem=nextitem))
# after all teardown hooks have been called
@@ -184,7 +184,7 @@ def call_and_report(item, when, log=True, **kwds):
def check_interactive_exception(call, report):
return call.excinfo and not (
hasattr(report, "wasxfail")
- or call.excinfo.errisinstance(Skipped)
+ or call.excinfo.errisinstance(Skipped)
or call.excinfo.errisinstance(bdb.BdbQuit)
)
@@ -192,66 +192,66 @@ def check_interactive_exception(call, report):
def call_runtest_hook(item, when, **kwds):
hookname = "pytest_runtest_" + when
ihook = getattr(item.ihook, hookname)
- reraise = (Exit,)
- if not item.config.getoption("usepdb", False):
- reraise += (KeyboardInterrupt,)
- return CallInfo.from_call(
- lambda: ihook(item=item, **kwds), when=when, reraise=reraise
+ reraise = (Exit,)
+ if not item.config.getoption("usepdb", False):
+ reraise += (KeyboardInterrupt,)
+ return CallInfo.from_call(
+ lambda: ihook(item=item, **kwds), when=when, reraise=reraise
)
-@attr.s(repr=False)
+@attr.s(repr=False)
class CallInfo(object):
""" Result/Exception info a function invocation. """
- _result = attr.ib()
- # Optional[ExceptionInfo]
- excinfo = attr.ib()
- start = attr.ib()
- stop = attr.ib()
- when = attr.ib()
-
- @property
- def result(self):
- if self.excinfo is not None:
- raise AttributeError("{!r} has no valid result".format(self))
- return self._result
-
- @classmethod
- def from_call(cls, func, when, reraise=None):
+ _result = attr.ib()
+ # Optional[ExceptionInfo]
+ excinfo = attr.ib()
+ start = attr.ib()
+ stop = attr.ib()
+ when = attr.ib()
+
+ @property
+ def result(self):
+ if self.excinfo is not None:
+ raise AttributeError("{!r} has no valid result".format(self))
+ return self._result
+
+ @classmethod
+ def from_call(cls, func, when, reraise=None):
#: context of invocation: one of "setup", "call",
#: "teardown", "memocollect"
- start = time()
- excinfo = None
+ start = time()
+ excinfo = None
try:
- result = func()
- except: # noqa
- excinfo = ExceptionInfo.from_current()
- if reraise is not None and excinfo.errisinstance(reraise):
+ result = func()
+ except: # noqa
+ excinfo = ExceptionInfo.from_current()
+ if reraise is not None and excinfo.errisinstance(reraise):
raise
- result = None
- stop = time()
- return cls(start=start, stop=stop, when=when, result=result, excinfo=excinfo)
+ result = None
+ stop = time()
+ return cls(start=start, stop=stop, when=when, result=result, excinfo=excinfo)
def __repr__(self):
- if self.excinfo is not None:
- status = "exception"
- value = self.excinfo.value
+ if self.excinfo is not None:
+ status = "exception"
+ value = self.excinfo.value
else:
- # TODO: investigate unification
- value = repr(self._result)
- status = "result"
- return "<CallInfo when={when!r} {status}: {value}>".format(
- when=self.when, value=safe_str(value), status=status
- )
+ # TODO: investigate unification
+ value = repr(self._result)
+ status = "result"
+ return "<CallInfo when={when!r} {status}: {value}>".format(
+ when=self.when, value=safe_str(value), status=status
+ )
def pytest_runtest_makereport(item, call):
- return TestReport.from_item_and_call(item, call)
+ return TestReport.from_item_and_call(item, call)
def pytest_make_collect_report(collector):
- call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
+ call = CallInfo.from_call(lambda: list(collector.collect()), "collect")
longrepr = None
if not call.excinfo:
outcome = "passed"
diff --git a/contrib/python/pytest/py2/_pytest/setuponly.py b/contrib/python/pytest/py2/_pytest/setuponly.py
index 0859011241..9d4e43ccac 100644
--- a/contrib/python/pytest/py2/_pytest/setuponly.py
+++ b/contrib/python/pytest/py2/_pytest/setuponly.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
diff --git a/contrib/python/pytest/py2/_pytest/setupplan.py b/contrib/python/pytest/py2/_pytest/setupplan.py
index 47b0fe82ef..a7271d39d5 100644
--- a/contrib/python/pytest/py2/_pytest/setupplan.py
+++ b/contrib/python/pytest/py2/_pytest/setupplan.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
diff --git a/contrib/python/pytest/py2/_pytest/skipping.py b/contrib/python/pytest/py2/_pytest/skipping.py
index bc8b88e717..c0faa05a22 100644
--- a/contrib/python/pytest/py2/_pytest/skipping.py
+++ b/contrib/python/pytest/py2/_pytest/skipping.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" support for skip/xfail functions and markers. """
from __future__ import absolute_import
from __future__ import division
@@ -18,7 +18,7 @@ def pytest_addoption(parser):
action="store_true",
dest="runxfail",
default=False,
- help="report the results of xfail tests as if they were not marked",
+ help="report the results of xfail tests as if they were not marked",
)
parser.addini(
@@ -181,6 +181,6 @@ def pytest_runtest_makereport(item, call):
def pytest_report_teststatus(report):
if hasattr(report, "wasxfail"):
if report.skipped:
- return "xfailed", "x", "XFAIL"
+ return "xfailed", "x", "XFAIL"
elif report.passed:
- return "xpassed", "X", "XPASS"
+ return "xpassed", "X", "XPASS"
diff --git a/contrib/python/pytest/py2/_pytest/stepwise.py b/contrib/python/pytest/py2/_pytest/stepwise.py
index 8890259589..83fb4727cd 100644
--- a/contrib/python/pytest/py2/_pytest/stepwise.py
+++ b/contrib/python/pytest/py2/_pytest/stepwise.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
import pytest
@@ -9,7 +9,7 @@ def pytest_addoption(parser):
"--stepwise",
action="store_true",
dest="stepwise",
- help="exit on test failure and continue from last failing test next time",
+ help="exit on test failure and continue from last failing test next time",
)
group.addoption(
"--stepwise-skip",
@@ -29,7 +29,7 @@ class StepwisePlugin:
self.config = config
self.active = config.getvalue("stepwise")
self.session = None
- self.report_status = ""
+ self.report_status = ""
if self.active:
self.lastfailed = config.cache.get("cache/stepwise", None)
@@ -39,11 +39,11 @@ class StepwisePlugin:
self.session = session
def pytest_collection_modifyitems(self, session, config, items):
- if not self.active:
- return
- if not self.lastfailed:
- self.report_status = "no previously failed tests, not skipping."
+ if not self.active:
return
+ if not self.lastfailed:
+ self.report_status = "no previously failed tests, not skipping."
+ return
already_passed = []
found = False
@@ -59,12 +59,12 @@ class StepwisePlugin:
# If the previously failed test was not found among the test items,
# do not skip any tests.
if not found:
- self.report_status = "previously failed test not found, not skipping."
+ self.report_status = "previously failed test not found, not skipping."
already_passed = []
- else:
- self.report_status = "skipping {} already passed items.".format(
- len(already_passed)
- )
+ else:
+ self.report_status = "skipping {} already passed items.".format(
+ len(already_passed)
+ )
for item in already_passed:
items.remove(item)
@@ -72,7 +72,7 @@ class StepwisePlugin:
config.hook.pytest_deselected(items=already_passed)
def pytest_runtest_logreport(self, report):
- if not self.active:
+ if not self.active:
return
if report.failed:
@@ -97,10 +97,10 @@ class StepwisePlugin:
if report.nodeid == self.lastfailed:
self.lastfailed = None
- def pytest_report_collectionfinish(self):
- if self.active and self.config.getoption("verbose") >= 0 and self.report_status:
- return "stepwise: %s" % self.report_status
-
+ def pytest_report_collectionfinish(self):
+ if self.active and self.config.getoption("verbose") >= 0 and self.report_status:
+ return "stepwise: %s" % self.report_status
+
def pytest_sessionfinish(self, session):
if self.active:
self.config.cache.set("cache/stepwise", self.lastfailed)
diff --git a/contrib/python/pytest/py2/_pytest/terminal.py b/contrib/python/pytest/py2/_pytest/terminal.py
index 4418338c65..1a80290b48 100644
--- a/contrib/python/pytest/py2/_pytest/terminal.py
+++ b/contrib/python/pytest/py2/_pytest/terminal.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" terminal reporting of the full testing process.
This is a good source for looking at the various reporting hooks.
@@ -8,11 +8,11 @@ from __future__ import division
from __future__ import print_function
import argparse
-import collections
+import collections
import platform
import sys
import time
-from functools import partial
+from functools import partial
import attr
import pluggy
@@ -28,9 +28,9 @@ from _pytest.main import EXIT_OK
from _pytest.main import EXIT_TESTSFAILED
from _pytest.main import EXIT_USAGEERROR
-REPORT_COLLECTING_RESOLUTION = 0.5
-
+REPORT_COLLECTING_RESOLUTION = 0.5
+
class MoreQuietAction(argparse.Action):
"""
a modified copy of the argparse count action which counts down and updates
@@ -83,11 +83,11 @@ def pytest_addoption(parser):
dest="reportchars",
default="",
metavar="chars",
- help="show extra test summary info as specified by chars: (f)ailed, "
- "(E)rror, (s)kipped, (x)failed, (X)passed, "
- "(p)assed, (P)assed with output, (a)ll except passed (p/P), or (A)ll. "
+ help="show extra test summary info as specified by chars: (f)ailed, "
+ "(E)rror, (s)kipped, (x)failed, (X)passed, "
+ "(p)assed, (P)assed with output, (a)ll except passed (p/P), or (A)ll. "
"Warnings are displayed at all times except when "
- "--disable-warnings is set.",
+ "--disable-warnings is set.",
)
group._addoption(
"--disable-warnings",
@@ -142,7 +142,7 @@ def pytest_addoption(parser):
parser.addini(
"console_output_style",
- help='console output: "classic", or with additional progress information ("progress" (percentage) | "count").',
+ help='console output: "classic", or with additional progress information ("progress" (percentage) | "count").',
default="progress",
)
@@ -166,41 +166,41 @@ def getreportopt(config):
reportchars += "w"
elif config.option.disable_warnings and "w" in reportchars:
reportchars = reportchars.replace("w", "")
- aliases = {"F", "S"}
- for char in reportchars:
- # handle old aliases
- if char in aliases:
- char = char.lower()
- if char == "a":
- reportopts = "sxXwEf"
- elif char == "A":
- reportopts = "PpsxXwEf"
- break
- elif char not in reportopts:
- reportopts += char
+ aliases = {"F", "S"}
+ for char in reportchars:
+ # handle old aliases
+ if char in aliases:
+ char = char.lower()
+ if char == "a":
+ reportopts = "sxXwEf"
+ elif char == "A":
+ reportopts = "PpsxXwEf"
+ break
+ elif char not in reportopts:
+ reportopts += char
return reportopts
-@pytest.hookimpl(trylast=True) # after _pytest.runner
+@pytest.hookimpl(trylast=True) # after _pytest.runner
def pytest_report_teststatus(report):
- letter = "F"
+ letter = "F"
if report.passed:
letter = "."
elif report.skipped:
letter = "s"
- outcome = report.outcome
- if report.when in ("collect", "setup", "teardown") and outcome == "failed":
- outcome = "error"
- letter = "E"
-
- return outcome, letter, outcome.upper()
-
+ outcome = report.outcome
+ if report.when in ("collect", "setup", "teardown") and outcome == "failed":
+ outcome = "error"
+ letter = "E"
+ return outcome, letter, outcome.upper()
+
+
@attr.s
class WarningReport(object):
"""
- Simple structure to hold warnings information captured by ``pytest_warning_captured``.
+ Simple structure to hold warnings information captured by ``pytest_warning_captured``.
:ivar str message: user friendly message about the warning
:ivar str|None nodeid: node id that generated the warning (see ``get_location``).
@@ -211,7 +211,7 @@ class WarningReport(object):
message = attr.ib()
nodeid = attr.ib(default=None)
fslocation = attr.ib(default=None)
- count_towards_summary = True
+ count_towards_summary = True
def get_location(self, config):
"""
@@ -239,10 +239,10 @@ class TerminalReporter(object):
self.config = config
self._numcollected = 0
self._session = None
- self._showfspath = None
+ self._showfspath = None
self.stats = {}
- self.startdir = config.invocation_dir
+ self.startdir = config.invocation_dir
if file is None:
file = sys.stdout
self._tw = _pytest.config.create_terminal_writer(config, file)
@@ -260,47 +260,47 @@ class TerminalReporter(object):
def _determine_show_progress_info(self):
"""Return True if we should display progress information based on the current config"""
# do not show progress if we are not capturing output (#3038)
- if self.config.getoption("capture", "no") == "no":
+ if self.config.getoption("capture", "no") == "no":
return False
# do not show progress if we are showing fixture setup/teardown
- if self.config.getoption("setupshow", False):
+ if self.config.getoption("setupshow", False):
return False
- cfg = self.config.getini("console_output_style")
- if cfg in ("progress", "count"):
- return cfg
- return False
-
- @property
- def verbosity(self):
- return self.config.option.verbose
-
- @property
- def showheader(self):
- return self.verbosity >= 0
-
- @property
- def showfspath(self):
- if self._showfspath is None:
- return self.verbosity >= 0
- return self._showfspath
-
- @showfspath.setter
- def showfspath(self, value):
- self._showfspath = value
-
- @property
- def showlongtestinfo(self):
- return self.verbosity > 0
-
+ cfg = self.config.getini("console_output_style")
+ if cfg in ("progress", "count"):
+ return cfg
+ return False
+
+ @property
+ def verbosity(self):
+ return self.config.option.verbose
+
+ @property
+ def showheader(self):
+ return self.verbosity >= 0
+
+ @property
+ def showfspath(self):
+ if self._showfspath is None:
+ return self.verbosity >= 0
+ return self._showfspath
+
+ @showfspath.setter
+ def showfspath(self, value):
+ self._showfspath = value
+
+ @property
+ def showlongtestinfo(self):
+ return self.verbosity > 0
+
def hasopt(self, char):
char = {"xfailed": "x", "skipped": "s"}.get(char, char)
return char in self.reportchars
def write_fspath_result(self, nodeid, res, **markup):
fspath = self.config.rootdir.join(nodeid.split("::")[0])
- # NOTE: explicitly check for None to work around py bug, and for less
- # overhead in general (https://github.com/pytest-dev/py/pull/207).
- if self.currentfspath is None or fspath != self.currentfspath:
+ # NOTE: explicitly check for None to work around py bug, and for less
+ # overhead in general (https://github.com/pytest-dev/py/pull/207).
+ if self.currentfspath is None or fspath != self.currentfspath:
if self.currentfspath is not None and self._show_progress_info:
self._write_progress_information_filling_space()
self.currentfspath = fspath
@@ -401,9 +401,9 @@ class TerminalReporter(object):
self.write_fspath_result(fsid, "")
def pytest_runtest_logreport(self, report):
- self._tests_ran = True
+ self._tests_ran = True
rep = report
- res = self.config.hook.pytest_report_teststatus(report=rep, config=self.config)
+ res = self.config.hook.pytest_report_teststatus(report=rep, config=self.config)
category, letter, word = res
if isinstance(word, tuple):
word, markup = word
@@ -415,11 +415,11 @@ class TerminalReporter(object):
return
running_xdist = hasattr(rep, "node")
if markup is None:
- was_xfail = hasattr(report, "wasxfail")
- if rep.passed and not was_xfail:
+ was_xfail = hasattr(report, "wasxfail")
+ if rep.passed and not was_xfail:
markup = {"green": True}
- elif rep.passed and was_xfail:
- markup = {"yellow": True}
+ elif rep.passed and was_xfail:
+ markup = {"yellow": True}
elif rep.failed:
markup = {"red": True}
elif rep.skipped:
@@ -452,18 +452,18 @@ class TerminalReporter(object):
self.currentfspath = -2
def pytest_runtest_logfinish(self, nodeid):
- if self.verbosity <= 0 and self._show_progress_info:
- if self._show_progress_info == "count":
- num_tests = self._session.testscollected
- progress_length = len(" [{}/{}]".format(str(num_tests), str(num_tests)))
- else:
- progress_length = len(" [100%]")
+ if self.verbosity <= 0 and self._show_progress_info:
+ if self._show_progress_info == "count":
+ num_tests = self._session.testscollected
+ progress_length = len(" [{}/{}]".format(str(num_tests), str(num_tests)))
+ else:
+ progress_length = len(" [100%]")
self._progress_nodeids_reported.add(nodeid)
- is_last_item = (
+ is_last_item = (
len(self._progress_nodeids_reported) == self._session.testscollected
)
- if is_last_item:
+ if is_last_item:
self._write_progress_information_filling_space()
else:
w = self._width_of_current_line
@@ -474,7 +474,7 @@ class TerminalReporter(object):
def _get_progress_information_message(self):
collected = self._session.testscollected
- if self._show_progress_info == "count":
+ if self._show_progress_info == "count":
if collected:
progress = self._progress_nodeids_reported
counter_format = "{{:{}d}}".format(len(str(collected)))
@@ -529,7 +529,7 @@ class TerminalReporter(object):
t = time.time()
if (
self._collect_report_last_write is not None
- and self._collect_report_last_write > t - REPORT_COLLECTING_RESOLUTION
+ and self._collect_report_last_write > t - REPORT_COLLECTING_RESOLUTION
):
return
self._collect_report_last_write = t
@@ -537,7 +537,7 @@ class TerminalReporter(object):
errors = len(self.stats.get("error", []))
skipped = len(self.stats.get("skipped", []))
deselected = len(self.stats.get("deselected", []))
- selected = self._numcollected - errors - skipped - deselected
+ selected = self._numcollected - errors - skipped - deselected
if final:
line = "collected "
else:
@@ -551,8 +551,8 @@ class TerminalReporter(object):
line += " / %d deselected" % deselected
if skipped:
line += " / %d skipped" % skipped
- if self._numcollected > selected > 0:
- line += " / %d selected" % selected
+ if self._numcollected > selected > 0:
+ line += " / %d selected" % selected
if self.isatty:
self.rewrite(line, bold=True, erase=True)
if final:
@@ -595,39 +595,39 @@ class TerminalReporter(object):
self.write_line(line)
def pytest_report_header(self, config):
- line = "rootdir: %s" % config.rootdir
-
+ line = "rootdir: %s" % config.rootdir
+
if config.inifile:
- line += ", inifile: " + config.rootdir.bestrelpath(config.inifile)
-
- testpaths = config.getini("testpaths")
- if testpaths and config.args == testpaths:
- rel_paths = [config.rootdir.bestrelpath(x) for x in testpaths]
- line += ", testpaths: {}".format(", ".join(rel_paths))
- result = [line]
-
+ line += ", inifile: " + config.rootdir.bestrelpath(config.inifile)
+
+ testpaths = config.getini("testpaths")
+ if testpaths and config.args == testpaths:
+ rel_paths = [config.rootdir.bestrelpath(x) for x in testpaths]
+ line += ", testpaths: {}".format(", ".join(rel_paths))
+ result = [line]
+
plugininfo = config.pluginmanager.list_plugin_distinfo()
if plugininfo:
- result.append("plugins: %s" % ", ".join(_plugin_nameversions(plugininfo)))
- return result
+ result.append("plugins: %s" % ", ".join(_plugin_nameversions(plugininfo)))
+ return result
- def pytest_collection_finish(self, session):
- self.report_collect(True)
+ def pytest_collection_finish(self, session):
+ self.report_collect(True)
- if self.config.getoption("collectonly"):
+ if self.config.getoption("collectonly"):
self._printcollecteditems(session.items)
-
+
lines = self.config.hook.pytest_report_collectionfinish(
config=self.config, startdir=self.startdir, items=session.items
)
self._write_report_lines_from_hooks(lines)
- if self.config.getoption("collectonly"):
- if self.stats.get("failed"):
- self._tw.sep("!", "collection failures")
- for rep in self.stats.get("failed"):
- rep.toterminal(self._tw)
-
+ if self.config.getoption("collectonly"):
+ if self.stats.get("failed"):
+ self._tw.sep("!", "collection failures")
+ for rep in self.stats.get("failed"):
+ rep.toterminal(self._tw)
+
def _printcollecteditems(self, items):
# to print out items and their parent collectors
# we take care to leave out Instances aka ()
@@ -658,10 +658,10 @@ class TerminalReporter(object):
continue
indent = (len(stack) - 1) * " "
self._tw.line("%s%s" % (indent, col))
- if self.config.option.verbose >= 1:
- if hasattr(col, "_obj") and col._obj.__doc__:
- for line in col._obj.__doc__.strip().splitlines():
- self._tw.line("%s%s" % (indent + " ", line.strip()))
+ if self.config.option.verbose >= 1:
+ if hasattr(col, "_obj") and col._obj.__doc__:
+ for line in col._obj.__doc__.strip().splitlines():
+ self._tw.line("%s%s" % (indent + " ", line.strip()))
@pytest.hookimpl(hookwrapper=True)
def pytest_sessionfinish(self, exitstatus):
@@ -677,7 +677,7 @@ class TerminalReporter(object):
)
if exitstatus in summary_exit_codes:
self.config.hook.pytest_terminal_summary(
- terminalreporter=self, exitstatus=exitstatus, config=self.config
+ terminalreporter=self, exitstatus=exitstatus, config=self.config
)
if exitstatus == EXIT_INTERRUPTED:
self._report_keyboardinterrupt()
@@ -689,9 +689,9 @@ class TerminalReporter(object):
self.summary_errors()
self.summary_failures()
self.summary_warnings()
- self.summary_passes()
+ self.summary_passes()
yield
- self.short_test_summary()
+ self.short_test_summary()
# Display any extra warnings from teardown here (if any).
self.summary_warnings()
@@ -739,10 +739,10 @@ class TerminalReporter(object):
return res + " "
def _getfailureheadline(self, rep):
- head_line = rep.head_line
- if head_line:
- return head_line
- return "test session" # XXX?
+ head_line = rep.head_line
+ if head_line:
+ return head_line
+ return "test session" # XXX?
def _getcrashline(self, rep):
try:
@@ -771,33 +771,33 @@ class TerminalReporter(object):
final = hasattr(self, "_already_displayed_warnings")
if final:
- warning_reports = all_warnings[self._already_displayed_warnings :]
+ warning_reports = all_warnings[self._already_displayed_warnings :]
else:
- warning_reports = all_warnings
- self._already_displayed_warnings = len(warning_reports)
- if not warning_reports:
+ warning_reports = all_warnings
+ self._already_displayed_warnings = len(warning_reports)
+ if not warning_reports:
return
- reports_grouped_by_message = collections.OrderedDict()
- for wr in warning_reports:
- reports_grouped_by_message.setdefault(wr.message, []).append(wr)
+ reports_grouped_by_message = collections.OrderedDict()
+ for wr in warning_reports:
+ reports_grouped_by_message.setdefault(wr.message, []).append(wr)
title = "warnings summary (final)" if final else "warnings summary"
self.write_sep("=", title, yellow=True, bold=False)
- for message, warning_reports in reports_grouped_by_message.items():
- has_any_location = False
- for w in warning_reports:
- location = w.get_location(self.config)
+ for message, warning_reports in reports_grouped_by_message.items():
+ has_any_location = False
+ for w in warning_reports:
+ location = w.get_location(self.config)
if location:
- self._tw.line(str(location))
- has_any_location = True
- if has_any_location:
- lines = message.splitlines()
- indented = "\n".join(" " + x for x in lines)
- message = indented.rstrip()
- else:
- message = message.rstrip()
- self._tw.line(message)
+ self._tw.line(str(location))
+ has_any_location = True
+ if has_any_location:
+ lines = message.splitlines()
+ indented = "\n".join(" " + x for x in lines)
+ message = indented.rstrip()
+ else:
+ message = message.rstrip()
+ self._tw.line(message)
self._tw.line()
self._tw.line("-- Docs: https://docs.pytest.org/en/latest/warnings.html")
@@ -811,7 +811,7 @@ class TerminalReporter(object):
for rep in reports:
if rep.sections:
msg = self._getfailureheadline(rep)
- self.write_sep("_", msg, green=True, bold=True)
+ self.write_sep("_", msg, green=True, bold=True)
self._outrep_summary(rep)
def print_teardown_sections(self, rep):
@@ -833,22 +833,22 @@ class TerminalReporter(object):
if not reports:
return
self.write_sep("=", "FAILURES")
- if self.config.option.tbstyle == "line":
- for rep in reports:
+ if self.config.option.tbstyle == "line":
+ for rep in reports:
line = self._getcrashline(rep)
self.write_line(line)
- else:
- teardown_sections = {}
- for report in self.getreports(""):
- if report.when == "teardown":
- teardown_sections.setdefault(report.nodeid, []).append(report)
-
- for rep in reports:
+ else:
+ teardown_sections = {}
+ for report in self.getreports(""):
+ if report.when == "teardown":
+ teardown_sections.setdefault(report.nodeid, []).append(report)
+
+ for rep in reports:
msg = self._getfailureheadline(rep)
self.write_sep("_", msg, red=True, bold=True)
self._outrep_summary(rep)
- for report in teardown_sections.get(rep.nodeid, []):
- self.print_teardown_sections(report)
+ for report in teardown_sections.get(rep.nodeid, []):
+ self.print_teardown_sections(report)
def summary_errors(self):
if self.config.option.tbstyle != "no":
@@ -858,10 +858,10 @@ class TerminalReporter(object):
self.write_sep("=", "ERRORS")
for rep in self.stats["error"]:
msg = self._getfailureheadline(rep)
- if rep.when == "collect":
+ if rep.when == "collect":
msg = "ERROR collecting " + msg
- else:
- msg = "ERROR at %s of %s" % (rep.when, msg)
+ else:
+ msg = "ERROR at %s of %s" % (rep.when, msg)
self.write_sep("_", msg, red=True, bold=True)
self._outrep_summary(rep)
@@ -889,174 +889,174 @@ class TerminalReporter(object):
if self.verbosity == -1:
self.write_line(msg, **markup)
- def short_test_summary(self):
- if not self.reportchars:
- return
-
- def show_simple(stat, lines):
- failed = self.stats.get(stat, [])
- if not failed:
- return
- termwidth = self.writer.fullwidth
- config = self.config
- for rep in failed:
- line = _get_line_with_reprcrash_message(config, rep, termwidth)
- lines.append(line)
-
- def show_xfailed(lines):
- xfailed = self.stats.get("xfailed", [])
- for rep in xfailed:
- verbose_word = rep._get_verbose_word(self.config)
- pos = _get_pos(self.config, rep)
- lines.append("%s %s" % (verbose_word, pos))
- reason = rep.wasxfail
- if reason:
- lines.append(" " + str(reason))
-
- def show_xpassed(lines):
- xpassed = self.stats.get("xpassed", [])
- for rep in xpassed:
- verbose_word = rep._get_verbose_word(self.config)
- pos = _get_pos(self.config, rep)
- reason = rep.wasxfail
- lines.append("%s %s %s" % (verbose_word, pos, reason))
-
- def show_skipped(lines):
- skipped = self.stats.get("skipped", [])
- fskips = _folded_skips(skipped) if skipped else []
- if not fskips:
- return
- verbose_word = skipped[0]._get_verbose_word(self.config)
- for num, fspath, lineno, reason in fskips:
- if reason.startswith("Skipped: "):
- reason = reason[9:]
- if lineno is not None:
- lines.append(
- "%s [%d] %s:%d: %s"
- % (verbose_word, num, fspath, lineno + 1, reason)
- )
- else:
- lines.append("%s [%d] %s: %s" % (verbose_word, num, fspath, reason))
-
- REPORTCHAR_ACTIONS = {
- "x": show_xfailed,
- "X": show_xpassed,
- "f": partial(show_simple, "failed"),
- "s": show_skipped,
- "p": partial(show_simple, "passed"),
- "E": partial(show_simple, "error"),
- }
-
- lines = []
- for char in self.reportchars:
- action = REPORTCHAR_ACTIONS.get(char)
- if action: # skipping e.g. "P" (passed with output) here.
- action(lines)
-
- if lines:
- self.write_sep("=", "short test summary info")
- for line in lines:
- self.write_line(line)
-
-
-def _get_pos(config, rep):
- nodeid = config.cwd_relative_nodeid(rep.nodeid)
- return nodeid
-
-
-def _get_line_with_reprcrash_message(config, rep, termwidth):
- """Get summary line for a report, trying to add reprcrash message."""
- from wcwidth import wcswidth
-
- verbose_word = rep._get_verbose_word(config)
- pos = _get_pos(config, rep)
-
- line = "%s %s" % (verbose_word, pos)
- len_line = wcswidth(line)
- ellipsis, len_ellipsis = "...", 3
- if len_line > termwidth - len_ellipsis:
- # No space for an additional message.
- return line
-
+ def short_test_summary(self):
+ if not self.reportchars:
+ return
+
+ def show_simple(stat, lines):
+ failed = self.stats.get(stat, [])
+ if not failed:
+ return
+ termwidth = self.writer.fullwidth
+ config = self.config
+ for rep in failed:
+ line = _get_line_with_reprcrash_message(config, rep, termwidth)
+ lines.append(line)
+
+ def show_xfailed(lines):
+ xfailed = self.stats.get("xfailed", [])
+ for rep in xfailed:
+ verbose_word = rep._get_verbose_word(self.config)
+ pos = _get_pos(self.config, rep)
+ lines.append("%s %s" % (verbose_word, pos))
+ reason = rep.wasxfail
+ if reason:
+ lines.append(" " + str(reason))
+
+ def show_xpassed(lines):
+ xpassed = self.stats.get("xpassed", [])
+ for rep in xpassed:
+ verbose_word = rep._get_verbose_word(self.config)
+ pos = _get_pos(self.config, rep)
+ reason = rep.wasxfail
+ lines.append("%s %s %s" % (verbose_word, pos, reason))
+
+ def show_skipped(lines):
+ skipped = self.stats.get("skipped", [])
+ fskips = _folded_skips(skipped) if skipped else []
+ if not fskips:
+ return
+ verbose_word = skipped[0]._get_verbose_word(self.config)
+ for num, fspath, lineno, reason in fskips:
+ if reason.startswith("Skipped: "):
+ reason = reason[9:]
+ if lineno is not None:
+ lines.append(
+ "%s [%d] %s:%d: %s"
+ % (verbose_word, num, fspath, lineno + 1, reason)
+ )
+ else:
+ lines.append("%s [%d] %s: %s" % (verbose_word, num, fspath, reason))
+
+ REPORTCHAR_ACTIONS = {
+ "x": show_xfailed,
+ "X": show_xpassed,
+ "f": partial(show_simple, "failed"),
+ "s": show_skipped,
+ "p": partial(show_simple, "passed"),
+ "E": partial(show_simple, "error"),
+ }
+
+ lines = []
+ for char in self.reportchars:
+ action = REPORTCHAR_ACTIONS.get(char)
+ if action: # skipping e.g. "P" (passed with output) here.
+ action(lines)
+
+ if lines:
+ self.write_sep("=", "short test summary info")
+ for line in lines:
+ self.write_line(line)
+
+
+def _get_pos(config, rep):
+ nodeid = config.cwd_relative_nodeid(rep.nodeid)
+ return nodeid
+
+
+def _get_line_with_reprcrash_message(config, rep, termwidth):
+ """Get summary line for a report, trying to add reprcrash message."""
+ from wcwidth import wcswidth
+
+ verbose_word = rep._get_verbose_word(config)
+ pos = _get_pos(config, rep)
+
+ line = "%s %s" % (verbose_word, pos)
+ len_line = wcswidth(line)
+ ellipsis, len_ellipsis = "...", 3
+ if len_line > termwidth - len_ellipsis:
+ # No space for an additional message.
+ return line
+
try:
- msg = rep.longrepr.reprcrash.message
- except AttributeError:
- pass
- else:
- # Only use the first line.
- i = msg.find("\n")
- if i != -1:
- msg = msg[:i]
- len_msg = wcswidth(msg)
-
- sep, len_sep = " - ", 3
- max_len_msg = termwidth - len_line - len_sep
- if max_len_msg >= len_ellipsis:
- if len_msg > max_len_msg:
- max_len_msg -= len_ellipsis
- msg = msg[:max_len_msg]
- while wcswidth(msg) > max_len_msg:
- msg = msg[:-1]
- if six.PY2:
- # on python 2 systems with narrow unicode compilation, trying to
- # get a single character out of a multi-byte unicode character such as
- # u'😄' will result in a High Surrogate (U+D83D) character, which is
- # rendered as u'�'; in this case we just strip that character out as it
- # serves no purpose being rendered
- try:
- surrogate = six.unichr(0xD83D)
- msg = msg.rstrip(surrogate)
- except ValueError: # pragma: no cover
- # Jython cannot represent this lone surrogate at all (#5256):
- # ValueError: unichr() arg is a lone surrogate in range
- # (0xD800, 0xDFFF) (Jython UTF-16 encoding)
- # ignore this case as it shouldn't appear in the string anyway
- pass
- msg += ellipsis
- line += sep + msg
- return line
-
-
-def _folded_skips(skipped):
- d = {}
- for event in skipped:
- key = event.longrepr
- assert len(key) == 3, (event, key)
- keywords = getattr(event, "keywords", {})
- # folding reports with global pytestmark variable
- # this is workaround, because for now we cannot identify the scope of a skip marker
- # TODO: revisit after marks scope would be fixed
- if (
- event.when == "setup"
- and "skip" in keywords
- and "pytestmark" not in keywords
- ):
- key = (key[0], None, key[2])
- d.setdefault(key, []).append(event)
- values = []
- for key, events in d.items():
- values.append((len(events),) + key)
- return values
-
-
+ msg = rep.longrepr.reprcrash.message
+ except AttributeError:
+ pass
+ else:
+ # Only use the first line.
+ i = msg.find("\n")
+ if i != -1:
+ msg = msg[:i]
+ len_msg = wcswidth(msg)
+
+ sep, len_sep = " - ", 3
+ max_len_msg = termwidth - len_line - len_sep
+ if max_len_msg >= len_ellipsis:
+ if len_msg > max_len_msg:
+ max_len_msg -= len_ellipsis
+ msg = msg[:max_len_msg]
+ while wcswidth(msg) > max_len_msg:
+ msg = msg[:-1]
+ if six.PY2:
+ # on python 2 systems with narrow unicode compilation, trying to
+ # get a single character out of a multi-byte unicode character such as
+ # u'😄' will result in a High Surrogate (U+D83D) character, which is
+ # rendered as u'�'; in this case we just strip that character out as it
+ # serves no purpose being rendered
+ try:
+ surrogate = six.unichr(0xD83D)
+ msg = msg.rstrip(surrogate)
+ except ValueError: # pragma: no cover
+ # Jython cannot represent this lone surrogate at all (#5256):
+ # ValueError: unichr() arg is a lone surrogate in range
+ # (0xD800, 0xDFFF) (Jython UTF-16 encoding)
+ # ignore this case as it shouldn't appear in the string anyway
+ pass
+ msg += ellipsis
+ line += sep + msg
+ return line
+
+
+def _folded_skips(skipped):
+ d = {}
+ for event in skipped:
+ key = event.longrepr
+ assert len(key) == 3, (event, key)
+ keywords = getattr(event, "keywords", {})
+ # folding reports with global pytestmark variable
+ # this is workaround, because for now we cannot identify the scope of a skip marker
+ # TODO: revisit after marks scope would be fixed
+ if (
+ event.when == "setup"
+ and "skip" in keywords
+ and "pytestmark" not in keywords
+ ):
+ key = (key[0], None, key[2])
+ d.setdefault(key, []).append(event)
+ values = []
+ for key, events in d.items():
+ values.append((len(events),) + key)
+ return values
+
+
def build_summary_stats_line(stats):
- known_types = (
- "failed passed skipped deselected xfailed xpassed warnings error".split()
- )
- unknown_type_seen = False
- for found_type in stats:
- if found_type not in known_types:
- if found_type: # setup/teardown reports have an empty key, ignore them
- known_types.append(found_type)
- unknown_type_seen = True
+ known_types = (
+ "failed passed skipped deselected xfailed xpassed warnings error".split()
+ )
+ unknown_type_seen = False
+ for found_type in stats:
+ if found_type not in known_types:
+ if found_type: # setup/teardown reports have an empty key, ignore them
+ known_types.append(found_type)
+ unknown_type_seen = True
parts = []
- for key in known_types:
- reports = stats.get(key, None)
- if reports:
- count = sum(
- 1 for rep in reports if getattr(rep, "count_towards_summary", True)
- )
- parts.append("%d %s" % (count, key))
+ for key in known_types:
+ reports = stats.get(key, None)
+ if reports:
+ count = sum(
+ 1 for rep in reports if getattr(rep, "count_towards_summary", True)
+ )
+ parts.append("%d %s" % (count, key))
if parts:
line = ", ".join(parts)
@@ -1065,14 +1065,14 @@ def build_summary_stats_line(stats):
if "failed" in stats or "error" in stats:
color = "red"
- elif "warnings" in stats or unknown_type_seen:
+ elif "warnings" in stats or unknown_type_seen:
color = "yellow"
elif "passed" in stats:
color = "green"
else:
color = "yellow"
- return line, color
+ return line, color
def _plugin_nameversions(plugininfo):
diff --git a/contrib/python/pytest/py2/_pytest/tmpdir.py b/contrib/python/pytest/py2/_pytest/tmpdir.py
index a8a7037713..7502540a87 100644
--- a/contrib/python/pytest/py2/_pytest/tmpdir.py
+++ b/contrib/python/pytest/py2/_pytest/tmpdir.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" support for providing temporary directories to test functions. """
from __future__ import absolute_import
from __future__ import division
@@ -60,30 +60,30 @@ class TempPathFactory(object):
def getbasetemp(self):
""" return base temporary directory. """
- if self._basetemp is not None:
+ if self._basetemp is not None:
return self._basetemp
- if self._given_basetemp is not None:
- basetemp = self._given_basetemp
- ensure_reset_dir(basetemp)
- basetemp = basetemp.resolve()
- else:
- from_env = os.environ.get("PYTEST_DEBUG_TEMPROOT")
- temproot = Path(from_env or tempfile.gettempdir()).resolve()
- user = get_user() or "unknown"
- # use a sub-directory in the temproot to speed-up
- # make_numbered_dir() call
- rootdir = temproot.joinpath("pytest-of-{}".format(user))
- rootdir.mkdir(exist_ok=True)
- basetemp = make_numbered_dir_with_cleanup(
- prefix="pytest-", root=rootdir, keep=3, lock_timeout=LOCK_TIMEOUT
- )
- assert basetemp is not None, basetemp
- self._basetemp = t = basetemp
- self._trace("new basetemp", t)
- return t
-
-
+ if self._given_basetemp is not None:
+ basetemp = self._given_basetemp
+ ensure_reset_dir(basetemp)
+ basetemp = basetemp.resolve()
+ else:
+ from_env = os.environ.get("PYTEST_DEBUG_TEMPROOT")
+ temproot = Path(from_env or tempfile.gettempdir()).resolve()
+ user = get_user() or "unknown"
+ # use a sub-directory in the temproot to speed-up
+ # make_numbered_dir() call
+ rootdir = temproot.joinpath("pytest-of-{}".format(user))
+ rootdir.mkdir(exist_ok=True)
+ basetemp = make_numbered_dir_with_cleanup(
+ prefix="pytest-", root=rootdir, keep=3, lock_timeout=LOCK_TIMEOUT
+ )
+ assert basetemp is not None, basetemp
+ self._basetemp = t = basetemp
+ self._trace("new basetemp", t)
+ return t
+
+
@attr.s
class TempdirFactory(object):
"""
@@ -169,7 +169,7 @@ def _mk_tmp(request, factory):
@pytest.fixture
-def tmpdir(tmp_path):
+def tmpdir(tmp_path):
"""Return a temporary directory path object
which is unique to each test function invocation,
created as a sub directory of the base temporary
@@ -178,7 +178,7 @@ def tmpdir(tmp_path):
.. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html
"""
- return py.path.local(tmp_path)
+ return py.path.local(tmp_path)
@pytest.fixture
diff --git a/contrib/python/pytest/py2/_pytest/unittest.py b/contrib/python/pytest/py2/_pytest/unittest.py
index 3ff6f45d8d..8445a6785c 100644
--- a/contrib/python/pytest/py2/_pytest/unittest.py
+++ b/contrib/python/pytest/py2/_pytest/unittest.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
""" discovery and running of std-library "unittest" style tests. """
from __future__ import absolute_import
from __future__ import division
@@ -8,7 +8,7 @@ import sys
import traceback
import _pytest._code
-import pytest
+import pytest
from _pytest.compat import getimfunc
from _pytest.config import hookimpl
from _pytest.outcomes import fail
@@ -40,12 +40,12 @@ class UnitTestCase(Class):
cls = self.obj
if not getattr(cls, "__test__", True):
return
-
- skipped = getattr(cls, "__unittest_skip__", False)
- if not skipped:
- self._inject_setup_teardown_fixtures(cls)
- self._inject_setup_class_fixture()
-
+
+ skipped = getattr(cls, "__unittest_skip__", False)
+ if not skipped:
+ self._inject_setup_teardown_fixtures(cls)
+ self._inject_setup_class_fixture()
+
self.session._fixturemanager.parsefactories(self, unittest=True)
loader = TestLoader()
foundsomething = False
@@ -64,48 +64,48 @@ class UnitTestCase(Class):
if ut is None or runtest != ut.TestCase.runTest:
yield TestCaseFunction("runTest", parent=self)
- def _inject_setup_teardown_fixtures(self, cls):
- """Injects a hidden auto-use fixture to invoke setUpClass/setup_method and corresponding
- teardown functions (#517)"""
- class_fixture = _make_xunit_fixture(
- cls, "setUpClass", "tearDownClass", scope="class", pass_self=False
- )
- if class_fixture:
- cls.__pytest_class_setup = class_fixture
-
- method_fixture = _make_xunit_fixture(
- cls, "setup_method", "teardown_method", scope="function", pass_self=True
- )
- if method_fixture:
- cls.__pytest_method_setup = method_fixture
-
-
-def _make_xunit_fixture(obj, setup_name, teardown_name, scope, pass_self):
- setup = getattr(obj, setup_name, None)
- teardown = getattr(obj, teardown_name, None)
- if setup is None and teardown is None:
- return None
-
- @pytest.fixture(scope=scope, autouse=True)
- def fixture(self, request):
- if getattr(self, "__unittest_skip__", None):
- reason = self.__unittest_skip_why__
- pytest.skip(reason)
- if setup is not None:
- if pass_self:
- setup(self, request.function)
- else:
- setup()
- yield
- if teardown is not None:
- if pass_self:
- teardown(self, request.function)
- else:
- teardown()
-
- return fixture
-
-
+ def _inject_setup_teardown_fixtures(self, cls):
+ """Injects a hidden auto-use fixture to invoke setUpClass/setup_method and corresponding
+ teardown functions (#517)"""
+ class_fixture = _make_xunit_fixture(
+ cls, "setUpClass", "tearDownClass", scope="class", pass_self=False
+ )
+ if class_fixture:
+ cls.__pytest_class_setup = class_fixture
+
+ method_fixture = _make_xunit_fixture(
+ cls, "setup_method", "teardown_method", scope="function", pass_self=True
+ )
+ if method_fixture:
+ cls.__pytest_method_setup = method_fixture
+
+
+def _make_xunit_fixture(obj, setup_name, teardown_name, scope, pass_self):
+ setup = getattr(obj, setup_name, None)
+ teardown = getattr(obj, teardown_name, None)
+ if setup is None and teardown is None:
+ return None
+
+ @pytest.fixture(scope=scope, autouse=True)
+ def fixture(self, request):
+ if getattr(self, "__unittest_skip__", None):
+ reason = self.__unittest_skip_why__
+ pytest.skip(reason)
+ if setup is not None:
+ if pass_self:
+ setup(self, request.function)
+ else:
+ setup()
+ yield
+ if teardown is not None:
+ if pass_self:
+ teardown(self, request.function)
+ else:
+ teardown()
+
+ return fixture
+
+
class TestCaseFunction(Function):
nofuncargs = True
_excinfo = None
@@ -143,10 +143,10 @@ class TestCaseFunction(Function):
rawexcinfo = getattr(rawexcinfo, "_rawexcinfo", rawexcinfo)
try:
excinfo = _pytest._code.ExceptionInfo(rawexcinfo)
- # invoke the attributes to trigger storing the traceback
- # trial causes some issue there
- excinfo.value
- excinfo.traceback
+ # invoke the attributes to trigger storing the traceback
+ # trial causes some issue there
+ excinfo.value
+ excinfo.traceback
except TypeError:
try:
try:
@@ -168,7 +168,7 @@ class TestCaseFunction(Function):
except KeyboardInterrupt:
raise
except fail.Exception:
- excinfo = _pytest._code.ExceptionInfo.from_current()
+ excinfo = _pytest._code.ExceptionInfo.from_current()
self.__dict__.setdefault("_excinfo", []).append(excinfo)
def addError(self, testcase, rawexcinfo):
diff --git a/contrib/python/pytest/py2/_pytest/warning_types.py b/contrib/python/pytest/py2/_pytest/warning_types.py
index 861010a127..ef10d82809 100644
--- a/contrib/python/pytest/py2/_pytest/warning_types.py
+++ b/contrib/python/pytest/py2/_pytest/warning_types.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
import attr
@@ -10,46 +10,46 @@ class PytestWarning(UserWarning):
"""
-class PytestAssertRewriteWarning(PytestWarning):
+class PytestAssertRewriteWarning(PytestWarning):
"""
- Bases: :class:`PytestWarning`.
+ Bases: :class:`PytestWarning`.
- Warning emitted by the pytest assert rewrite module.
+ Warning emitted by the pytest assert rewrite module.
"""
-class PytestCacheWarning(PytestWarning):
+class PytestCacheWarning(PytestWarning):
"""
- Bases: :class:`PytestWarning`.
+ Bases: :class:`PytestWarning`.
- Warning emitted by the cache plugin in various situations.
- """
-
-
-class PytestConfigWarning(PytestWarning):
- """
- Bases: :class:`PytestWarning`.
-
- Warning emitted for configuration issues.
- """
-
-
-class PytestCollectionWarning(PytestWarning):
- """
- Bases: :class:`PytestWarning`.
-
- Warning emitted when pytest is not able to collect a file or symbol in a module.
- """
-
-
-class PytestDeprecationWarning(PytestWarning, DeprecationWarning):
- """
- Bases: :class:`pytest.PytestWarning`, :class:`DeprecationWarning`.
-
- Warning class for features that will be removed in a future version.
+ Warning emitted by the cache plugin in various situations.
"""
+class PytestConfigWarning(PytestWarning):
+ """
+ Bases: :class:`PytestWarning`.
+
+ Warning emitted for configuration issues.
+ """
+
+
+class PytestCollectionWarning(PytestWarning):
+ """
+ Bases: :class:`PytestWarning`.
+
+ Warning emitted when pytest is not able to collect a file or symbol in a module.
+ """
+
+
+class PytestDeprecationWarning(PytestWarning, DeprecationWarning):
+ """
+ Bases: :class:`pytest.PytestWarning`, :class:`DeprecationWarning`.
+
+ Warning class for features that will be removed in a future version.
+ """
+
+
class PytestExperimentalApiWarning(PytestWarning, FutureWarning):
"""
Bases: :class:`pytest.PytestWarning`, :class:`FutureWarning`.
@@ -67,33 +67,33 @@ class PytestExperimentalApiWarning(PytestWarning, FutureWarning):
)
-class PytestUnhandledCoroutineWarning(PytestWarning):
- """
- Bases: :class:`PytestWarning`.
-
- Warning emitted when pytest encounters a test function which is a coroutine,
- but it was not handled by any async-aware plugin. Coroutine test functions
- are not natively supported.
- """
-
-
-class PytestUnknownMarkWarning(PytestWarning):
- """
- Bases: :class:`PytestWarning`.
-
- Warning emitted on use of unknown markers.
- See https://docs.pytest.org/en/latest/mark.html for details.
- """
-
-
-class RemovedInPytest4Warning(PytestDeprecationWarning):
- """
- Bases: :class:`pytest.PytestDeprecationWarning`.
-
- Warning class for features scheduled to be removed in pytest 4.0.
- """
-
-
+class PytestUnhandledCoroutineWarning(PytestWarning):
+ """
+ Bases: :class:`PytestWarning`.
+
+ Warning emitted when pytest encounters a test function which is a coroutine,
+ but it was not handled by any async-aware plugin. Coroutine test functions
+ are not natively supported.
+ """
+
+
+class PytestUnknownMarkWarning(PytestWarning):
+ """
+ Bases: :class:`PytestWarning`.
+
+ Warning emitted on use of unknown markers.
+ See https://docs.pytest.org/en/latest/mark.html for details.
+ """
+
+
+class RemovedInPytest4Warning(PytestDeprecationWarning):
+ """
+ Bases: :class:`pytest.PytestDeprecationWarning`.
+
+ Warning class for features scheduled to be removed in pytest 4.0.
+ """
+
+
@attr.s
class UnformattedWarning(object):
"""Used to hold warnings that need to format their message at runtime, as opposed to a direct message.
diff --git a/contrib/python/pytest/py2/_pytest/warnings.py b/contrib/python/pytest/py2/_pytest/warnings.py
index a3debae462..7c1240d501 100644
--- a/contrib/python/pytest/py2/_pytest/warnings.py
+++ b/contrib/python/pytest/py2/_pytest/warnings.py
@@ -1,4 +1,4 @@
-# -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
@@ -104,9 +104,9 @@ def catch_warnings_for_item(config, ihook, when, item):
def warning_record_to_str(warning_message):
- """Convert a warnings.WarningMessage to a string.
+ """Convert a warnings.WarningMessage to a string.
- This takes lot of unicode shenaningans into account for Python 2.
+ This takes lot of unicode shenaningans into account for Python 2.
When Python 2 support is dropped this function can be greatly simplified.
"""
warn_msg = warning_message.message
@@ -162,19 +162,19 @@ def pytest_terminal_summary(terminalreporter):
yield
-def _issue_warning_captured(warning, hook, stacklevel):
+def _issue_warning_captured(warning, hook, stacklevel):
"""
This function should be used instead of calling ``warnings.warn`` directly when we are in the "configure" stage:
at this point the actual options might not have been set, so we manually trigger the pytest_warning_captured
hook so we can display this warnings in the terminal. This is a hack until we can sort out #2891.
:param warning: the warning instance.
- :param hook: the hook caller
+ :param hook: the hook caller
:param stacklevel: stacklevel forwarded to warnings.warn
"""
with warnings.catch_warnings(record=True) as records:
warnings.simplefilter("always", type(warning))
warnings.warn(warning, stacklevel=stacklevel)
- hook.pytest_warning_captured.call_historic(
+ hook.pytest_warning_captured.call_historic(
kwargs=dict(warning_message=records[0], when="config", item=None)
)