Merge pull request #5368 from asottile/pyupgrade

Automated / semi-automated python3 upgrades
This commit is contained in:
Anthony Sottile 2019-06-03 08:41:37 -07:00 committed by GitHub
commit 5976f36240
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
191 changed files with 820 additions and 1517 deletions

View File

@ -7,17 +7,18 @@ repos:
args: [--safe, --quiet]
language_version: python3
- repo: https://github.com/asottile/blacken-docs
rev: v0.5.0
rev: v1.0.0
hooks:
- id: blacken-docs
additional_dependencies: [black==19.3b0]
language_version: python3
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.2.2
rev: v2.2.3
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: fix-encoding-pragma
args: [--remove]
- id: check-yaml
- id: debug-statements
exclude: _pytest/debugging.py
@ -31,14 +32,14 @@ repos:
rev: v1.4.0
hooks:
- id: reorder-python-imports
args: ['--application-directories=.:src']
args: ['--application-directories=.:src', --py3-plus]
- repo: https://github.com/asottile/pyupgrade
rev: v1.15.0
rev: v1.18.0
hooks:
- id: pyupgrade
args: [--keep-percent-format]
args: [--py3-plus]
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.3.0
rev: v1.4.0
hooks:
- id: rst-backticks
- repo: local

View File

@ -34,7 +34,7 @@ jobs:
- test $(python -c 'import sys; print("%d%d" % sys.version_info[0:2])') = 37
# Full run of latest supported version, without xdist.
- env: TOXENV=py37
- env: TOXENV=py37 PYTEST_COVERAGE=1
python: '3.7'
# Coverage tracking is slow with pypy, skip it.

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import sys
if __name__ == "__main__":

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# 10000 iterations, just for relative comparison
# 2.7.5 3.3.2
# FilesCompleter 75.1109 69.2116

View File

@ -1,3 +1,2 @@
# -*- coding: utf-8 -*-
for i in range(1000):
exec("def test_func_%d(): pass" % i)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import pytest

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from six.moves import range
import pytest
SKIP = True

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# flasky extensions. flasky pygments style based on tango style
from pygments.style import Style
from pygments.token import Comment

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
#
# pytest documentation build configuration file, created by
# sphinx-quickstart on Fri Oct 8 17:54:28 2010.
@ -63,9 +62,9 @@ source_suffix = ".rst"
master_doc = "contents"
# General information about the project.
project = u"pytest"
project = "pytest"
year = datetime.datetime.utcnow().year
copyright = u"20152019 , holger krekel and pytest-dev team"
copyright = "20152019 , holger krekel and pytest-dev team"
# The language for content autogenerated by Sphinx. Refer to documentation
@ -233,8 +232,8 @@ latex_documents = [
(
"contents",
"pytest.tex",
u"pytest Documentation",
u"holger krekel, trainer and consultant, http://merlinux.eu",
"pytest Documentation",
"holger krekel, trainer and consultant, http://merlinux.eu",
"manual",
)
]
@ -266,16 +265,16 @@ latex_domain_indices = False
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [("usage", "pytest", u"pytest usage", [u"holger krekel at merlinux eu"], 1)]
man_pages = [("usage", "pytest", "pytest usage", ["holger krekel at merlinux eu"], 1)]
# -- Options for Epub output ---------------------------------------------------
# Bibliographic Dublin Core info.
epub_title = u"pytest"
epub_author = u"holger krekel at merlinux eu"
epub_publisher = u"holger krekel at merlinux eu"
epub_copyright = u"2013, holger krekel et alii"
epub_title = "pytest"
epub_author = "holger krekel at merlinux eu"
epub_publisher = "holger krekel at merlinux eu"
epub_copyright = "2013, holger krekel et alii"
# The language of the text. It defaults to the language option
# or en if the language is not set.

View File

@ -1,2 +1 @@
# -*- coding: utf-8 -*-
collect_ignore = ["conf.py"]

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import _pytest._code
import pytest
from pytest import raises
@ -21,7 +20,7 @@ def test_generative(param1, param2):
assert param1 * 2 < param2
class TestFailing(object):
class TestFailing:
def test_simple(self):
def f():
return 42
@ -41,7 +40,7 @@ class TestFailing(object):
assert not f()
class TestSpecialisedExplanations(object):
class TestSpecialisedExplanations:
def test_eq_text(self):
assert "spam" == "eggs"
@ -101,7 +100,7 @@ class TestSpecialisedExplanations(object):
from dataclasses import dataclass
@dataclass
class Foo(object):
class Foo:
a: int
b: str
@ -113,7 +112,7 @@ class TestSpecialisedExplanations(object):
import attr
@attr.s
class Foo(object):
class Foo:
a = attr.ib()
b = attr.ib()
@ -123,7 +122,7 @@ class TestSpecialisedExplanations(object):
def test_attribute():
class Foo(object):
class Foo:
b = 1
i = Foo()
@ -131,14 +130,14 @@ def test_attribute():
def test_attribute_instance():
class Foo(object):
class Foo:
b = 1
assert Foo().b == 2
def test_attribute_failure():
class Foo(object):
class Foo:
def _get_b(self):
raise Exception("Failed to get attrib")
@ -149,10 +148,10 @@ def test_attribute_failure():
def test_attribute_multiple():
class Foo(object):
class Foo:
b = 1
class Bar(object):
class Bar:
b = 2
assert Foo().b == Bar().b
@ -162,7 +161,7 @@ def globf(x):
return x + 1
class TestRaises(object):
class TestRaises:
def test_raises(self):
s = "qwe"
raises(TypeError, int, s)
@ -203,7 +202,7 @@ def test_dynamic_compile_shows_nicely():
module.foo()
class TestMoreErrors(object):
class TestMoreErrors:
def test_complex_error(self):
def f():
return 44
@ -253,16 +252,16 @@ class TestMoreErrors(object):
x = 0
class TestCustomAssertMsg(object):
class TestCustomAssertMsg:
def test_single_line(self):
class A(object):
class A:
a = 1
b = 2
assert A.a == b, "A.a appears not to be b"
def test_multiline(self):
class A(object):
class A:
a = 1
b = 2
@ -271,7 +270,7 @@ class TestCustomAssertMsg(object):
), "A.a appears not to be b\nor does not appear to be b\none of those"
def test_custom_repr(self):
class JSON(object):
class JSON:
a = 1
def __repr__(self):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import py
import pytest

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
hello = "world"

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import py
failure_demo = py.path.local(__file__).dirpath("failure_demo.py")

View File

@ -1,9 +1,8 @@
# -*- coding: utf-8 -*-
def setup_module(module):
module.TestStateFullThing.classcount = 0
class TestStateFullThing(object):
class TestStateFullThing:
def setup_class(cls):
cls.classcount += 1

View File

@ -1,2 +1 @@
# -*- coding: utf-8 -*-
collect_ignore = ["nonpython"]

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import pytest
@ -9,7 +8,7 @@ def setup(request):
setup.finalize()
class CostlySetup(object):
class CostlySetup:
def __init__(self):
import time

View File

@ -1,2 +1 @@
# -*- coding: utf-8 -*-
#

View File

@ -1,3 +1,2 @@
# -*- coding: utf-8 -*-
def test_quick(setup):
pass

View File

@ -1,2 +1 @@
# -*- coding: utf-8 -*-
#

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
def test_something(setup):
assert setup.timecostly == 1

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
module containing a parametrized tests testing cross-python
serialization via the pickle module.
@ -23,7 +22,7 @@ def python2(request, python1):
return Python(request.param, python1.picklefile)
class Python(object):
class Python:
def __init__(self, version, picklefile):
self.pythonpath = distutils.spawn.find_executable(version)
if not self.pythonpath:

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# content of conftest.py
import pytest
@ -19,7 +18,7 @@ class YamlFile(pytest.File):
class YamlItem(pytest.Item):
def __init__(self, name, parent, spec):
super(YamlItem, self).__init__(name, parent)
super().__init__(name, parent)
self.spec = spec
def runtest(self):

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import sys
import pytest

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
def test_exception_syntax():
try:
0 / 0

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# run this with $ pytest --collect-only test_collectonly.py
#
@ -7,7 +6,7 @@ def test_function():
pass
class TestClass(object):
class TestClass:
def test_method(self):
pass

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import pytest
xfail = pytest.mark.xfail

View File

@ -335,8 +335,6 @@ string value of ``Hello World!`` if we do not supply a value or ``Hello
.. code-block:: python
# -*- coding: utf-8 -*-
import pytest

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import json
import py

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import sys
from distutils.core import setup

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
Invoke development tasks.
"""

View File

@ -1,11 +1,9 @@
# -*- coding: utf-8 -*-
from setuptools import setup
# TODO: if py gets upgrade to >=1.6,
# remove _width_of_current_line in terminal.py
INSTALL_REQUIRES = [
"py>=1.5.0",
"six>=1.10.0",
"packaging",
"attrs>=17.4.0",
"more-itertools>=4.0.0",

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
__all__ = ["__version__"]
try:

View File

@ -1,4 +1,3 @@
# -*- 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
@ -54,16 +53,12 @@ If things do not work right away:
which should throw a KeyError: 'COMPLINE' (which is properly set by the
global argcomplete script).
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import sys
from glob import glob
class FastFilesCompleter(object):
class FastFilesCompleter:
"Fast file completer class"
def __init__(self, directories=True):

View File

@ -1,9 +1,4 @@
# -*- coding: utf-8 -*-
""" python inspection/code generation API """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from .code import Code # noqa
from .code import ExceptionInfo # noqa
from .code import filter_traceback # noqa

View File

@ -1,95 +0,0 @@
# -*- coding: utf-8 -*-
# copied from python-2.7.3's traceback.py
# CHANGES:
# - some_str is replaced, trying to create unicode strings
#
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import types
from six import text_type
def format_exception_only(etype, value):
"""Format the exception part of a traceback.
The arguments are the exception type and value such as given by
sys.last_type and sys.last_value. The return value is a list of
strings, each ending in a newline.
Normally, the list contains a single string; however, for
SyntaxError exceptions, it contains several lines that (when
printed) display detailed information about where the syntax
error occurred.
The message indicating which exception occurred is always the last
string in the list.
"""
# An instance should not have a meaningful value parameter, but
# sometimes does, particularly for string exceptions, such as
# >>> raise string1, string2 # deprecated
#
# Clear these out first because issubtype(string1, SyntaxError)
# would throw another exception and mask the original problem.
if (
isinstance(etype, BaseException)
or isinstance(etype, types.InstanceType)
or etype is None
or type(etype) is str
):
return [_format_final_exc_line(etype, value)]
stype = etype.__name__
if not issubclass(etype, SyntaxError):
return [_format_final_exc_line(stype, value)]
# It was a syntax error; show exactly where the problem was found.
lines = []
try:
msg, (filename, lineno, offset, badline) = value.args
except Exception:
pass
else:
filename = filename or "<string>"
lines.append(' File "{}", line {}\n'.format(filename, lineno))
if badline is not None:
if isinstance(badline, bytes): # python 2 only
badline = badline.decode("utf-8", "replace")
lines.append(" {}\n".format(badline.strip()))
if offset is not None:
caretspace = badline.rstrip("\n")[:offset].lstrip()
# non-space whitespace (likes tabs) must be kept for alignment
caretspace = ((c.isspace() and c or " ") for c in caretspace)
# only three spaces to account for offset1 == pos 0
lines.append(" {}^\n".format("".join(caretspace)))
value = msg
lines.append(_format_final_exc_line(stype, value))
return lines
def _format_final_exc_line(etype, value):
"""Return a list of a single line -- normal case for format_exception_only"""
valuestr = _some_str(value)
if value is None or not valuestr:
line = "{}\n".format(etype)
else:
line = "{}: {}\n".format(etype, valuestr)
return line
def _some_str(value):
try:
return text_type(value)
except Exception:
try:
return bytes(value).decode("UTF-8", "replace")
except Exception:
pass
return "<unprintable {} object>".format(type(value).__name__)

View File

@ -1,8 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import inspect
import re
import sys
@ -21,7 +16,7 @@ from _pytest._io.saferepr import safeformat
from _pytest._io.saferepr import saferepr
class Code(object):
class Code:
""" wrapper around Python code objects """
def __init__(self, rawcode):
@ -32,7 +27,7 @@ class Code(object):
self.firstlineno = rawcode.co_firstlineno - 1
self.name = rawcode.co_name
except AttributeError:
raise TypeError("not a code object: %r" % (rawcode,))
raise TypeError("not a code object: {!r}".format(rawcode))
self.raw = rawcode
def __eq__(self, other):
@ -91,7 +86,7 @@ class Code(object):
return raw.co_varnames[:argcount]
class Frame(object):
class Frame:
"""Wrapper around a Python frame holding f_locals and f_globals
in which expressions can be evaluated."""
@ -154,7 +149,7 @@ class Frame(object):
return retval
class TracebackEntry(object):
class TracebackEntry:
""" a single entry in a traceback """
_repr_style = None
@ -314,7 +309,7 @@ class Traceback(list):
return self
def __getitem__(self, key):
val = super(Traceback, self).__getitem__(key)
val = super().__getitem__(key)
if isinstance(key, type(slice(0))):
val = self.__class__(val)
return val
@ -376,7 +371,7 @@ co_equal = compile(
@attr.s(repr=False)
class ExceptionInfo(object):
class ExceptionInfo:
""" wraps sys.exc_info() objects and offers
help for navigating the traceback.
"""
@ -561,7 +556,7 @@ class ExceptionInfo(object):
@attr.s
class FormattedExcinfo(object):
class FormattedExcinfo:
""" presenting information about failing Functions and Generators. """
# for traceback entries
@ -660,7 +655,7 @@ class FormattedExcinfo(object):
str_repr = safeformat(value)
# if len(str_repr) < 70 or not isinstance(value,
# (list, tuple, dict)):
lines.append("%-10s = %s" % (name, str_repr))
lines.append("{:<10} = {}".format(name, str_repr))
# else:
# self._line("%-10s =\\" % (name,))
# # XXX
@ -809,7 +804,7 @@ class FormattedExcinfo(object):
return ExceptionChainRepr(repr_chain)
class TerminalRepr(object):
class TerminalRepr:
def __str__(self):
# FYI this is called from pytest-xdist's serialization of exception
# information.
@ -819,7 +814,7 @@ class TerminalRepr(object):
return io.getvalue().strip()
def __repr__(self):
return "<%s instance at %0x>" % (self.__class__, id(self))
return "<{} instance at {:0x}>".format(self.__class__, id(self))
class ExceptionRepr(TerminalRepr):
@ -837,7 +832,7 @@ class ExceptionRepr(TerminalRepr):
class ExceptionChainRepr(ExceptionRepr):
def __init__(self, chain):
super(ExceptionChainRepr, self).__init__()
super().__init__()
self.chain = chain
# reprcrash and reprtraceback of the outermost (the newest) exception
# in the chain
@ -850,18 +845,18 @@ class ExceptionChainRepr(ExceptionRepr):
if element[2] is not None:
tw.line("")
tw.line(element[2], yellow=True)
super(ExceptionChainRepr, self).toterminal(tw)
super().toterminal(tw)
class ReprExceptionInfo(ExceptionRepr):
def __init__(self, reprtraceback, reprcrash):
super(ReprExceptionInfo, self).__init__()
super().__init__()
self.reprtraceback = reprtraceback
self.reprcrash = reprcrash
def toterminal(self, tw):
self.reprtraceback.toterminal(tw)
super(ReprExceptionInfo, self).toterminal(tw)
super().toterminal(tw)
class ReprTraceback(TerminalRepr):
@ -938,7 +933,9 @@ class ReprEntry(TerminalRepr):
self.reprfileloc.toterminal(tw)
def __str__(self):
return "%s\n%s\n%s" % ("\n".join(self.lines), self.reprlocals, self.reprfileloc)
return "{}\n{}\n{}".format(
"\n".join(self.lines), self.reprlocals, self.reprfileloc
)
class ReprFileLocation(TerminalRepr):
@ -955,7 +952,7 @@ class ReprFileLocation(TerminalRepr):
if i != -1:
msg = msg[:i]
tw.write(self.path, bold=True, red=True)
tw.line(":%s: %s" % (self.lineno, msg))
tw.line(":{}: {}".format(self.lineno, msg))
class ReprLocals(TerminalRepr):
@ -975,7 +972,7 @@ class ReprFuncArgs(TerminalRepr):
if self.args:
linesofar = ""
for name, value in self.args:
ns = "%s = %s" % (name, value)
ns = "{} = {}".format(name, value)
if len(ns) + len(linesofar) + 2 > tw.fullwidth:
if linesofar:
tw.line(linesofar)

View File

@ -1,8 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import ast
import inspect
import linecache
@ -14,10 +9,9 @@ from ast import PyCF_ONLY_AST as _AST_FLAG
from bisect import bisect_right
import py
import six
class Source(object):
class Source:
""" an immutable object holding a source code fragment,
possibly deindenting it.
"""
@ -34,7 +28,7 @@ class Source(object):
partlines = part.lines
elif isinstance(part, (tuple, list)):
partlines = [x.rstrip("\n") for x in part]
elif isinstance(part, six.string_types):
elif isinstance(part, str):
partlines = part.split("\n")
else:
partlines = getsource(part, deindent=de).lines

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
import pprint
from six.moves import reprlib
import reprlib
def _call_and_format_exception(call, x, *args):
@ -14,11 +12,8 @@ def _call_and_format_exception(call, x, *args):
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),
return '<[{}("{}") raised in repr()] {} object at 0x{:x}>'.format(
exc_name, exc_info, x.__class__.__name__, id(x)
)
@ -34,11 +29,11 @@ class SafeRepr(reprlib.Repr):
# Strictly speaking wrong on narrow builds
def repr(u):
if "'" not in u:
return u"'%s'" % u
return "'%s'" % u
elif '"' not in u:
return u'"%s"' % u
return '"%s"' % u
else:
return u"'%s'" % u.replace("'", r"\'")
return "'%s'" % u.replace("'", r"\'")
s = repr(x[: self.maxstring])
if len(s) > self.maxstring:

View File

@ -1,15 +1,8 @@
# -*- coding: utf-8 -*-
"""
support for presenting detailed information in failing assertions.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import sys
import six
from _pytest.assertion import rewrite
from _pytest.assertion import truncate
from _pytest.assertion import util
@ -56,14 +49,14 @@ def register_assert_rewrite(*names):
importhook.mark_rewrite(*names)
class DummyRewriteHook(object):
class DummyRewriteHook:
"""A no-op import hook for when rewriting is disabled."""
def mark_rewrite(self, *names):
pass
class AssertionState(object):
class AssertionState:
"""State for the assertion plugin."""
def __init__(self, config, mode):
@ -129,7 +122,7 @@ def pytest_runtest_setup(item):
if new_expl:
new_expl = truncate.truncate_if_required(new_expl, item)
new_expl = [line.replace("\n", "\\n") for line in new_expl]
res = six.text_type("\n~").join(new_expl)
res = "\n~".join(new_expl)
if item.config.getvalue("assertmode") == "rewrite":
res = res.replace("%", "%%")
return res

View File

@ -1,9 +1,4 @@
# -*- 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 ast
import errno
import imp
@ -19,7 +14,6 @@ from importlib.util import spec_from_file_location
import atomicwrites
import py
import six
from _pytest._io.saferepr import saferepr
from _pytest.assertion import util
@ -38,14 +32,14 @@ else:
else:
impl = "cpython"
ver = sys.version_info
PYTEST_TAG = "%s-%s%s-PYTEST" % (impl, ver[0], ver[1])
PYTEST_TAG = "{}-{}{}-PYTEST".format(impl, ver[0], ver[1])
del ver, impl
PYC_EXT = ".py" + (__debug__ and "c" or "o")
PYC_TAIL = "." + PYTEST_TAG + PYC_EXT
class AssertionRewritingHook(object):
class AssertionRewritingHook:
"""PEP302 Import hook which rewrites asserts."""
def __init__(self, config):
@ -154,7 +148,7 @@ class AssertionRewritingHook(object):
# to check for a cached pyc. This may not be optimal...
co = _read_pyc(fn_pypath, pyc, state.trace)
if co is None:
state.trace("rewriting %r" % (fn,))
state.trace("rewriting {!r}".format(fn))
source_stat, co = _rewrite_test(self.config, fn_pypath)
if co is None:
# Probably a SyntaxError in the test.
@ -166,7 +160,7 @@ class AssertionRewritingHook(object):
finally:
self._writing_pyc = False
else:
state.trace("found cached rewritten pyc for %r" % (fn,))
state.trace("found cached rewritten pyc for {!r}".format(fn))
self.modules[name] = co, pyc
return self
@ -205,26 +199,28 @@ class AssertionRewritingHook(object):
if self._is_marked_for_rewrite(name, state):
return False
state.trace("early skip of rewriting module: %s" % (name,))
state.trace("early skip of rewriting module: {}".format(name))
return True
def _should_rewrite(self, name, fn_pypath, state):
# always rewrite conftest files
fn = str(fn_pypath)
if fn_pypath.basename == "conftest.py":
state.trace("rewriting conftest file: %r" % (fn,))
state.trace("rewriting conftest file: {!r}".format(fn))
return True
if self.session is not None:
if self.session.isinitpath(fn):
state.trace("matched test file (was specified on cmdline): %r" % (fn,))
state.trace(
"matched test file (was specified on cmdline): {!r}".format(fn)
)
return True
# modules not passed explicitly on the command line are only
# rewritten if they match the naming convention for test files
for pat in self.fnpats:
if fn_pypath.fnmatch(pat):
state.trace("matched test file %r" % (fn,))
state.trace("matched test file {!r}".format(fn))
return True
return self._is_marked_for_rewrite(name, state)
@ -235,7 +231,9 @@ class AssertionRewritingHook(object):
except KeyError:
for marked in self._must_rewrite:
if name == marked or name.startswith(marked + "."):
state.trace("matched marked file %r (from %r)" % (name, marked))
state.trace(
"matched marked file {!r} (from {!r})".format(name, marked)
)
self._marked_for_rewrite_cache[name] = True
return True
@ -330,7 +328,7 @@ def _write_pyc(state, co, source_stat, pyc):
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))
state.trace("error writing pyc file at {}: errno={}".format(pyc, e.errno))
# we ignore any failure to write the cache file
# there are many reasons, permission-denied, __pycache__ being a
# file etc.
@ -338,8 +336,8 @@ def _write_pyc(state, co, source_stat, pyc):
return True
RN = "\r\n".encode("utf-8")
N = "\n".encode("utf-8")
RN = "\r\n".encode()
N = "\n".encode()
cookie_re = re.compile(r"^[ \t\f]*#.*coding[:=][ \t]*[-\w.]+")
BOM_UTF8 = "\xef\xbb\xbf"
@ -357,7 +355,7 @@ def _rewrite_test(config, fn):
tree = ast.parse(source, filename=fn.strpath)
except SyntaxError:
# Let this pop up again in the real import.
state.trace("failed to parse: %r" % (fn,))
state.trace("failed to parse: {!r}".format(fn))
return None, None
rewrite_asserts(tree, fn, config)
try:
@ -365,7 +363,7 @@ def _rewrite_test(config, fn):
except SyntaxError:
# It's possible that this error is from some bug in the
# assertion rewriting, but I don't know of a fast way to tell.
state.trace("failed to compile: %r" % (fn,))
state.trace("failed to compile: {!r}".format(fn))
return None, None
return stat, co
@ -385,7 +383,7 @@ def _read_pyc(source, pyc, trace=lambda x: None):
size = source.size()
data = fp.read(12)
except EnvironmentError as e:
trace("_read_pyc(%s): EnvironmentError %s" % (source, e))
trace("_read_pyc({}): EnvironmentError {}".format(source, e))
return None
# Check for invalid or out of date pyc file.
if (
@ -398,7 +396,7 @@ def _read_pyc(source, pyc, trace=lambda x: None):
try:
co = marshal.load(fp)
except Exception as e:
trace("_read_pyc(%s): marshal.load error %s" % (source, e))
trace("_read_pyc({}): marshal.load error {}".format(source, e))
return None
if not isinstance(co, types.CodeType):
trace("_read_pyc(%s): not a code object" % source)
@ -426,11 +424,11 @@ def _saferepr(obj):
# only occurs in python2.x, repr must return text in python3+
if isinstance(r, bytes):
# Represent unprintable bytes as `\x##`
r = u"".join(
u"\\x{:x}".format(ord(c)) if c not in string.printable else c.decode()
r = "".join(
"\\x{:x}".format(ord(c)) if c not in string.printable else c.decode()
for c in r
)
return r.replace(u"\n", u"\\n")
return r.replace("\n", "\\n")
def _format_assertmsg(obj):
@ -445,10 +443,10 @@ def _format_assertmsg(obj):
# contains a newline it gets escaped, however if an object has a
# .__repr__() which contains newlines it does not get escaped.
# However in either case we want to preserve the newline.
replaces = [(u"\n", u"\n~"), (u"%", u"%%")]
if not isinstance(obj, six.string_types):
replaces = [("\n", "\n~"), ("%", "%%")]
if not isinstance(obj, str):
obj = saferepr(obj)
replaces.append((u"\\n", u"\n~"))
replaces.append(("\\n", "\n~"))
if isinstance(obj, bytes):
replaces = [(r1.encode(), r2.encode()) for r1, r2 in replaces]
@ -471,8 +469,8 @@ def _should_repr_global_name(obj):
def _format_boolop(explanations, is_or):
explanation = "(" + (is_or and " or " or " and ").join(explanations) + ")"
if isinstance(explanation, six.text_type):
return explanation.replace(u"%", u"%%")
if isinstance(explanation, str):
return explanation.replace("%", "%%")
else:
return explanation.replace(b"%", b"%%")
@ -601,7 +599,7 @@ class AssertionRewriter(ast.NodeVisitor):
"""
def __init__(self, module_path, config):
super(AssertionRewriter, self).__init__()
super().__init__()
self.module_path = module_path
self.config = config
@ -613,7 +611,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("builtins", "@py_builtins"),
ast.alias("_pytest.assertion.rewrite", "@pytest_ar"),
]
doc = getattr(mod, "docstring", None)
@ -901,7 +899,7 @@ warn_explicit(
symbol = binop_map[binop.op.__class__]
left_expr, left_expl = self.visit(binop.left)
right_expr, right_expl = self.visit(binop.right)
explanation = "(%s %s %s)" % (left_expl, symbol, right_expl)
explanation = "({} {} {})".format(left_expl, symbol, right_expl)
res = self.assign(ast.BinOp(left_expr, binop.op, right_expr))
return res, explanation
@ -937,11 +935,11 @@ warn_explicit(
else: # **args have `arg` keywords with an .arg of None
arg_expls.append("**" + expl)
expl = "%s(%s)" % (func_expl, ", ".join(arg_expls))
expl = "{}({})".format(func_expl, ", ".join(arg_expls))
new_call = ast.Call(new_func, new_args, new_kwargs)
res = self.assign(new_call)
res_expl = self.explanation_param(self.display(res))
outer_expl = "%s\n{%s = %s\n}" % (res_expl, res_expl, expl)
outer_expl = "{}\n{{{} = {}\n}}".format(res_expl, res_expl, expl)
return res, outer_expl
def _visit_all(self, call):
@ -998,7 +996,7 @@ warn_explicit(
results.append(next_res)
sym = binop_map[op.__class__]
syms.append(ast.Str(sym))
expl = "%s %s %s" % (left_expl, sym, next_expl)
expl = "{} {} {}".format(left_expl, sym, next_expl)
expls.append(ast.Str(expl))
res_expr = ast.Compare(left_res, [op], [next_res])
self.statements.append(ast.Assign([store_names[i]], res_expr))

View File

@ -1,18 +1,11 @@
# -*- coding: utf-8 -*-
"""
Utilities for truncating assertion output.
Current default behaviour is to truncate assertion explanations at
~8 terminal lines, unless running in "-vv" mode or running on CI.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import six
DEFAULT_MAX_LINES = 8
DEFAULT_MAX_CHARS = 8 * 80
USAGE_MSG = "use '-vv' to show"
@ -76,7 +69,7 @@ def _truncate_explanation(input_lines, max_lines=None, max_chars=None):
else:
msg += " ({} lines hidden)".format(truncated_line_count)
msg += ", {}".format(USAGE_MSG)
truncated_explanation.extend([six.text_type(""), six.text_type(msg)])
truncated_explanation.extend(["", str(msg)])
return truncated_explanation

View File

@ -1,14 +1,7 @@
# -*- coding: utf-8 -*-
"""Utilities for assertion debugging"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import pprint
from collections.abc import Sequence
import six
import _pytest._code
from _pytest import outcomes
from _pytest._io.saferepr import saferepr
@ -42,7 +35,7 @@ def format_explanation(explanation):
explanation = ecu(explanation)
lines = _split_explanation(explanation)
result = _format_lines(lines)
return u"\n".join(result)
return "\n".join(result)
def _split_explanation(explanation):
@ -52,7 +45,7 @@ def _split_explanation(explanation):
Any other newlines will be escaped and appear in the line as the
literal '\n' characters.
"""
raw_lines = (explanation or u"").split("\n")
raw_lines = (explanation or "").split("\n")
lines = [raw_lines[0]]
for values in raw_lines[1:]:
if values and values[0] in ["{", "}", "~", ">"]:
@ -77,13 +70,13 @@ def _format_lines(lines):
for line in lines[1:]:
if line.startswith("{"):
if stackcnt[-1]:
s = u"and "
s = "and "
else:
s = u"where "
s = "where "
stack.append(len(result))
stackcnt[-1] += 1
stackcnt.append(0)
result.append(u" +" + u" " * (len(stack) - 1) + s + line[1:])
result.append(" +" + " " * (len(stack) - 1) + s + line[1:])
elif line.startswith("}"):
stack.pop()
stackcnt.pop()
@ -92,7 +85,7 @@ def _format_lines(lines):
assert line[0] in ["~", ">"]
stack[-1] += 1
indent = len(stack) if line.startswith("~") else len(stack) - 1
result.append(u" " * indent + line[1:])
result.append(" " * indent + line[1:])
assert len(stack) == 1
return result
@ -142,7 +135,7 @@ def assertrepr_compare(config, op, left, right):
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))
summary = "{} {} {}".format(ecu(left_repr), op, ecu(right_repr))
verbose = config.getoption("verbose")
explanation = None
@ -175,9 +168,9 @@ def assertrepr_compare(config, op, left, right):
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()),
"(pytest_assertion plugin: representation of details failed. "
"Probably an object has a faulty __repr__.)",
str(_pytest._code.ExceptionInfo.from_current()),
]
if not explanation:
@ -204,7 +197,7 @@ def _diff_text(left, right, verbose=0):
This is done using repr() which then needs post-processing to fix the encompassing quotes and un-escape
newlines and carriage returns (#429).
"""
r = six.text_type(repr(binary_text)[1:-1])
r = str(repr(binary_text)[1:-1])
r = r.replace(r"\n", "\n")
r = r.replace(r"\r", "\r")
return r
@ -221,7 +214,7 @@ def _diff_text(left, right, verbose=0):
if i > 42:
i -= 10 # Provide some context
explanation = [
u"Skipping %s identical leading characters in diff, use -v to show" % i
"Skipping %s identical leading characters in diff, use -v to show" % i
]
left = left[i:]
right = right[i:]
@ -232,8 +225,8 @@ def _diff_text(left, right, verbose=0):
if i > 42:
i -= 10 # Provide some context
explanation += [
u"Skipping {} identical trailing "
u"characters in diff, use -v to show".format(i)
"Skipping {} identical trailing "
"characters in diff, use -v to show".format(i)
]
left = left[:-i]
right = right[:-i]
@ -241,7 +234,7 @@ def _diff_text(left, right, verbose=0):
if left.isspace() or right.isspace():
left = repr(str(left))
right = repr(str(right))
explanation += [u"Strings contain only whitespace, escaping them using repr()"]
explanation += ["Strings contain only whitespace, escaping them using repr()"]
explanation += [
line.strip("\n")
for line in ndiff(left.splitlines(keepends), right.splitlines(keepends))
@ -255,29 +248,29 @@ def _compare_eq_verbose(left, right):
right_lines = repr(right).splitlines(keepends)
explanation = []
explanation += [u"-" + line for line in left_lines]
explanation += [u"+" + line for line in right_lines]
explanation += ["-" + line for line in left_lines]
explanation += ["+" + 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"]
return ["Use -v to get the full diff"]
# dynamic import to speedup pytest
import difflib
try:
left_formatting = pprint.pformat(left).splitlines()
right_formatting = pprint.pformat(right).splitlines()
explanation = [u"Full diff:"]
explanation = ["Full diff:"]
except Exception:
# hack: PrettyPrinter.pformat() in python 2 fails when formatting items that can't be sorted(), ie, calling
# sorted() on a list would raise. See issue #718.
# As a workaround, the full diff is generated by using the repr() string of each item of each container.
left_formatting = sorted(repr(x) for x in left)
right_formatting = sorted(repr(x) for x in right)
explanation = [u"Full diff (fallback to calling repr on each item):"]
explanation = ["Full diff (fallback to calling repr on each item):"]
explanation.extend(
line.strip() for line in difflib.ndiff(left_formatting, right_formatting)
)
@ -290,7 +283,9 @@ def _compare_eq_sequence(left, right, verbose=0):
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])]
explanation += [
"At index {} diff: {!r} != {!r}".format(i, left[i], right[i])
]
break
len_diff = len_left - len_right
@ -304,10 +299,12 @@ def _compare_eq_sequence(left, right, verbose=0):
extra = saferepr(right[len_left])
if len_diff == 1:
explanation += [u"%s contains one more item: %s" % (dir_with_more, extra)]
explanation += [
"{} contains one more item: {}".format(dir_with_more, extra)
]
else:
explanation += [
u"%s contains %d more items, first extra item: %s"
"%s contains %d more items, first extra item: %s"
% (dir_with_more, len_diff, extra)
]
return explanation
@ -318,11 +315,11 @@ def _compare_eq_set(left, right, verbose=0):
diff_left = left - right
diff_right = right - left
if diff_left:
explanation.append(u"Extra items in the left set:")
explanation.append("Extra items in the left set:")
for item in diff_left:
explanation.append(saferepr(item))
if diff_right:
explanation.append(u"Extra items in the right set:")
explanation.append("Extra items in the right set:")
for item in diff_right:
explanation.append(saferepr(item))
return explanation
@ -335,20 +332,20 @@ def _compare_eq_dict(left, right, verbose=0):
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)]
explanation += ["Omitting %s identical items, use -vv to show" % len(same)]
elif same:
explanation += [u"Common items:"]
explanation += ["Common items:"]
explanation += pprint.pformat(same).splitlines()
diff = {k for k in common if left[k] != right[k]}
if diff:
explanation += [u"Differing items:"]
explanation += ["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:"
"Left contains %d more item%s:"
% (len_extra_left, "" if len_extra_left == 1 else "s")
)
explanation.extend(
@ -358,7 +355,7 @@ def _compare_eq_dict(left, right, verbose=0):
len_extra_right = len(extra_right)
if len_extra_right:
explanation.append(
u"Right contains %d more item%s:"
"Right contains %d more item%s:"
% (len_extra_right, "" if len_extra_right == 1 else "s")
)
explanation.extend(
@ -386,15 +383,15 @@ def _compare_eq_cls(left, right, verbose, type_fns):
explanation = []
if same and verbose < 2:
explanation.append(u"Omitting %s identical items, use -vv to show" % len(same))
explanation.append("Omitting %s identical items, use -vv to show" % len(same))
elif same:
explanation += [u"Matching attributes:"]
explanation += ["Matching attributes:"]
explanation += pprint.pformat(same).splitlines()
if diff:
explanation += [u"Differing attributes:"]
explanation += ["Differing attributes:"]
for field in diff:
explanation += [
(u"%s: %r != %r") % (field, getattr(left, field), getattr(right, field))
("%s: %r != %r") % (field, getattr(left, field), getattr(right, field))
]
return explanation
@ -405,14 +402,14 @@ def _notin_text(term, text, verbose=0):
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 = ["%s is contained here:" % saferepr(term, maxsize=42)]
for line in diff:
if line.startswith(u"Skipping"):
if line.startswith("Skipping"):
continue
if line.startswith(u"- "):
if line.startswith("- "):
continue
if line.startswith(u"+ "):
newdiff.append(u" " + line[2:])
if line.startswith("+ "):
newdiff.append(" " + line[2:])
else:
newdiff.append(line)
return newdiff

View File

@ -1,28 +1,22 @@
# -*- coding: utf-8 -*-
"""
merged implementation of the cache provider
the name cache was not chosen to ensure pluggy automatically
ignores the external pytest-cache
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import json
import os
from collections import OrderedDict
import attr
import py
import six
import pytest
from .pathlib import Path
from .pathlib import resolve_from_str
from .pathlib import rmtree
README_CONTENT = u"""\
README_CONTENT = """\
# pytest cache directory #
This directory contains data from the pytest's cache plugin,
@ -42,7 +36,7 @@ Signature: 8a477f597d28d172789f06886806bc55
@attr.s
class Cache(object):
class Cache:
_cachedir = attr.ib(repr=False)
_config = attr.ib(repr=False)
@ -141,14 +135,14 @@ class Cache(object):
readme_path.write_text(README_CONTENT)
gitignore_path = self._cachedir.joinpath(".gitignore")
msg = u"# Created by pytest automatically.\n*"
msg = "# 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):
class LFPlugin:
""" Plugin which implements the --lf (run last-failing) option """
def __init__(self, config):
@ -261,7 +255,7 @@ class LFPlugin(object):
config.cache.set("cache/lastfailed", self.lastfailed)
class NFPlugin(object):
class NFPlugin:
""" Plugin which implements the --nf (run new-first) option """
def __init__(self, config):
@ -280,8 +274,8 @@ class NFPlugin(object):
other_items[item.nodeid] = item
items[:] = self._get_increasing_order(
six.itervalues(new_items)
) + self._get_increasing_order(six.itervalues(other_items))
new_items.values()
) + self._get_increasing_order(other_items.values())
self.cached_nodeids = [x.nodeid for x in items if isinstance(x, pytest.Item)]
def _get_increasing_order(self, items):

View File

@ -1,12 +1,7 @@
# -*- coding: utf-8 -*-
"""
per-test stdout/stderr capturing mechanism.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import collections
import contextlib
import io
@ -15,8 +10,6 @@ import sys
from io import UnsupportedOperation
from tempfile import TemporaryFile
import six
import pytest
from _pytest.compat import CaptureIO
@ -66,7 +59,7 @@ def pytest_load_initial_conftests(early_config, parser, args):
sys.stderr.write(err)
class CaptureManager(object):
class CaptureManager:
"""
Capture plugin, manages that the appropriate capture method is enabled/disabled during collection and each
test phase (setup, call, teardown). After each of those points, the captured output is obtained and
@ -85,10 +78,8 @@ class CaptureManager(object):
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,
return "<CaptureManager _method={!r} _global_capturing={!r} _current_item={!r}>".format(
self._method, self._global_capturing, self._current_item
)
def _getcapture(self, method):
@ -340,7 +331,7 @@ def _install_capture_fixture_on_item(request, capture_class):
del request.node._capture_fixture
class CaptureFixture(object):
class CaptureFixture:
"""
Object returned by :py:func:`capsys`, :py:func:`capsysbinary`, :py:func:`capfd` and :py:func:`capfdbinary`
fixtures.
@ -419,7 +410,7 @@ def safe_text_dupfile(f, mode, default_encoding="UTF8"):
return EncodedFile(f, encoding or default_encoding)
class EncodedFile(object):
class EncodedFile:
errors = "strict" # possibly needed by py3 code (issue555)
def __init__(self, buffer, encoding):
@ -427,7 +418,7 @@ class EncodedFile(object):
self.encoding = encoding
def write(self, obj):
if isinstance(obj, six.text_type):
if isinstance(obj, str):
obj = obj.encode(self.encoding, "replace")
else:
raise TypeError(
@ -455,7 +446,7 @@ class EncodedFile(object):
CaptureResult = collections.namedtuple("CaptureResult", ["out", "err"])
class MultiCapture(object):
class MultiCapture:
out = err = in_ = None
_state = None
@ -468,7 +459,7 @@ class MultiCapture(object):
self.err = Capture(2)
def __repr__(self):
return "<MultiCapture out=%r err=%r in_=%r _state=%r _in_suspended=%r>" % (
return "<MultiCapture out={!r} err={!r} in_={!r} _state={!r} _in_suspended={!r}>".format(
self.out,
self.err,
self.in_,
@ -534,12 +525,12 @@ class MultiCapture(object):
)
class NoCapture(object):
class NoCapture:
EMPTY_BUFFER = None
__init__ = start = done = suspend = resume = lambda *args: None
class FDCaptureBinary(object):
class FDCaptureBinary:
"""Capture IO to/from a given os-level filedescriptor.
snap() produces `bytes`
@ -573,10 +564,8 @@ 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 {} oldfd={} _state={!r}>".format(
self.targetfd, getattr(self, "targetfd_save", None), self._state
)
def start(self):
@ -618,7 +607,7 @@ class FDCaptureBinary(object):
def writeorg(self, data):
""" write to original file descriptor. """
if isinstance(data, six.text_type):
if isinstance(data, str):
data = data.encode("utf8") # XXX use encoding of original stream
os.write(self.targetfd_save, data)
@ -632,14 +621,14 @@ class FDCapture(FDCaptureBinary):
EMPTY_BUFFER = str()
def snap(self):
res = super(FDCapture, self).snap()
res = super().snap()
enc = getattr(self.tmpfile, "encoding", None)
if enc and isinstance(res, bytes):
res = six.text_type(res, enc, "replace")
res = str(res, enc, "replace")
return res
class SysCapture(object):
class SysCapture:
EMPTY_BUFFER = str()
_state = None
@ -656,11 +645,8 @@ class SysCapture(object):
self.tmpfile = tmpfile
def __repr__(self):
return "<SysCapture %s _old=%r, tmpfile=%r _state=%r>" % (
self.name,
self._old,
self.tmpfile,
self._state,
return "<SysCapture {} _old={!r}, tmpfile={!r} _state={!r}>".format(
self.name, self._old, self.tmpfile, self._state
)
def start(self):
@ -702,7 +688,7 @@ class SysCaptureBinary(SysCapture):
return res
class DontReadFromInput(six.Iterator):
class DontReadFromInput:
"""Temporary stub class. Ideally when stdin is accessed, the
capturing should be turned off, with possibly all data captured
so far sent to the screen. This should be configurable, though,

View File

@ -1,11 +1,6 @@
# -*- coding: utf-8 -*-
"""
python version compatibility code
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import functools
import inspect
import io
@ -153,10 +148,10 @@ 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)
i: "\\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"}
{ord("\t"): "\\t", ord("\r"): "\\r", ord("\n"): "\\n"}
)
@ -196,7 +191,7 @@ def ascii_escaped(val):
return _translate_non_printable(ret)
class _PytestWrapper(object):
class _PytestWrapper:
"""Dummy wrapper around a function object for internal use only.
Used to correctly unwrap the underlying function object
@ -315,15 +310,13 @@ def _setup_collect_fakemodule():
class CaptureIO(io.TextIOWrapper):
def __init__(self):
super(CaptureIO, self).__init__(
io.BytesIO(), encoding="UTF-8", newline="", write_through=True
)
super().__init__(io.BytesIO(), encoding="UTF-8", newline="", write_through=True)
def getvalue(self):
return self.buffer.getvalue().decode("UTF-8")
class FuncargnamesCompatAttr(object):
class FuncargnamesCompatAttr:
""" helper class so that Metafunc, Function and FixtureRequest
don't need to each define the "funcargnames" compatibility attribute.
"""

View File

@ -1,9 +1,4 @@
# -*- coding: utf-8 -*-
""" command line options, ini-file and conftest.py processing. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import copy
import inspect
@ -16,7 +11,6 @@ from functools import lru_cache
import importlib_metadata
import py
import six
from packaging.version import Version
from pluggy import HookimplMarker
from pluggy import HookspecMarker
@ -88,7 +82,7 @@ def main(args=None, plugins=None):
return EXIT_USAGEERROR
class cmdline(object): # compatibility namespace
class cmdline: # compatibility namespace
main = staticmethod(main)
@ -194,7 +188,7 @@ def _prepareconfig(args=None, plugins=None):
try:
if plugins:
for plugin in plugins:
if isinstance(plugin, six.string_types):
if isinstance(plugin, str):
pluginmanager.consider_pluginarg(plugin)
else:
pluginmanager.register(plugin)
@ -221,7 +215,7 @@ class PytestPluginManager(PluginManager):
"""
def __init__(self):
super(PytestPluginManager, self).__init__("pytest")
super().__init__("pytest")
self._conftest_plugins = set()
# state related to local conftest plugins
@ -269,7 +263,7 @@ class PytestPluginManager(PluginManager):
return
method = getattr(plugin, name)
opts = super(PytestPluginManager, self).parse_hookimpl_opts(plugin, name)
opts = super().parse_hookimpl_opts(plugin, name)
# consider only actual functions for hooks (#3775)
if not inspect.isroutine(method):
@ -288,9 +282,7 @@ class PytestPluginManager(PluginManager):
return opts
def parse_hookspec_opts(self, module_or_class, name):
opts = super(PytestPluginManager, self).parse_hookspec_opts(
module_or_class, name
)
opts = super().parse_hookspec_opts(module_or_class, name)
if opts is None:
method = getattr(module_or_class, name)
@ -317,7 +309,7 @@ class PytestPluginManager(PluginManager):
)
)
return
ret = super(PytestPluginManager, self).register(plugin, name)
ret = super().register(plugin, name)
if ret:
self.hook.pytest_plugin_registered.call_historic(
kwargs=dict(plugin=plugin, manager=self)
@ -478,7 +470,7 @@ class PytestPluginManager(PluginManager):
while i < n:
opt = args[i]
i += 1
if isinstance(opt, six.string_types):
if isinstance(opt, str):
if opt == "-p":
try:
parg = args[i]
@ -539,7 +531,7 @@ class PytestPluginManager(PluginManager):
# "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, str), (
"module name as text required, got %r" % modname
)
modname = str(modname)
@ -557,20 +549,19 @@ class PytestPluginManager(PluginManager):
try:
__import__(importspec)
except ImportError as e:
new_exc_message = 'Error importing plugin "%s": %s' % (
modname,
str(e.args[0]),
new_exc_message = 'Error importing plugin "{}": {}'.format(
modname, str(e.args[0])
)
new_exc = ImportError(new_exc_message)
tb = sys.exc_info()[2]
six.reraise(ImportError, new_exc, tb)
raise new_exc.with_traceback(tb)
except Skipped as e:
from _pytest.warnings import _issue_warning_captured
_issue_warning_captured(
PytestConfigWarning("skipped plugin %r: %s" % (modname, e.msg)),
PytestConfigWarning("skipped plugin {!r}: {}".format(modname, e.msg)),
self.hook,
stacklevel=1,
)
@ -588,7 +579,7 @@ def _get_plugin_specs_as_list(specs):
empty list is returned.
"""
if specs is not None and not isinstance(specs, types.ModuleType):
if isinstance(specs, six.string_types):
if isinstance(specs, str):
specs = specs.split(",") if specs else []
if not isinstance(specs, (list, tuple)):
raise UsageError(
@ -606,7 +597,7 @@ def _ensure_removed_sysmodule(modname):
pass
class Notset(object):
class Notset:
def __repr__(self):
return "<NOTSET>"
@ -626,7 +617,7 @@ def _iter_rewritable_modules(package_files):
yield package_name
class Config(object):
class Config:
""" access to configuration values, pluginmanager and plugin hooks. """
def __init__(self, pluginmanager):
@ -637,7 +628,7 @@ class Config(object):
_a = FILE_OR_DIR
self._parser = Parser(
usage="%%(prog)s [options] [%s] [%s] [...]" % (_a, _a),
usage="%(prog)s [options] [{}] [{}] [...]".format(_a, _a),
processopt=self._processopt,
)
#: a pluginmanager instance
@ -925,7 +916,7 @@ class Config(object):
try:
description, type, default = self._parser._inidict[name]
except KeyError:
raise ValueError("unknown configuration value: %r" % (name,))
raise ValueError("unknown configuration value: {!r}".format(name))
value = self._get_override_ini_value(name)
if value is None:
try:
@ -1002,8 +993,8 @@ class Config(object):
if skip:
import pytest
pytest.skip("no %r option found" % (name,))
raise ValueError("no option named %r" % (name,))
pytest.skip("no {!r} option found".format(name))
raise ValueError("no option named {!r}".format(name))
def getvalue(self, name, path=None):
""" (deprecated, use getoption()) """
@ -1091,4 +1082,4 @@ def _strtobool(val):
elif val in ("n", "no", "f", "false", "off", "0"):
return 0
else:
raise ValueError("invalid truth value %r" % (val,))
raise ValueError("invalid truth value {!r}".format(val))

View File

@ -1,16 +1,14 @@
# -*- coding: utf-8 -*-
import argparse
import warnings
import py
import six
from _pytest.config.exceptions import UsageError
FILE_OR_DIR = "file_or_dir"
class Parser(object):
class Parser:
""" Parser for command line arguments and ini-file values.
:ivar extra_info: dict of generic param -> value to display in case
@ -145,12 +143,12 @@ class ArgumentError(Exception):
def __str__(self):
if self.option_id:
return "option %s: %s" % (self.option_id, self.msg)
return "option {}: {}".format(self.option_id, self.msg)
else:
return self.msg
class Argument(object):
class Argument:
"""class that mimics the necessary behaviour of optparse.Option
it's currently a least effort implementation
@ -179,7 +177,7 @@ class Argument(object):
pass
else:
# this might raise a keyerror as well, don't want to catch that
if isinstance(typ, six.string_types):
if isinstance(typ, str):
if typ == "choice":
warnings.warn(
"`type` argument to addoption() is the string %r."
@ -282,7 +280,7 @@ class Argument(object):
return "Argument({})".format(", ".join(args))
class OptionGroup(object):
class OptionGroup:
def __init__(self, name, description="", parser=None):
self.name = name
self.description = description
@ -337,10 +335,10 @@ class MyOptionParser(argparse.ArgumentParser):
def error(self, message):
"""Transform argparse error message into UsageError."""
msg = "%s: error: %s" % (self.prog, message)
msg = "{}: error: {}".format(self.prog, message)
if hasattr(self._parser, "_config_source_hint"):
msg = "%s (%s)" % (msg, self._parser._config_source_hint)
msg = "{} ({})".format(msg, self._parser._config_source_hint)
raise UsageError(self.format_usage() + msg)
@ -352,7 +350,7 @@ class MyOptionParser(argparse.ArgumentParser):
if arg and arg[0] == "-":
lines = ["unrecognized arguments: %s" % (" ".join(argv))]
for k, v in sorted(self.extra_info.items()):
lines.append(" %s: %s" % (k, v))
lines.append(" {}: {}".format(k, v))
self.error("\n".join(lines))
getattr(args, FILE_OR_DIR).extend(argv)
return args

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
class UsageError(Exception):
""" error in pytest usage or invocation"""

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import os
import py

View File

@ -1,9 +1,4 @@
# -*- 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 argparse
import pdb
import sys
@ -74,7 +69,7 @@ def pytest_configure(config):
config._cleanup.append(fin)
class pytestPDB(object):
class pytestPDB:
""" Pseudo PDB that defers to the real pdb. """
_pluginmanager = None
@ -128,18 +123,18 @@ class pytestPDB(object):
def _get_pdb_wrapper_class(cls, pdb_cls, capman):
import _pytest.config
class PytestPdbWrapper(pdb_cls, object):
class PytestPdbWrapper(pdb_cls):
_pytest_capman = capman
_continued = False
def do_debug(self, arg):
cls._recursive_debug += 1
ret = super(PytestPdbWrapper, self).do_debug(arg)
ret = super().do_debug(arg)
cls._recursive_debug -= 1
return ret
def do_continue(self, arg):
ret = super(PytestPdbWrapper, self).do_continue(arg)
ret = super().do_continue(arg)
if cls._recursive_debug == 0:
tw = _pytest.config.create_terminal_writer(cls._config)
tw.line()
@ -171,7 +166,7 @@ class pytestPDB(object):
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)
ret = super().do_quit(arg)
if cls._recursive_debug == 0:
outcomes.exit("Quitting debugger")
@ -187,7 +182,7 @@ class pytestPDB(object):
Needed after do_continue resumed, and entering another
breakpoint again.
"""
ret = super(PytestPdbWrapper, self).setup(f, tb)
ret = super().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.
@ -196,7 +191,7 @@ class pytestPDB(object):
return ret
def get_stack(self, f, t):
stack, i = super(PytestPdbWrapper, self).get_stack(f, t)
stack, i = super().get_stack(f, t)
if f is None:
# Find last non-hidden frame.
i = max(0, len(stack) - 1)
@ -230,7 +225,7 @@ class pytestPDB(object):
else:
capturing = cls._is_capturing(capman)
if capturing == "global":
tw.sep(">", "PDB %s (IO-capturing turned off)" % (method,))
tw.sep(">", "PDB {} (IO-capturing turned off)".format(method))
elif capturing:
tw.sep(
">",
@ -238,7 +233,7 @@ class pytestPDB(object):
% (method, capturing),
)
else:
tw.sep(">", "PDB %s" % (method,))
tw.sep(">", "PDB {}".format(method))
_pdb = cls._import_pdb_cls(capman)(**kwargs)
@ -254,7 +249,7 @@ class pytestPDB(object):
_pdb.set_trace(frame)
class PdbInvoke(object):
class PdbInvoke:
def pytest_exception_interact(self, node, call, report):
capman = node.config.pluginmanager.getplugin("capturemanager")
if capman:
@ -269,7 +264,7 @@ class PdbInvoke(object):
post_mortem(tb)
class PdbTrace(object):
class PdbTrace:
@hookimpl(hookwrapper=True)
def pytest_pyfunc_call(self, pyfuncitem):
_test_pytest_function(pyfuncitem)

View File

@ -1,4 +1,3 @@
# -*- 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.
@ -9,10 +8,6 @@ be removed when the time comes.
All constants defined in this module should be either PytestWarning instances or UnformattedWarning
in case of warnings which need to format their messages.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from _pytest.warning_types import PytestDeprecationWarning
from _pytest.warning_types import RemovedInPytest4Warning
from _pytest.warning_types import UnformattedWarning

View File

@ -1,9 +1,4 @@
# -*- 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 platform
import sys
@ -126,7 +121,7 @@ class ReprFailDoctest(TerminalRepr):
class MultipleDoctestFailures(Exception):
def __init__(self, failures):
super(MultipleDoctestFailures, self).__init__()
super().__init__()
self.failures = failures
@ -181,7 +176,7 @@ def _get_runner(checker=None, verbose=None, optionflags=0, continue_on_failure=T
class DoctestItem(pytest.Item):
def __init__(self, name, parent, runner=None, dtest=None):
super(DoctestItem, self).__init__(name, parent)
super().__init__(name, parent)
self.runner = runner
self.dtest = dtest
self.obj = None
@ -258,7 +253,7 @@ class DoctestItem(pytest.Item):
]
indent = ">>>"
for line in example.source.splitlines():
lines.append("??? %s %s" % (indent, line))
lines.append("??? {} {}".format(indent, line))
indent = "..."
if isinstance(failure, doctest.DocTestFailure):
lines += checker.output_difference(
@ -271,7 +266,7 @@ class DoctestItem(pytest.Item):
reprlocation_lines.append((reprlocation, lines))
return ReprFailDoctest(reprlocation_lines)
else:
return super(DoctestItem, self).repr_failure(excinfo)
return super().repr_failure(excinfo)
def reportinfo(self):
return self.fspath, self.dtest.lineno, "[doctest] %s" % self.name

View File

@ -1,8 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import functools
import inspect
import itertools
@ -14,7 +9,6 @@ from collections import OrderedDict
import attr
import py
import six
import _pytest
from _pytest import nodes
@ -41,7 +35,7 @@ from _pytest.outcomes import TEST_OUTCOME
@attr.s(frozen=True)
class PseudoFixtureDef(object):
class PseudoFixtureDef:
cached_result = attr.ib()
scope = attr.ib()
@ -81,7 +75,7 @@ def scopeproperty(name=None, doc=None):
if func.__name__ in scope2props[self.scope]:
return func(self)
raise AttributeError(
"%s not available in %s-scoped context" % (scopename, self.scope)
"{} not available in {}-scoped context".format(scopename, self.scope)
)
return property(provide, None, None, func.__doc__)
@ -94,7 +88,7 @@ def get_scope_package(node, fixturedef):
cls = pytest.Package
current = node
fixture_package_name = "%s/%s" % (fixturedef.baseid, "__init__.py")
fixture_package_name = "{}/{}".format(fixturedef.baseid, "__init__.py")
while current and (
type(current) is not cls or fixture_package_name != current.nodeid
):
@ -301,7 +295,7 @@ def get_direct_param_fixture_func(request):
@attr.s(slots=True)
class FuncFixtureInfo(object):
class FuncFixtureInfo:
# original function argument names
argnames = attr.ib(type=tuple)
# argnames that function immediately requires. These include argnames +
@ -657,7 +651,7 @@ class SubRequest(FixtureRequest):
self._fixturemanager = request._fixturemanager
def __repr__(self):
return "<SubRequest %r for %r>" % (self.fixturename, self._pyfuncitem)
return "<SubRequest {!r} for {!r}>".format(self.fixturename, self._pyfuncitem)
def addfinalizer(self, finalizer):
self._fixturedef.addfinalizer(finalizer)
@ -670,7 +664,7 @@ class SubRequest(FixtureRequest):
fixturedef.addfinalizer(
functools.partial(self._fixturedef.finish, request=self)
)
super(SubRequest, self)._schedule_finalizers(fixturedef, subrequest)
super()._schedule_finalizers(fixturedef, subrequest)
scopes = "session package module class function".split()
@ -723,7 +717,7 @@ class FixtureLookupError(LookupError):
error_msg = "file %s, line %s: source code not available"
addline(error_msg % (fspath, lineno + 1))
else:
addline("file %s, line %s" % (fspath, lineno + 1))
addline("file {}, line {}".format(fspath, lineno + 1))
for i, line in enumerate(lines):
line = line.rstrip()
addline(" " + line)
@ -779,7 +773,7 @@ class FixtureLookupErrorRepr(TerminalRepr):
def fail_fixturefunc(fixturefunc, msg):
fs, lineno = getfslineno(fixturefunc)
location = "%s:%s" % (fs, lineno + 1)
location = "{}:{}".format(fs, lineno + 1)
source = _pytest._code.Source(fixturefunc)
fail(msg + ":\n\n" + str(source.indent()) + "\n" + location, pytrace=False)
@ -809,7 +803,7 @@ def _teardown_yield_fixture(fixturefunc, it):
)
class FixtureDef(object):
class FixtureDef:
""" A container for a factory definition. """
def __init__(
@ -853,10 +847,10 @@ class FixtureDef(object):
except: # noqa
exceptions.append(sys.exc_info())
if exceptions:
e = exceptions[0]
_, val, tb = exceptions[0]
# Ensure to not keep frame references through traceback.
del exceptions
six.reraise(*e)
raise val.with_traceback(tb)
finally:
hook = self._fixturemanager.session.gethookproxy(request.node.fspath)
hook.pytest_fixture_post_finalizer(fixturedef=self, request=request)
@ -882,7 +876,8 @@ class FixtureDef(object):
result, cache_key, err = cached_result
if my_cache_key == cache_key:
if err is not None:
six.reraise(*err)
_, val, tb = err
raise val.with_traceback(tb)
else:
return result
# we have a previous but differently parametrized fixture instance
@ -894,10 +889,8 @@ class FixtureDef(object):
return hook.pytest_fixture_setup(fixturedef=self, request=request)
def __repr__(self):
return "<FixtureDef argname=%r scope=%r baseid=%r>" % (
self.argname,
self.scope,
self.baseid,
return "<FixtureDef argname={!r} scope={!r} baseid={!r}>".format(
self.argname, self.scope, self.baseid
)
@ -957,7 +950,7 @@ def wrap_function_to_error_out_if_called_directly(function, fixture_marker):
name=fixture_marker.name or function.__name__
)
@six.wraps(function)
@functools.wraps(function)
def result(*args, **kwargs):
fail(message, pytrace=False)
@ -969,7 +962,7 @@ def wrap_function_to_error_out_if_called_directly(function, fixture_marker):
@attr.s(frozen=True)
class FixtureFunctionMarker(object):
class FixtureFunctionMarker:
scope = attr.ib()
params = attr.ib(converter=attr.converters.optional(tuple))
autouse = attr.ib(default=False)
@ -1083,7 +1076,7 @@ def pytest_addoption(parser):
)
class FixtureManager(object):
class FixtureManager:
"""
pytest fixtures definitions and information is stored and managed
from this class.

View File

@ -1,11 +1,7 @@
# -*- coding: utf-8 -*-
"""
Provides a function to report all internal modules for using freezing tools
pytest
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
def freeze_includes():

View File

@ -1,9 +1,4 @@
# -*- coding: utf-8 -*-
""" version info, help messages, tracing configuration. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import sys
from argparse import Action
@ -24,7 +19,7 @@ class HelpAction(Action):
"""
def __init__(self, option_strings, dest=None, default=False, help=None):
super(HelpAction, self).__init__(
super().__init__(
option_strings=option_strings,
dest=dest,
const=True,
@ -122,7 +117,7 @@ def pytest_cmdline_parse():
def showversion(config):
p = py.path.local(pytest.__file__)
sys.stderr.write(
"This is pytest version %s, imported from %s\n" % (pytest.__version__, p)
"This is pytest version {}, imported from {}\n".format(pytest.__version__, p)
)
plugininfo = getpluginversioninfo(config)
if plugininfo:
@ -160,7 +155,7 @@ def showhelp(config):
help, type, default = config._parser._inidict[name]
if type is None:
type = "string"
spec = "%s (%s):" % (name, type)
spec = "{} ({}):".format(name, type)
tw.write(" %s" % spec)
spec_len = len(spec)
if spec_len > (indent_len - 3):
@ -194,7 +189,7 @@ def showhelp(config):
("PYTEST_DEBUG", "set to enable debug tracing of pytest's internals"),
]
for name, help in vars:
tw.line(" %-24s %s" % (name, help))
tw.line(" {:<24} {}".format(name, help))
tw.line()
tw.line()
@ -221,7 +216,7 @@ def getpluginversioninfo(config):
lines.append("setuptools registered plugins:")
for plugin, dist in plugininfo:
loc = getattr(plugin, "__file__", repr(plugin))
content = "%s-%s at %s" % (dist.project_name, dist.version, loc)
content = "{}-{} at {}".format(dist.project_name, dist.version, loc)
lines.append(" " + content)
return lines
@ -229,7 +224,9 @@ def getpluginversioninfo(config):
def pytest_report_header(config):
lines = []
if config.option.debug or config.option.traceconfig:
lines.append("using: pytest-%s pylib-%s" % (pytest.__version__, py.__version__))
lines.append(
"using: pytest-{} pylib-{}".format(pytest.__version__, py.__version__)
)
verinfo = getpluginversioninfo(config)
if verinfo:
@ -243,5 +240,5 @@ def pytest_report_header(config):
r = plugin.__file__
else:
r = repr(plugin)
lines.append(" %-20s: %s" % (name, r))
lines.append(" {:<20}: {}".format(name, r))
return lines

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
""" hook specifications for pytest plugins, invoked from main.py and builtin plugins. """
from pluggy import HookspecMarker

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
report test results in JUnit-XML format,
for use with Jenkins and build integration servers.
@ -9,10 +8,6 @@ Based on initial code from Ross Lawley.
Output conforms to https://github.com/jenkinsci/xunit-plugin/blob/master/
src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import functools
import os
import re
@ -20,7 +15,6 @@ import sys
import time
import py
import six
import pytest
from _pytest import nodes
@ -39,12 +33,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))
"{}-{}".format(chr(low), chr(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 = [chr(x) for x in _legal_chars] + _legal_xml_re
illegal_xml_re = re.compile("[^%s]" % "".join(_legal_xml_re))
del _legal_chars
del _legal_ranges
del _legal_xml_re
@ -56,9 +50,9 @@ def bin_xml_escape(arg):
def repl(matchobj):
i = ord(matchobj.group())
if i <= 0xFF:
return u"#x%02X" % i
return "#x%02X" % i
else:
return u"#x%04X" % i
return "#x%04X" % i
return py.xml.raw(illegal_xml_re.sub(repl, py.xml.escape(arg)))
@ -85,7 +79,7 @@ merge_family(families["xunit1"], families["_base_legacy"])
families["xunit2"] = families["_base"]
class _NodeReporter(object):
class _NodeReporter:
def __init__(self, nodeid, xml):
self.id = nodeid
self.xml = xml
@ -225,7 +219,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, str):
message = report.longrepr
else:
message = str(report.longrepr)
@ -264,7 +258,7 @@ class _NodeReporter(object):
filename, lineno, skipreason = report.longrepr
if skipreason.startswith("Skipped: "):
skipreason = skipreason[9:]
details = "%s:%s: %s" % (filename, lineno, skipreason)
details = "{}:{}: {}".format(filename, lineno, skipreason)
self.append(
Junit.skipped(
@ -349,7 +343,7 @@ 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):
if not isinstance(v, str):
msg = "{param} parameter needs to be a string, but {g} given"
raise TypeError(msg.format(param=param, g=type(v).__name__))
@ -469,7 +463,7 @@ def mangle_test_address(address):
return names
class LogXML(object):
class LogXML:
def __init__(
self,
logfile,

View File

@ -1,15 +1,9 @@
# -*- coding: utf-8 -*-
""" Access and control log capturing. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import logging
import re
from contextlib import contextmanager
import py
import six
import pytest
from _pytest.compat import dummy_context_manager
@ -42,7 +36,7 @@ class ColoredLevelFormatter(logging.Formatter):
LEVELNAME_FMT_REGEX = re.compile(r"%\(levelname\)([+-.]?\d*s)")
def __init__(self, terminalwriter, *args, **kwargs):
super(ColoredLevelFormatter, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self._original_fmt = self._style._fmt
self._level_to_fmt_mapping = {}
@ -68,37 +62,34 @@ class ColoredLevelFormatter(logging.Formatter):
def format(self, record):
fmt = self._level_to_fmt_mapping.get(record.levelno, self._original_fmt)
self._style._fmt = fmt
return super(ColoredLevelFormatter, self).format(record)
return super().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.
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.
"""
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
@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 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):
@ -240,7 +231,7 @@ class LogCaptureHandler(logging.StreamHandler):
self.stream = py.io.TextIO()
class LogCaptureFixture(object):
class LogCaptureFixture:
"""Provides access and control of log capturing."""
def __init__(self, item):
@ -387,7 +378,7 @@ def get_actual_log_level(config, *setting_names):
else:
return
if isinstance(log_level, six.string_types):
if isinstance(log_level, str):
log_level = log_level.upper()
try:
return int(getattr(logging, log_level, log_level))
@ -406,7 +397,7 @@ def pytest_configure(config):
config.pluginmanager.register(LoggingPlugin(config), "logging-plugin")
class LoggingPlugin(object):
class LoggingPlugin:
"""Attaches to the logging module and captures log messages for each test.
"""
@ -469,8 +460,7 @@ class LoggingPlugin(object):
else:
formatter = logging.Formatter(log_format, log_date_format)
if not six.PY2:
formatter._style = PercentStyleMultiline(formatter._style._fmt)
formatter._style = PercentStyleMultiline(formatter._style._fmt)
return formatter
def _setup_cli_logging(self):

View File

@ -1,9 +1,4 @@
# -*- 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 fnmatch
import functools
import os
@ -13,7 +8,6 @@ import warnings
import attr
import py
import six
import _pytest._code
from _pytest import nodes
@ -171,7 +165,7 @@ def pytest_addoption(parser):
)
class _ConfigDeprecated(object):
class _ConfigDeprecated:
def __init__(self, config):
self.__dict__["_config"] = config
@ -310,10 +304,7 @@ def pytest_ignore_collect(path, config):
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
):
if any(fnmatch.fnmatch(str(path), str(glob)) for glob in ignore_globs):
return True
allow_in_venv = config.getoption("collect_in_virtualenv")
@ -341,7 +332,7 @@ def pytest_collection_modifyitems(items, config):
items[:] = remaining
class FSHookProxy(object):
class FSHookProxy:
def __init__(self, fspath, pm, remove_mods):
self.fspath = fspath
self.pm = pm
@ -481,8 +472,8 @@ class Session(nodes.FSCollector):
if self._notfound:
errors = []
for arg, exc in self._notfound:
line = "(no name %r in any of %r)" % (arg, exc.args[0])
errors.append("not found: %s\n%s" % (arg, line))
line = "(no name {!r} in any of {!r})".format(arg, exc.args[0])
errors.append("not found: {}\n{}".format(arg, line))
# XXX: test this
raise UsageError(*errors)
if not genitems:
@ -499,8 +490,7 @@ class Session(nodes.FSCollector):
self.trace("processing argument", arg)
self.trace.root.indent += 1
try:
for x in self._collect(arg):
yield x
yield from self._collect(arg)
except NoMatch:
# we are inside a make_report hook so
# we cannot directly pass through the exception
@ -537,7 +527,7 @@ class Session(nodes.FSCollector):
# If it's a directory argument, recurse and look for any Subpackages.
# Let the Package collector deal with subnodes, don't collect here.
if argpath.check(dir=1):
assert not names, "invalid arg %r" % (arg,)
assert not names, "invalid arg {!r}".format(arg)
seen_dirs = set()
for path in argpath.visit(
@ -582,15 +572,13 @@ class Session(nodes.FSCollector):
if argpath.basename == "__init__.py":
yield next(m[0].collect())
return
for y in m:
yield y
yield from m
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})".format(
path, path.isdir(), path.exists(), path.islink()
)
ihook = self.gethookproxy(path)
if not self.isinitpath(path):
@ -718,6 +706,5 @@ class Session(nodes.FSCollector):
rep = collect_one_node(node)
if rep.passed:
for subnode in rep.result:
for x in self.genitems(subnode):
yield x
yield from self.genitems(subnode)
node.ihook.pytest_collectreport(report=rep)

View File

@ -1,9 +1,4 @@
# -*- coding: utf-8 -*-
""" generic mechanism for marking and selecting python functions. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from .legacy import matchkeyword
from .legacy import matchmark
from .structures import EMPTY_PARAMETERSET_OPTION

View File

@ -1,11 +1,8 @@
# -*- coding: utf-8 -*-
import os
import platform
import sys
import traceback
import six
from ..outcomes import fail
from ..outcomes import TEST_OUTCOME
@ -23,7 +20,7 @@ def cached_eval(config, expr, d):
return x
class MarkEvaluator(object):
class MarkEvaluator:
def __init__(self, item, name):
self.item = item
self._marks = None
@ -87,7 +84,7 @@ class MarkEvaluator(object):
for expr in args:
self.expr = expr
if isinstance(expr, six.string_types):
if isinstance(expr, str):
d = self._getglobals()
result = cached_eval(self.item.config, expr, d)
else:

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
this is a place where we put datastructures used by legacy apis
we hope ot remove
@ -11,7 +10,7 @@ from _pytest.config import UsageError
@attr.s
class MarkMapping(object):
class MarkMapping:
"""Provides a local mapping for markers where item access
resolves to True if the marker is present. """
@ -26,7 +25,7 @@ class MarkMapping(object):
return name in self.own_mark_names
class KeywordMapping(object):
class KeywordMapping:
"""Provides a local mapping for keywords.
Given a list of names, map any substring of one of these names to True.
"""

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import inspect
import warnings
from collections import namedtuple
@ -6,7 +5,6 @@ from collections.abc import MutableMapping
from operator import attrgetter
import attr
import six
from ..compat import ascii_escaped
from ..compat import getfslineno
@ -72,7 +70,7 @@ class ParameterSet(namedtuple("ParameterSet", "values, marks, id")):
id_ = kwargs.pop("id", None)
if id_ is not None:
if not isinstance(id_, six.string_types):
if not isinstance(id_, str):
raise TypeError(
"Expected id to be a string, got {}: {!r}".format(type(id_), id_)
)
@ -158,7 +156,7 @@ class ParameterSet(namedtuple("ParameterSet", "values, marks, id")):
@attr.s(frozen=True)
class Mark(object):
class Mark:
#: name of the mark
name = attr.ib(type=str)
#: positional arguments of the mark decorator
@ -181,7 +179,7 @@ class Mark(object):
@attr.s
class MarkDecorator(object):
class MarkDecorator:
""" A decorator for test functions and test classes. When applied
it will create :class:`MarkInfo` objects which may be
:ref:`retrieved by hooks as item keywords <excontrolskip>`.
@ -229,7 +227,7 @@ class MarkDecorator(object):
return self.mark == other.mark if isinstance(other, MarkDecorator) else False
def __repr__(self):
return "<MarkDecorator %r>" % (self.mark,)
return "<MarkDecorator {!r}>".format(self.mark)
def with_args(self, *args, **kwargs):
""" return a MarkDecorator with extra arguments added
@ -290,7 +288,7 @@ def store_mark(obj, mark):
obj.pytestmark = get_unpacked_marks(obj) + [mark]
class MarkGenerator(object):
class MarkGenerator:
""" Factory for :class:`MarkDecorator` objects - exposed as
a ``pytest.mark`` singleton instance. Example::
@ -377,11 +375,11 @@ class NodeKeywords(MutableMapping):
return len(self._seen())
def __repr__(self):
return "<NodeKeywords for node %s>" % (self.node,)
return "<NodeKeywords for node {}>".format(self.node)
@attr.s(cmp=False, hash=False)
class NodeMarkers(object):
class NodeMarkers:
"""
internal structure for storing marks belonging to a node

View File

@ -1,17 +1,10 @@
# -*- coding: utf-8 -*-
""" monkeypatching and mocking functionality. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import re
import sys
import warnings
from contextlib import contextmanager
import six
import pytest
from _pytest.fixtures import fixture
from _pytest.pathlib import Path
@ -67,7 +60,7 @@ def resolve(name):
if expected == used:
raise
else:
raise ImportError("import error in %s: %s" % (used, ex))
raise ImportError("import error in {}: {}".format(used, ex))
found = annotated_getattr(found, part, used)
return found
@ -77,14 +70,18 @@ def annotated_getattr(obj, name, ann):
obj = getattr(obj, name)
except AttributeError:
raise AttributeError(
"%r object at %s has no attribute %r" % (type(obj).__name__, ann, name)
"{!r} object at {} has no attribute {!r}".format(
type(obj).__name__, ann, name
)
)
return obj
def derive_importpath(import_path, raising):
if not isinstance(import_path, six.string_types) or "." not in import_path:
raise TypeError("must be absolute import path string, not %r" % (import_path,))
if not isinstance(import_path, str) or "." not in import_path:
raise TypeError(
"must be absolute import path string, not {!r}".format(import_path)
)
module, attr = import_path.rsplit(".", 1)
target = resolve(module)
if raising:
@ -92,7 +89,7 @@ def derive_importpath(import_path, raising):
return attr, target
class Notset(object):
class Notset:
def __repr__(self):
return "<notset>"
@ -100,7 +97,7 @@ class Notset(object):
notset = Notset()
class MonkeyPatch(object):
class MonkeyPatch:
""" Object returned by the ``monkeypatch`` fixture keeping a record of setattr/item/env/syspath changes.
"""
@ -151,7 +148,7 @@ class MonkeyPatch(object):
import inspect
if value is notset:
if not isinstance(target, six.string_types):
if not isinstance(target, str):
raise TypeError(
"use setattr(target, name, value) or "
"setattr(target, value) with target being a dotted "
@ -162,7 +159,7 @@ class MonkeyPatch(object):
oldval = getattr(target, name, notset)
if raising and oldval is notset:
raise AttributeError("%r has no attribute %r" % (target, name))
raise AttributeError("{!r} has no attribute {!r}".format(target, name))
# avoid class descriptors like staticmethod/classmethod
if inspect.isclass(target):
@ -185,7 +182,7 @@ class MonkeyPatch(object):
import inspect
if name is notset:
if not isinstance(target, six.string_types):
if not isinstance(target, str):
raise TypeError(
"use delattr(target, name) or "
"delattr(target) with target being a dotted "

View File

@ -1,13 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import warnings
import py
import six
import _pytest._code
from _pytest.compat import getfslineno
@ -55,7 +49,7 @@ def ischildnode(baseid, nodeid):
return node_parts[: len(base_parts)] == base_parts
class Node(object):
class Node:
""" base class for Collector and Item the test collection tree.
Collector subclasses have children, Items are terminal nodes."""
@ -103,7 +97,7 @@ class Node(object):
return self.session.gethookproxy(self.fspath)
def __repr__(self):
return "<%s %s>" % (self.__class__.__name__, getattr(self, "name", None))
return "<{} {}>".format(self.__class__.__name__, getattr(self, "name", None))
def warn(self, warning):
"""Issue a warning for this item.
@ -173,7 +167,7 @@ class Node(object):
"""
from _pytest.mark import MarkDecorator, MARK_GEN
if isinstance(marker, six.string_types):
if isinstance(marker, str):
marker = getattr(MARK_GEN, marker)
elif not isinstance(marker, MarkDecorator):
raise ValueError("is not a string or pytest.mark.* Marker")
@ -244,7 +238,7 @@ class Node(object):
def _repr_failure_py(self, excinfo, style=None):
if excinfo.errisinstance(fail.Exception):
if not excinfo.value.pytrace:
return six.text_type(excinfo.value)
return str(excinfo.value)
fm = self.session._fixturemanager
if excinfo.errisinstance(fm.FixtureLookupError):
return excinfo.value.formatrepr()
@ -371,9 +365,7 @@ class FSCollector(Collector):
if nodeid and os.sep != SEP:
nodeid = nodeid.replace(os.sep, SEP)
super(FSCollector, self).__init__(
name, parent, config, session, nodeid=nodeid, fspath=fspath
)
super().__init__(name, parent, config, session, nodeid=nodeid, fspath=fspath)
class File(FSCollector):
@ -388,7 +380,7 @@ class Item(Node):
nextitem = None
def __init__(self, name, parent=None, config=None, session=None, nodeid=None):
super(Item, self).__init__(name, parent, config, session, nodeid=nodeid)
super().__init__(name, parent, config, session, nodeid=nodeid)
self._report_sections = []
#: user properties is a list of tuples (name, value) that holds user

View File

@ -1,13 +1,6 @@
# -*- coding: utf-8 -*-
""" run test suites written for nose. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import sys
import six
import pytest
from _pytest import python
from _pytest import runner
@ -28,7 +21,7 @@ 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
lambda: pytest.skip(str(call.excinfo.value)), call.when
)
call.excinfo = call2.excinfo

View File

@ -1,12 +1,7 @@
# -*- coding: utf-8 -*-
"""
exception classes and constants handling test outcomes
as well as functions creating them
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import sys
from packaging.version import Version
@ -28,7 +23,7 @@ class OutcomeException(BaseException):
if isinstance(val, bytes):
val = val.decode("UTF-8", errors="replace")
return val
return "<%s instance>" % (self.__class__.__name__,)
return "<{} instance>".format(self.__class__.__name__)
__str__ = __repr__
@ -58,7 +53,7 @@ class Exit(Exception):
def __init__(self, msg="unknown reason", returncode=None):
self.msg = msg
self.returncode = returncode
super(Exit, self).__init__(msg)
super().__init__(msg)
# exposed helper methods
@ -171,7 +166,7 @@ def importorskip(modname, minversion=None, reason=None):
import_exc = exc
if import_exc:
if reason is None:
reason = "could not import %r: %s" % (modname, import_exc)
reason = "could not import {!r}: {}".format(modname, import_exc)
raise Skipped(reason, allow_module_level=True)
mod = sys.modules[modname]
if minversion is None:

View File

@ -1,13 +1,6 @@
# -*- coding: utf-8 -*-
""" submit failure or test session information to a pastebin service. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import tempfile
import six
import pytest
@ -38,7 +31,7 @@ def pytest_configure(config):
def tee_write(s, **kwargs):
oldwrite(s, **kwargs)
if isinstance(s, six.text_type):
if isinstance(s, str):
s = s.encode("utf-8")
config._pastebinfile.write(s)
@ -77,7 +70,7 @@ def create_new_paste(contents):
response = urlopen(url, data=urlencode(params).encode("ascii")).read()
m = re.search(r'href="/raw/(\w+)"', response.decode("utf-8"))
if m:
return "%s/show/%s" % (url, m.group(1))
return "{}/show/{}".format(url, m.group(1))
else:
return "bad response: " + response
@ -102,4 +95,4 @@ def pytest_terminal_summary(terminalreporter):
s = tw.stringio.getvalue()
assert len(s)
pastebinurl = create_new_paste(s)
tr.write_line("%s --> %s" % (msg, pastebinurl))
tr.write_line("{} --> {}".format(msg, pastebinurl))

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import atexit
import errno
import fnmatch
@ -14,9 +13,6 @@ from os.path import isabs
from os.path import sep
from posixpath import sep as posix_sep
import six
from six.moves import map
if sys.version_info[:2] >= (3, 6):
from pathlib import Path, PurePath
@ -130,9 +126,10 @@ def create_cleanup_lock(p):
fd = os.open(str(lock_path), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644)
except OSError as e:
if e.errno == errno.EEXIST:
six.raise_from(
EnvironmentError("cannot create lockfile in {path}".format(path=p)), e
)
raise EnvironmentError(
"cannot create lockfile in {path}".format(path=p)
) from e
else:
raise
else:
@ -298,7 +295,7 @@ def fnmatch_ex(pattern, path):
if sep not in pattern:
name = path.name
else:
name = six.text_type(path)
name = str(path)
return fnmatch.fnmatch(name, pattern)

View File

@ -1,10 +1,4 @@
# -*- coding: utf-8 -*-
"""(disabled by default) support for testing pytest and pytest plugins."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import codecs
import gc
import os
import platform
@ -18,7 +12,6 @@ from fnmatch import fnmatch
from weakref import WeakKeyDictionary
import py
import six
import pytest
from _pytest._code import Source
@ -33,7 +26,7 @@ from _pytest.monkeypatch import MonkeyPatch
from _pytest.pathlib import Path
IGNORE_PAM = [ # filenames added when obtaining details about the current user
u"/var/lib/sss/mc/passwd"
"/var/lib/sss/mc/passwd"
]
@ -83,7 +76,7 @@ def raise_on_kwargs(kwargs):
)
class LsofFdLeakChecker(object):
class LsofFdLeakChecker:
def get_open_files(self):
out = self._exec_lsof()
open_files = self._parse_lsof_output(out)
@ -165,7 +158,7 @@ def _pytest(request):
return PytestArg(request)
class PytestArg(object):
class PytestArg:
def __init__(self, request):
self.request = request
@ -180,7 +173,7 @@ def get_public_names(values):
return [x for x in values if x[0] != "_"]
class ParsedCall(object):
class ParsedCall:
def __init__(self, name, kwargs):
self.__dict__.update(kwargs)
self._name = name
@ -188,10 +181,10 @@ class ParsedCall(object):
def __repr__(self):
d = self.__dict__.copy()
del d["_name"]
return "<ParsedCall %r(**%r)>" % (self._name, d)
return "<ParsedCall {!r}(**{!r})>".format(self._name, d)
class HookRecorder(object):
class HookRecorder:
"""Record all hooks called in a plugin manager.
This wraps all the hook calls in the plugin manager, recording each call
@ -238,7 +231,7 @@ class HookRecorder(object):
break
print("NONAMEMATCH", name, "with", call)
else:
pytest.fail("could not find %r check %r" % (name, check))
pytest.fail("could not find {!r} check {!r}".format(name, check))
def popcall(self, name):
__tracebackhide__ = True
@ -246,7 +239,7 @@ class HookRecorder(object):
if call._name == name:
del self.calls[i]
return call
lines = ["could not find call %r, in:" % (name,)]
lines = ["could not find call {!r}, in:".format(name)]
lines.extend([" %s" % x for x in self.calls])
pytest.fail("\n".join(lines))
@ -283,7 +276,9 @@ class HookRecorder(object):
)
if len(values) > 1:
raise ValueError(
"found 2 or more testreports matching %r: %s" % (inamepart, values)
"found 2 or more testreports matching {!r}: {}".format(
inamepart, values
)
)
return values[0]
@ -357,7 +352,7 @@ def _config_for_test():
rex_outcome = re.compile(r"(\d+) ([\w-]+)")
class RunResult(object):
class RunResult:
"""The result of running a command.
Attributes:
@ -429,7 +424,7 @@ class RunResult(object):
assert obtained == expected
class CwdSnapshot(object):
class CwdSnapshot:
def __init__(self):
self.__saved = os.getcwd()
@ -437,7 +432,7 @@ class CwdSnapshot(object):
os.chdir(self.__saved)
class SysModulesSnapshot(object):
class SysModulesSnapshot:
def __init__(self, preserve=None):
self.__preserve = preserve
self.__saved = dict(sys.modules)
@ -451,7 +446,7 @@ class SysModulesSnapshot(object):
sys.modules.update(self.__saved)
class SysPathsSnapshot(object):
class SysPathsSnapshot:
def __init__(self):
self.__saved = list(sys.path), list(sys.meta_path)
@ -459,7 +454,7 @@ class SysPathsSnapshot(object):
sys.path[:], sys.meta_path[:] = self.__saved
class Testdir(object):
class Testdir:
"""Temporary test directory with tools to test/run pytest itself.
This is based on the ``tmpdir`` fixture but provides a number of methods
@ -512,7 +507,7 @@ class Testdir(object):
self._env_run_update = {"HOME": tmphome, "USERPROFILE": tmphome}
def __repr__(self):
return "<Testdir %r>" % (self.tmpdir,)
return "<Testdir {!r}>".format(self.tmpdir)
def __str__(self):
return str(self.tmpdir)
@ -557,10 +552,10 @@ class Testdir(object):
items = list(kwargs.items())
def to_text(s):
return s.decode(encoding) if isinstance(s, bytes) else six.text_type(s)
return s.decode(encoding) if isinstance(s, bytes) else str(s)
if args:
source = u"\n".join(to_text(x) for x in args)
source = "\n".join(to_text(x) for x in args)
basename = self.request.function.__name__
items.insert(0, (basename, source))
@ -569,7 +564,7 @@ class Testdir(object):
p = self.tmpdir.join(basename).new(ext=ext)
p.dirpath().ensure_dir()
source = Source(value)
source = u"\n".join(to_text(line) for line in source.lines)
source = "\n".join(to_text(line) for line in source.lines)
p.write(source.strip().encode(encoding), "wb")
if ret is None:
ret = p
@ -838,7 +833,7 @@ class Testdir(object):
rec = []
class Collect(object):
class Collect:
def pytest_configure(x, config):
rec.append(self.make_hook_recorder(config.pluginmanager))
@ -848,7 +843,7 @@ class Testdir(object):
reprec = rec.pop()
else:
class reprec(object):
class reprec:
pass
reprec.ret = ret
@ -880,13 +875,13 @@ class Testdir(object):
reprec = self.inline_run(*args, **kwargs)
except SystemExit as e:
class reprec(object):
class reprec:
ret = e.args[0]
except Exception:
traceback.print_exc()
class reprec(object):
class reprec:
ret = 3
finally:
@ -968,10 +963,8 @@ class Testdir(object):
for item in items:
if item.name == funcname:
return item
assert 0, "%r item not found in module:\n%s\nitems: %s" % (
funcname,
source,
items,
assert 0, "{!r} item not found in module:\n{}\nitems: {}".format(
funcname, source, items
)
def getitems(self, source):
@ -1095,8 +1088,8 @@ class Testdir(object):
p2 = self.tmpdir.join("stderr")
print("running:", *cmdargs)
print(" in:", py.path.local())
f1 = codecs.open(str(p1), "w", encoding="utf8")
f2 = codecs.open(str(p2), "w", encoding="utf8")
f1 = open(str(p1), "w", encoding="utf8")
f2 = open(str(p2), "w", encoding="utf8")
try:
now = time.time()
popen = self.popen(
@ -1131,8 +1124,8 @@ class Testdir(object):
finally:
f1.close()
f2.close()
f1 = codecs.open(str(p1), "r", encoding="utf8")
f2 = codecs.open(str(p2), "r", encoding="utf8")
f1 = open(str(p1), "r", encoding="utf8")
f2 = open(str(p2), "r", encoding="utf8")
try:
out = f1.read().splitlines()
err = f2.read().splitlines()
@ -1148,7 +1141,7 @@ class Testdir(object):
for line in lines:
print(line, file=fp)
except UnicodeEncodeError:
print("couldn't print to %s because of encoding" % (fp,))
print("couldn't print to {} because of encoding".format(fp))
def _getpytestargs(self):
return sys.executable, "-mpytest"
@ -1205,7 +1198,7 @@ class Testdir(object):
"""
basetemp = self.tmpdir.mkdir("temp-pexpect")
invoke = " ".join(map(str, self._getpytestargs()))
cmd = "%s --basetemp=%s %s" % (invoke, basetemp, string)
cmd = "{} --basetemp={} {}".format(invoke, basetemp, string)
return self.spawn(cmd, expect_timeout=expect_timeout)
def spawn(self, cmd, expect_timeout=10.0):
@ -1235,10 +1228,12 @@ 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{}".format(
saferepr(out)
)
class LineComp(object):
class LineComp:
def __init__(self):
self.stringio = py.io.TextIO()
@ -1256,7 +1251,7 @@ class LineComp(object):
return LineMatcher(lines1).fnmatch_lines(lines2)
class LineMatcher(object):
class LineMatcher:
"""Flexible matching of text.
This is a convenience class to test large texts like the output of
@ -1394,5 +1389,5 @@ class LineMatcher(object):
self._log(" and:", repr(nextline))
extralines.append(nextline)
else:
self._log("remains unmatched: %r" % (line,))
self._log("remains unmatched: {!r}".format(line))
pytest.fail(self._log_text)

View File

@ -1,9 +1,4 @@
# -*- coding: utf-8 -*-
""" Python test discovery, setup and run of test functions. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import collections
import enum
import fnmatch
@ -15,7 +10,6 @@ from functools import partial
from textwrap import dedent
import py
import six
import _pytest
from _pytest import deprecated
@ -54,8 +48,8 @@ def pyobj_property(name):
if node is not None:
return node.obj
doc = "python %s object this node was collected from (can be None)." % (
name.lower(),
doc = "python {} object this node was collected from (can be None).".format(
name.lower()
)
return property(get, None, None, doc)
@ -238,7 +232,7 @@ def pytest_make_parametrize_id(config, val, argname=None):
return None
class PyobjContext(object):
class PyobjContext:
module = pyobj_property("Module")
cls = pyobj_property("Class")
instance = pyobj_property("Instance")
@ -248,7 +242,7 @@ class PyobjMixin(PyobjContext):
_ALLOW_MARKERS = True
def __init__(self, *k, **kw):
super(PyobjMixin, self).__init__(*k, **kw)
super().__init__(*k, **kw)
@property
def obj(self):
@ -420,7 +414,7 @@ class PyCollector(PyobjMixin, nodes.Collector):
fixtureinfo.prune_dependency_tree()
for callspec in metafunc._calls:
subname = "%s[%s]" % (name, callspec.id)
subname = "{}[{}]".format(name, callspec.id)
yield Function(
name=subname,
parent=self,
@ -442,7 +436,7 @@ class Module(nodes.File, PyCollector):
self._inject_setup_module_fixture()
self._inject_setup_function_fixture()
self.session._fixturemanager.parsefactories(self)
return super(Module, self).collect()
return super().collect()
def _inject_setup_module_fixture(self):
"""Injects a hidden autouse, module scoped fixture into the collected module object
@ -605,11 +599,10 @@ 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})".format(
path, path.isdir(), path.exists(), path.islink()
)
ihook = self.gethookproxy(path)
if not self.isinitpath(path):
@ -656,8 +649,7 @@ class Package(Module):
continue
if is_file:
for x in self._collectfile(path):
yield x
yield from self._collectfile(path)
elif not path.isdir():
# Broken symlink or invalid/missing file.
continue
@ -799,7 +791,7 @@ class Instance(PyCollector):
def collect(self):
self.session._fixturemanager.parsefactories(self)
return super(Instance, self).collect()
return super().collect()
def newinstance(self):
self.obj = self._getobj()
@ -857,7 +849,7 @@ def hasnew(obj):
return new != object.__new__
class CallSpec2(object):
class CallSpec2:
def __init__(self, metafunc):
self.metafunc = metafunc
self.funcargs = {}
@ -883,7 +875,7 @@ class CallSpec2(object):
def _checkargnotcontained(self, arg):
if arg in self.params or arg in self.funcargs:
raise ValueError("duplicate %r" % (arg,))
raise ValueError("duplicate {!r}".format(arg))
def getparam(self, name):
try:
@ -1059,7 +1051,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
msg = "In {}: {} parameter sets specified, with different number of ids: {}"
fail(msg.format(func_name, len(parameters), len(ids)), pytrace=False)
for id_value in ids:
if id_value is not None and not isinstance(id_value, six.string_types):
if id_value is not None and not isinstance(id_value, str):
msg = "In {}: ids must be list of strings, found: {} (type: {!r})"
fail(
msg.format(func_name, saferepr(id_value), type(id_value)),
@ -1182,7 +1174,7 @@ def _idval(val, argname, idx, idfn, item, config):
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)
raise ValueError(msg) from e
elif config:
hook_id = config.hook.pytest_make_parametrize_id(
config=config, val=val, argname=argname
@ -1334,7 +1326,7 @@ def _showfixtures_main(config, session):
if currentmodule != module:
if not module.startswith("_pytest."):
tw.line()
tw.sep("-", "fixtures defined from %s" % (module,))
tw.sep("-", "fixtures defined from {}".format(module))
currentmodule = module
if verbose <= 0 and argname[0] == "_":
continue
@ -1349,7 +1341,7 @@ def _showfixtures_main(config, session):
if doc:
write_docstring(tw, doc)
else:
tw.line(" %s: no docstring available" % (loc,), red=True)
tw.line(" {}: no docstring available".format(loc), red=True)
tw.line()
@ -1389,7 +1381,7 @@ class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr):
fixtureinfo=None,
originalname=None,
):
super(Function, self).__init__(name, parent, config=config, session=session)
super().__init__(name, parent, config=config, session=session)
self._args = args
if callobj is not NOTSET:
self.obj = callobj
@ -1463,7 +1455,7 @@ class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr):
self.ihook.pytest_pyfunc_call(pyfuncitem=self)
def setup(self):
super(Function, self).setup()
super().setup()
fixtures.fillfixtures(self)

View File

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
import math
import pprint
import sys
@ -9,11 +6,10 @@ from collections.abc import Iterable
from collections.abc import Mapping
from collections.abc import Sized
from decimal import Decimal
from itertools import filterfalse
from numbers import Number
from more_itertools.more import always_iterable
from six.moves import filterfalse
from six.moves import zip
import _pytest._code
from _pytest import deprecated
@ -50,7 +46,7 @@ def _non_numeric_type_error(value, at):
# builtin pytest.approx helper
class ApproxBase(object):
class ApproxBase:
"""
Provide shared utilities for making approximate comparisons between numbers
or sequences of numbers.
@ -710,7 +706,7 @@ def raises(expected_exception, *args, **kwargs):
raises.Exception = fail.Exception
class RaisesContext(object):
class RaisesContext:
def __init__(self, expected_exception, message, match_expr):
self.expected_exception = expected_exception
self.message = message

View File

@ -1,9 +1,4 @@
# -*- coding: utf-8 -*-
""" recording warnings during test function execution. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import inspect
import re
import sys
@ -115,7 +110,7 @@ class WarningsRecorder(warnings.catch_warnings):
"""
def __init__(self):
super(WarningsRecorder, self).__init__(record=True)
super().__init__(record=True)
self._entered = False
self._list = []
@ -152,7 +147,7 @@ class WarningsRecorder(warnings.catch_warnings):
if self._entered:
__tracebackhide__ = True
raise RuntimeError("Cannot enter %r twice" % self)
self._list = super(WarningsRecorder, self).__enter__()
self._list = super().__enter__()
warnings.simplefilter("always")
return self
@ -161,7 +156,7 @@ class WarningsRecorder(warnings.catch_warnings):
__tracebackhide__ = True
raise RuntimeError("Cannot exit %r without entering first" % self)
super(WarningsRecorder, self).__exit__(*exc_info)
super().__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.
@ -170,7 +165,7 @@ class WarningsRecorder(warnings.catch_warnings):
class WarningsChecker(WarningsRecorder):
def __init__(self, expected_warning=None, match_expr=None):
super(WarningsChecker, self).__init__()
super().__init__()
msg = "exceptions must be old-style classes or derived from Warning, not %s"
if isinstance(expected_warning, tuple):
@ -186,7 +181,7 @@ class WarningsChecker(WarningsRecorder):
self.match_expr = match_expr
def __exit__(self, *exc_info):
super(WarningsChecker, self).__exit__(*exc_info)
super().__exit__(*exc_info)
__tracebackhide__ = True

View File

@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
from pprint import pprint
import py
import six
from _pytest._code.code import ExceptionInfo
from _pytest._code.code import ReprEntry
@ -23,16 +21,13 @@ def getslaveinfoline(node):
except AttributeError:
d = node.slaveinfo
ver = "%s.%s.%s" % d["version_info"][:3]
node._slaveinfocache = s = "[%s] %s -- Python %s %s" % (
d["id"],
d["sysplatform"],
ver,
d["executable"],
node._slaveinfocache = s = "[{}] {} -- Python {} {}".format(
d["id"], d["sysplatform"], ver, d["executable"]
)
return s
class BaseReport(object):
class BaseReport:
when = None
location = None
@ -195,7 +190,7 @@ class BaseReport(object):
):
d["longrepr"] = disassembled_report(self)
else:
d["longrepr"] = six.text_type(self.longrepr)
d["longrepr"] = str(self.longrepr)
else:
d["longrepr"] = self.longrepr
for name in d:
@ -335,11 +330,8 @@ class TestReport(BaseReport):
self.__dict__.update(extra)
def __repr__(self):
return "<%s %r when=%r outcome=%r>" % (
self.__class__.__name__,
self.nodeid,
self.when,
self.outcome,
return "<{} {!r} when={!r} outcome={!r}>".format(
self.__class__.__name__, self.nodeid, self.when, self.outcome
)
@classmethod
@ -372,7 +364,7 @@ class TestReport(BaseReport):
excinfo, style=item.config.getoption("tbstyle", "auto")
)
for rwhen, key, content in item._report_sections:
sections.append(("Captured %s %s" % (key, rwhen), content))
sections.append(("Captured {} {}".format(key, rwhen), content))
return cls(
item.nodeid,
item.location,
@ -402,10 +394,8 @@ class CollectReport(BaseReport):
return (self.fspath, None, self.fspath)
def __repr__(self):
return "<CollectReport %r lenresult=%s outcome=%r>" % (
self.nodeid,
len(self.result),
self.outcome,
return "<CollectReport {!r} lenresult={} outcome={!r}>".format(
self.nodeid, len(self.result), self.outcome
)

View File

@ -1,11 +1,6 @@
# -*- coding: utf-8 -*-
""" log machine-parseable test session result information in a plain
text file.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import py
@ -48,13 +43,13 @@ def pytest_unconfigure(config):
config.pluginmanager.unregister(resultlog)
class ResultLog(object):
class ResultLog:
def __init__(self, config, logfile):
self.config = config
self.logfile = logfile # preferably line buffered
def write_log_entry(self, testpath, lettercode, longrepr):
print("%s %s" % (lettercode, testpath), file=self.logfile)
print("{} {}".format(lettercode, testpath), file=self.logfile)
for line in longrepr.splitlines():
print(" %s" % line, file=self.logfile)

View File

@ -1,16 +1,10 @@
# -*- coding: utf-8 -*-
""" basic collect and runtest protocol implementations """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import bdb
import os
import sys
from time import time
import attr
import six
from .reports import CollectErrorRepr
from .reports import CollectReport
@ -62,7 +56,7 @@ def pytest_terminal_summary(terminalreporter):
tr.write_line("")
tr.write_line("(0.00 durations hidden. Use -vv to show these durations.)")
break
tr.write_line("%02.2fs %-8s %s" % (rep.duration, rep.when, rep.nodeid))
tr.write_line("{:02.2f}s {:<8} {}".format(rep.duration, rep.when, rep.nodeid))
def pytest_sessionstart(session):
@ -200,7 +194,7 @@ def call_runtest_hook(item, when, **kwds):
@attr.s(repr=False)
class CallInfo(object):
class CallInfo:
""" Result/Exception info a function invocation. """
_result = attr.ib()
@ -275,7 +269,7 @@ def pytest_make_collect_report(collector):
return rep
class SetupState(object):
class SetupState:
""" shared state for setting up/tearing down test items or collectors. """
def __init__(self):
@ -309,7 +303,8 @@ class SetupState(object):
if exc is None:
exc = sys.exc_info()
if exc:
six.reraise(*exc)
_, val, tb = exc
raise val.with_traceback(tb)
def _teardown_with_finalization(self, colitem):
self._callfinalizers(colitem)
@ -344,7 +339,8 @@ class SetupState(object):
if exc is None:
exc = sys.exc_info()
if exc:
six.reraise(*exc)
_, val, tb = exc
raise val.with_traceback(tb)
def prepare(self, colitem):
""" setup objects along the collector chain to the test-method
@ -355,7 +351,8 @@ class SetupState(object):
# check if the last collection node has raised an error
for col in self.stack:
if hasattr(col, "_prepare_exc"):
six.reraise(*col._prepare_exc)
_, val, tb = col._prepare_exc
raise val.with_traceback(tb)
for col in needed_collectors[len(self.stack) :]:
self.stack.append(col)
try:

View File

@ -1,8 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import sys
import pytest

View File

@ -1,8 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import pytest

View File

@ -1,9 +1,4 @@
# -*- coding: utf-8 -*-
""" support for skip/xfail functions and markers. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from _pytest.config import hookimpl
from _pytest.mark.evaluate import MarkEvaluator
from _pytest.outcomes import fail

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import pytest

View File

@ -1,12 +1,7 @@
# -*- coding: utf-8 -*-
""" terminal reporting of the full testing process.
This is a good source for looking at the various reporting hooks.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import collections
import platform
@ -17,7 +12,6 @@ from functools import partial
import attr
import pluggy
import py
import six
from more_itertools import collapse
import pytest
@ -40,7 +34,7 @@ class MoreQuietAction(argparse.Action):
"""
def __init__(self, option_strings, dest, default=None, required=False, help=None):
super(MoreQuietAction, self).__init__(
super().__init__(
option_strings=option_strings,
dest=dest,
nargs=0,
@ -191,7 +185,7 @@ def pytest_report_teststatus(report):
@attr.s
class WarningReport(object):
class WarningReport:
"""
Simple structure to hold warnings information captured by ``pytest_warning_captured``.
@ -219,13 +213,13 @@ class WarningReport(object):
relpath = py.path.local(filename).relto(config.invocation_dir)
if not relpath:
relpath = str(filename)
return "%s:%s" % (relpath, linenum)
return "{}:{}".format(relpath, linenum)
else:
return str(self.fslocation)
return None
class TerminalReporter(object):
class TerminalReporter:
def __init__(self, config, file=None):
import _pytest.config
@ -320,8 +314,8 @@ class TerminalReporter(object):
self._tw.write(content, **markup)
def write_line(self, line, **markup):
if not isinstance(line, six.text_type):
line = six.text_type(line, errors="replace")
if not isinstance(line, str):
line = str(line, errors="replace")
self.ensure_newline()
self._tw.line(line, **markup)
@ -354,7 +348,7 @@ class TerminalReporter(object):
self._tw.line(msg, **kw)
def pytest_internalerror(self, excrepr):
for line in six.text_type(excrepr).split("\n"):
for line in str(excrepr).split("\n"):
self.write_line("INTERNALERROR> " + line)
return 1
@ -374,7 +368,7 @@ class TerminalReporter(object):
def pytest_plugin_registered(self, plugin):
if self.config.option.traceconfig:
msg = "PLUGIN registered: %s" % (plugin,)
msg = "PLUGIN registered: {}".format(plugin)
# XXX this event may happen during setup/teardown time
# which unfortunately captures our output here
# which garbles our output if we use self.write_line
@ -561,14 +555,12 @@ class TerminalReporter(object):
return
self.write_sep("=", "test session starts", bold=True)
verinfo = platform.python_version()
msg = "platform %s -- Python %s" % (sys.platform, verinfo)
msg = "platform {} -- Python {}".format(sys.platform, verinfo)
if hasattr(sys, "pypy_version_info"):
verinfo = ".".join(map(str, sys.pypy_version_info[:3]))
msg += "[pypy-%s-%s]" % (verinfo, sys.pypy_version_info[3])
msg += ", pytest-%s, py-%s, pluggy-%s" % (
pytest.__version__,
py.__version__,
pluggy.__version__,
msg += "[pypy-{}-{}]".format(verinfo, sys.pypy_version_info[3])
msg += ", pytest-{}, py-{}, pluggy-{}".format(
pytest.__version__, py.__version__, pluggy.__version__
)
if (
self.verbosity > 0
@ -650,11 +642,11 @@ class TerminalReporter(object):
if col.name == "()": # Skip Instances.
continue
indent = (len(stack) - 1) * " "
self._tw.line("%s%s" % (indent, col))
self._tw.line("{}{}".format(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()))
self._tw.line("{}{}".format(indent + " ", line.strip()))
@pytest.hookimpl(hookwrapper=True)
def pytest_sessionfinish(self, exitstatus):
@ -854,7 +846,7 @@ class TerminalReporter(object):
if rep.when == "collect":
msg = "ERROR collecting " + msg
else:
msg = "ERROR at %s of %s" % (rep.when, msg)
msg = "ERROR at {} of {}".format(rep.when, msg)
self.write_sep("_", msg, red=True, bold=True)
self._outrep_summary(rep)
@ -874,7 +866,7 @@ class TerminalReporter(object):
def summary_stats(self):
session_duration = time.time() - self._sessionstarttime
(line, color) = build_summary_stats_line(self.stats)
msg = "%s in %.2f seconds" % (line, session_duration)
msg = "{} in {:.2f} seconds".format(line, session_duration)
markup = {color: True, "bold": True}
if self.verbosity >= 0:
@ -901,7 +893,7 @@ class TerminalReporter(object):
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))
lines.append("{} {}".format(verbose_word, pos))
reason = rep.wasxfail
if reason:
lines.append(" " + str(reason))
@ -912,7 +904,7 @@ class TerminalReporter(object):
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))
lines.append("{} {} {}".format(verbose_word, pos, reason))
def show_skipped(lines):
skipped = self.stats.get("skipped", [])
@ -966,7 +958,7 @@ def _get_line_with_reprcrash_message(config, rep, termwidth):
verbose_word = rep._get_verbose_word(config)
pos = _get_pos(config, rep)
line = "%s %s" % (verbose_word, pos)
line = "{} {}".format(verbose_word, pos)
len_line = wcswidth(line)
ellipsis, len_ellipsis = "...", 3
if len_line > termwidth - len_ellipsis:

View File

@ -1,9 +1,4 @@
# -*- coding: utf-8 -*-
""" support for providing temporary directories to test functions. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import re
import tempfile
@ -22,7 +17,7 @@ from _pytest.monkeypatch import MonkeyPatch
@attr.s
class TempPathFactory(object):
class TempPathFactory:
"""Factory for temporary directories under the common base temp directory.
The base directory can be configured using the ``--basetemp`` option."""
@ -82,7 +77,7 @@ class TempPathFactory(object):
@attr.s
class TempdirFactory(object):
class TempdirFactory:
"""
backward comptibility wrapper that implements
:class:``py.path.local`` for :class:``TempPathFactory``

View File

@ -1,9 +1,4 @@
# -*- coding: utf-8 -*-
""" discovery and running of std-library "unittest" style tests. """
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import sys
import traceback

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import attr
@ -95,7 +94,7 @@ class RemovedInPytest4Warning(PytestDeprecationWarning):
@attr.s
class UnformattedWarning(object):
class UnformattedWarning:
"""Used to hold warnings that need to format their message at runtime, as opposed to a direct message.
Using this class avoids to keep all the warning types and messages in this module, avoiding misuse.

View File

@ -1,8 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import sys
import warnings
from contextlib import contextmanager
@ -18,7 +13,7 @@ def _setoption(wmod, arg):
"""
parts = arg.split(":")
if len(parts) > 5:
raise wmod._OptionError("too many fields (max 5): %r" % (arg,))
raise wmod._OptionError("too many fields (max 5): {!r}".format(arg))
while len(parts) < 5:
parts.append("")
action, message, category, module, lineno = [s.strip() for s in parts]
@ -30,7 +25,7 @@ def _setoption(wmod, arg):
if lineno < 0:
raise ValueError
except (ValueError, OverflowError):
raise wmod._OptionError("invalid lineno %r" % (lineno,))
raise wmod._OptionError("invalid lineno {!r}".format(lineno))
else:
lineno = 0
wmod.filterwarnings(action, message, category, module, lineno)

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# PYTHON_ARGCOMPLETE_OK
"""
pytest: unit and functional testing with Python.

View File

@ -1,8 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import sys
import textwrap
@ -11,7 +6,6 @@ import types
import attr
import importlib_metadata
import py
import six
import pytest
from _pytest.main import EXIT_NOTESTSCOLLECTED
@ -26,7 +20,7 @@ def prepend_pythonpath(*dirs):
return os.pathsep.join(str(p) for p in dirs)
class TestGeneralUsage(object):
class TestGeneralUsage:
def test_config_error(self, testdir):
testdir.copy_example("conftest_usageerror/conftest.py")
result = testdir.runpytest(testdir.tmpdir)
@ -120,7 +114,7 @@ class TestGeneralUsage(object):
loaded = []
@attr.s
class DummyEntryPoint(object):
class DummyEntryPoint:
name = attr.ib()
module = attr.ib()
group = "pytest11"
@ -137,7 +131,7 @@ class TestGeneralUsage(object):
]
@attr.s
class DummyDist(object):
class DummyDist:
entry_points = attr.ib()
files = ()
@ -513,20 +507,19 @@ class TestGeneralUsage(object):
def test_parametrized_with_null_bytes(self, testdir):
"""Test parametrization with values that contain null bytes and unicode characters (#2644, #2957)"""
p = testdir.makepyfile(
u"""
# encoding: UTF-8
"""\
import pytest
@pytest.mark.parametrize("data", [b"\\x00", "\\x00", u'ação'])
def test_foo(data):
assert data
"""
"""
)
res = testdir.runpytest(p)
res.assert_outcomes(passed=3)
class TestInvocationVariants(object):
class TestInvocationVariants:
def test_earlyinit(self, testdir):
p = testdir.makepyfile(
"""
@ -623,7 +616,7 @@ class TestInvocationVariants(object):
out, err = capsys.readouterr()
def test_invoke_plugin_api(self, testdir, capsys):
class MyPlugin(object):
class MyPlugin:
def pytest_addoption(self, parser):
parser.addoption("--myopt")
@ -761,7 +754,7 @@ class TestInvocationVariants(object):
str(testdir.tmpdir.join("tmpfile2")),
)
except OSError as e:
pytest.skip(six.text_type(e.args[0]))
pytest.skip(str(e.args[0]))
monkeypatch.delenv("PYTHONDONTWRITEBYTECODE", raising=False)
dirname = "lib"
@ -876,7 +869,7 @@ class TestInvocationVariants(object):
assert request.config.pluginmanager.hasplugin("python")
class TestDurations(object):
class TestDurations:
source = """
import time
frag = 0.002
@ -954,7 +947,7 @@ class TestDurations(object):
assert result.ret == 0
class TestDurationWithFixture(object):
class TestDurationWithFixture:
source = """
import pytest
import time

View File

@ -1,12 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import sys
from unittest import mock
from six import text_type
from test_excinfo import TWMock
import _pytest._code
@ -30,7 +24,7 @@ def test_code_gives_back_name_for_not_existing_file():
def test_code_with_class():
class A(object):
class A:
pass
pytest.raises(TypeError, _pytest._code.Code, A)
@ -81,13 +75,13 @@ def test_code_from_func():
def test_unicode_handling():
value = u"ąć".encode("UTF-8")
value = "ąć".encode()
def f():
raise Exception(value)
excinfo = pytest.raises(Exception, f)
text_type(excinfo)
str(excinfo)
def test_code_getargs():
@ -142,7 +136,7 @@ def test_frame_getargs():
assert fr4.getargs(var=True) == [("x", "a"), ("y", ("b",)), ("z", {"c": "d"})]
class TestExceptionInfo(object):
class TestExceptionInfo:
def test_bad_getsource(self):
try:
if False:
@ -158,7 +152,7 @@ class TestExceptionInfo(object):
_pytest._code.ExceptionInfo.from_current()
class TestTracebackEntry(object):
class TestTracebackEntry:
def test_getsource(self):
try:
if False:
@ -173,13 +167,13 @@ class TestTracebackEntry(object):
assert "assert False" in source[5]
class TestReprFuncArgs(object):
class TestReprFuncArgs:
def test_not_raise_exception_with_mixed_encoding(self):
from _pytest._code.code import ReprFuncArgs
tw = TWMock()
args = [("unicode_string", u"São Paulo"), ("utf8_string", b"S\xc3\xa3o Paulo")]
args = [("unicode_string", "São Paulo"), ("utf8_string", b"S\xc3\xa3o Paulo")]
r = ReprFuncArgs(args)
r.toterminal(tw)

View File

@ -1,16 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import operator
import os
import queue
import sys
import textwrap
import py
import six
from six.moves import queue
import _pytest
import pytest
@ -37,7 +31,7 @@ def limited_recursion_depth():
sys.setrecursionlimit(before)
class TWMock(object):
class TWMock:
WRITE = object()
def __init__(self):
@ -118,7 +112,7 @@ def h():
#
class TestTraceback_f_g_h(object):
class TestTraceback_f_g_h:
def setup_method(self, method):
try:
h()
@ -257,7 +251,7 @@ class TestTraceback_f_g_h(object):
import sys
exc, val, tb = sys.exc_info()
six.reraise(exc, val, tb)
raise val.with_traceback(tb)
def f(n):
try:
@ -434,7 +428,7 @@ def test_match_raises_error(testdir):
result.stdout.fnmatch_lines(["*AssertionError*Pattern*[123]*not found*"])
class TestFormattedExcinfo(object):
class TestFormattedExcinfo:
@pytest.fixture
def importasmod(self, request, _sys_snapshot):
def importasmod(source):
@ -520,8 +514,8 @@ raise ValueError()
def test_repr_source_failing_fullsource(self):
pr = FormattedExcinfo()
class FakeCode(object):
class raw(object):
class FakeCode:
class raw:
co_filename = "?"
path = "?"
@ -532,7 +526,7 @@ raise ValueError()
fullsource = property(fullsource)
class FakeFrame(object):
class FakeFrame:
code = FakeCode()
f_locals = {}
f_globals = {}
@ -563,7 +557,7 @@ raise ValueError()
excinfo = FakeExcinfo()
class FakeRawTB(object):
class FakeRawTB:
tb_next = None
tb = FakeRawTB()
@ -920,10 +914,10 @@ raise ValueError()
class MyRepr(TerminalRepr):
def toterminal(self, tw):
tw.line(u"я")
tw.line("я")
x = six.text_type(MyRepr())
assert x == u"я"
x = str(MyRepr())
assert x == "я"
def test_toterminal_long(self, importasmod):
mod = importasmod(
@ -1356,7 +1350,7 @@ raise ValueError()
@pytest.mark.parametrize("style", ["short", "long"])
@pytest.mark.parametrize("encoding", [None, "utf8", "utf16"])
def test_repr_traceback_with_unicode(style, encoding):
msg = u""
msg = ""
if encoding is not None:
msg = msg.encode(encoding)
try:
@ -1390,7 +1384,7 @@ def test_exception_repr_extraction_error_on_recursion():
"""
from _pytest.pytester import LineMatcher
class numpy_like(object):
class numpy_like:
def __eq__(self, other):
if type(other) is numpy_like:
raise ValueError(
@ -1424,7 +1418,7 @@ def test_no_recursion_index_on_recursion_error():
during a recursion error (#2486).
"""
class RecursionDepthError(object):
class RecursionDepthError:
def __getattr__(self, attr):
return getattr(self, "_" + attr)

View File

@ -1,17 +1,10 @@
# -*- coding: utf-8 -*-
# flake8: noqa
# disable flake check on this file because some constructs are strange
# or redundant on purpose and can't be disable on a line-by-line basis
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import ast
import inspect
import sys
import six
import _pytest._code
import pytest
from _pytest._code import Source
@ -33,11 +26,11 @@ def test_source_str_function():
def test_unicode():
x = Source(u"4")
x = Source("4")
assert str(x) == "4"
co = _pytest._code.compile(u'u"å"', mode="eval")
co = _pytest._code.compile('u"å"', mode="eval")
val = eval(co)
assert isinstance(val, six.text_type)
assert isinstance(val, str)
def test_source_from_function():
@ -46,7 +39,7 @@ def test_source_from_function():
def test_source_from_method():
class TestClass(object):
class TestClass:
def test_method(self):
pass
@ -120,7 +113,7 @@ def test_source_strip_multiline():
def test_syntaxerror_rerepresentation():
ex = pytest.raises(SyntaxError, _pytest._code.compile, "xyz xyz")
assert ex.value.lineno == 1
assert ex.value.offset == 7
assert ex.value.offset in {5, 7} # cpython: 7, pypy3.6 7.1.1: 5
assert ex.value.text.strip(), "x x"
@ -133,7 +126,7 @@ def test_isparseable():
assert not Source(chr(0)).isparseable()
class TestAccesses(object):
class TestAccesses:
source = Source(
"""\
def f(x):
@ -161,7 +154,7 @@ class TestAccesses(object):
assert len(values) == 4
class TestSourceParsingAndCompiling(object):
class TestSourceParsingAndCompiling:
source = Source(
"""\
def f(x):
@ -338,7 +331,7 @@ class TestSourceParsingAndCompiling(object):
def test_getstartingblock_singleline():
class A(object):
class A:
def __init__(self, *args):
frame = sys._getframe(1)
self.source = _pytest._code.Frame(frame).statement
@ -485,7 +478,7 @@ def test_getfslineno():
assert fspath.basename == "test_source.py"
assert lineno == _pytest._code.getrawcode(f).co_firstlineno - 1 # see findsource
class A(object):
class A:
pass
fspath, lineno = getfslineno(A)
@ -496,7 +489,7 @@ def test_getfslineno():
assert getfslineno(3) == ("", -1)
class B(object):
class B:
pass
B.__name__ = "B2"
@ -504,19 +497,19 @@ def test_getfslineno():
def test_code_of_object_instance_with_call():
class A(object):
class A:
pass
pytest.raises(TypeError, lambda: _pytest._code.Source(A()))
class WithCall(object):
class WithCall:
def __call__(self):
pass
code = _pytest._code.Code(WithCall())
assert "pass" in str(code.source())
class Hello(object):
class Hello:
def __call__(self):
pass
@ -625,7 +618,7 @@ x = 3
assert str(source) == "raise ValueError(\n 23\n)"
class TestTry(object):
class TestTry:
source = """\
try:
raise ValueError
@ -652,7 +645,7 @@ else:
assert str(source) == " raise KeyError()"
class TestTryFinally(object):
class TestTryFinally:
source = """\
try:
raise ValueError
@ -669,7 +662,7 @@ finally:
assert str(source) == " raise IndexError(1)"
class TestIf(object):
class TestIf:
source = """\
if 1:
y = 3
@ -725,7 +718,7 @@ something
def test_getstartingblock_multiline():
class A(object):
class A:
def __init__(self, *args):
frame = sys._getframe(1)
self.source = _pytest._code.Frame(frame).statement

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
import pytest

View File

@ -1,8 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import pytest

View File

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""Reproduces issue #3774"""
from unittest import mock

View File

@ -1,3 +1,2 @@
# -*- coding: utf-8 -*-
def test_init():
pass

View File

@ -1,3 +1,2 @@
# -*- coding: utf-8 -*-
def test_foo():
pass

View File

@ -1,3 +1,2 @@
# -*- coding: utf-8 -*-
def pytest_ignore_collect(path):
return False

View File

@ -1,3 +1,2 @@
# -*- coding: utf-8 -*-
def test():
pass

View File

@ -1,3 +1,2 @@
# -*- coding: utf-8 -*-
def test():
pass

View File

@ -1,3 +1,2 @@
# -*- coding: utf-8 -*-
class pytest_something(object):
class pytest_something:
pass

Some files were not shown because too many files have changed in this diff Show More