diff --git a/bench/empty.py b/bench/empty.py index b90319936..338ebf138 100644 --- a/bench/empty.py +++ b/bench/empty.py @@ -1,4 +1,4 @@ -import py +import six for i in range(1000): - py.builtin.exec_("def test_func_%d(): pass" % i) + six.exec_("def test_func_%d(): pass" % i) diff --git a/changelog/3848.bugfix.rst b/changelog/3848.bugfix.rst new file mode 100644 index 000000000..4442d7a89 --- /dev/null +++ b/changelog/3848.bugfix.rst @@ -0,0 +1 @@ +Fix bugs where unicode arguments could not be passed to ``testdir.runpytest`` on Python 2. diff --git a/doc/en/example/assertion/failure_demo.py b/doc/en/example/assertion/failure_demo.py index 0a104578c..def6ae2ef 100644 --- a/doc/en/example/assertion/failure_demo.py +++ b/doc/en/example/assertion/failure_demo.py @@ -1,6 +1,6 @@ from pytest import raises import _pytest._code -import py +import six def otherfunc(a, b): @@ -177,7 +177,7 @@ def test_dynamic_compile_shows_nicely(): name = "abc-123" module = imp.new_module(name) code = _pytest._code.compile(src, name, "exec") - py.builtin.exec_(code, module.__dict__) + six.exec_(code, module.__dict__) sys.modules[name] = module module.foo() diff --git a/doc/en/example/assertion/global_testmodule_config/conftest.py b/doc/en/example/assertion/global_testmodule_config/conftest.py index 4859bea78..3597ec06d 100644 --- a/doc/en/example/assertion/global_testmodule_config/conftest.py +++ b/doc/en/example/assertion/global_testmodule_config/conftest.py @@ -10,4 +10,4 @@ def pytest_runtest_setup(item): return mod = item.getparent(pytest.Module).obj if hasattr(mod, "hello"): - print("mod.hello %r" % (mod.hello,)) + print("mod.hello {!r}".format(mod.hello)) diff --git a/doc/en/example/multipython.py b/doc/en/example/multipython.py index 299833f71..5e12c9b03 100644 --- a/doc/en/example/multipython.py +++ b/doc/en/example/multipython.py @@ -2,9 +2,10 @@ module containing a parametrized tests testing cross-python serialization via the pickle module. """ +import textwrap + import py import pytest -import _pytest._code pythonlist = ["python2.7", "python3.4", "python3.5"] @@ -24,42 +25,44 @@ class Python(object): def __init__(self, version, picklefile): self.pythonpath = py.path.local.sysfind(version) if not self.pythonpath: - pytest.skip("%r not found" % (version,)) + pytest.skip("{!r} not found".format(version)) self.picklefile = picklefile def dumps(self, obj): dumpfile = self.picklefile.dirpath("dump.py") dumpfile.write( - _pytest._code.Source( - """ - import pickle - f = open(%r, 'wb') - s = pickle.dump(%r, f, protocol=2) - f.close() - """ - % (str(self.picklefile), obj) + textwrap.dedent( + """\ + import pickle + f = open({!r}, 'wb') + s = pickle.dump({!r}, f, protocol=2) + f.close() + """.format( + str(self.picklefile), obj + ) ) ) - py.process.cmdexec("%s %s" % (self.pythonpath, dumpfile)) + py.process.cmdexec("{} {}".format(self.pythonpath, dumpfile)) def load_and_is_true(self, expression): loadfile = self.picklefile.dirpath("load.py") loadfile.write( - _pytest._code.Source( - """ - import pickle - f = open(%r, 'rb') - obj = pickle.load(f) - f.close() - res = eval(%r) - if not res: - raise SystemExit(1) - """ - % (str(self.picklefile), expression) + textwrap.dedent( + """\ + import pickle + f = open({!r}, 'rb') + obj = pickle.load(f) + f.close() + res = eval({!r}) + if not res: + raise SystemExit(1) + """.format( + str(self.picklefile), expression + ) ) ) print(loadfile) - py.process.cmdexec("%s %s" % (self.pythonpath, loadfile)) + py.process.cmdexec("{} {}".format(self.pythonpath, loadfile)) @pytest.mark.parametrize("obj", [42, {}, {1: 3}]) diff --git a/doc/en/goodpractices.rst b/doc/en/goodpractices.rst index d9c685299..87d446d0d 100644 --- a/doc/en/goodpractices.rst +++ b/doc/en/goodpractices.rst @@ -4,6 +4,28 @@ Good Integration Practices ================================================= +Install package with pip +------------------------------------------------- + +For development, we recommend to use virtualenv_ environments and pip_ +for installing your application and any dependencies +as well as the ``pytest`` package itself. This ensures your code and +dependencies are isolated from the system Python installation. + +First you need to place a ``setup.py`` file in the root of your package with the following minimum content: + + from setuptools import setup, find_packages + + + setup(name="PACKAGENAME", packages=find_packages()) + +Where ``PACKAGENAME`` is the name of your package. You can then install your package in "editable" mode by running from the same directory:: + + pip install -e . + +which lets you change your source code (both tests and application) and rerun tests at will. +This is similar to running ``python setup.py develop`` or ``conda develop`` in that it installs +your package using a symlink to your development code. .. _`test discovery`: .. _`Python test discovery`: @@ -177,19 +199,6 @@ Note that this layout also works in conjunction with the ``src`` layout mentione tox ------ -For development, we recommend to use virtualenv_ environments and pip_ -for installing your application and any dependencies -as well as the ``pytest`` package itself. This ensures your code and -dependencies are isolated from the system Python installation. - -You can then install your package in "editable" mode:: - - pip install -e . - -which lets you change your source code (both tests and application) and rerun tests at will. -This is similar to running ``python setup.py develop`` or ``conda develop`` in that it installs -your package using a symlink to your development code. - Once you are done with your work and want to make sure that your actual package passes all tests you may want to look into `tox`_, the virtualenv test automation tool and its `pytest support diff --git a/src/_pytest/_code/_py2traceback.py b/src/_pytest/_code/_py2traceback.py index 2dd100c33..cceed40ed 100644 --- a/src/_pytest/_code/_py2traceback.py +++ b/src/_pytest/_code/_py2traceback.py @@ -2,7 +2,7 @@ # CHANGES: # - some_str is replaced, trying to create unicode strings # -from __future__ import absolute_import, division, print_function +from __future__ import absolute_import, division, print_function, unicode_literals import types from six import text_type @@ -51,17 +51,17 @@ def format_exception_only(etype, value): pass else: filename = filename or "" - lines.append(' File "%s", line %d\n' % (filename, lineno)) + 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(u" %s\n" % badline.strip()) + 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(" %s^\n" % "".join(caretspace)) + lines.append(" {}^\n".format("".join(caretspace))) value = msg lines.append(_format_final_exc_line(stype, value)) @@ -72,9 +72,9 @@ 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 = "%s\n" % etype + line = "{}\n".format(etype) else: - line = "%s: %s\n" % (etype, valuestr) + line = "{}: {}\n".format(etype, valuestr) return line @@ -83,7 +83,7 @@ def _some_str(value): return text_type(value) except Exception: try: - return str(value) + return bytes(value).decode("UTF-8", "replace") except Exception: pass - return "" % type(value).__name__ + return "".format(type(value).__name__) diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index d6c5cd90e..2662e4320 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -11,6 +11,7 @@ from weakref import ref from _pytest.compat import _PY2, _PY3, PY35, safe_str from six import text_type import py +import six builtin_repr = repr @@ -128,7 +129,7 @@ class Frame(object): """ f_locals = self.f_locals.copy() f_locals.update(vars) - py.builtin.exec_(code, self.f_globals, f_locals) + six.exec_(code, self.f_globals, f_locals) def repr(self, object): """ return a 'safe' (non-recursive, one-line) string repr for 'object' diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 4f96b9e8c..5cf63a063 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -223,7 +223,7 @@ class AssertionRewritingHook(object): mod.__loader__ = self # Normally, this attribute is 3.4+ mod.__spec__ = spec_from_file_location(name, co.co_filename, loader=self) - py.builtin.exec_(co, mod.__dict__) + six.exec_(co, mod.__dict__) except: # noqa if name in sys.modules: del sys.modules[name] @@ -402,12 +402,11 @@ def _saferepr(obj): JSON reprs. """ - repr = py.io.saferepr(obj) - if isinstance(repr, six.text_type): - t = six.text_type + r = py.io.saferepr(obj) + if isinstance(r, six.text_type): + return r.replace(u"\n", u"\\n") else: - t = six.binary_type - return repr.replace(t("\n"), t("\\n")) + return r.replace(b"\n", b"\\n") from _pytest.assertion.util import format_explanation as _format_explanation # noqa @@ -446,10 +445,9 @@ 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): - t = six.text_type + return explanation.replace(u"%", u"%%") else: - t = six.binary_type - return explanation.replace(t("%"), t("%%")) + return explanation.replace(b"%", b"%%") def _call_reprcompare(ops, results, expls, each_obj): diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index 08213c80e..a3013cb98 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -187,9 +187,9 @@ def _diff_text(left, right, verbose=False): r = r.replace(r"\r", "\r") return r - if isinstance(left, six.binary_type): + if isinstance(left, bytes): left = escape_for_readable_diff(left) - if isinstance(right, six.binary_type): + if isinstance(right, bytes): right = escape_for_readable_diff(right) if not verbose: i = 0 # just in case left or right has zero length diff --git a/src/_pytest/config/argparsing.py b/src/_pytest/config/argparsing.py index 5a4e35b88..3a2a11af4 100644 --- a/src/_pytest/config/argparsing.py +++ b/src/_pytest/config/argparsing.py @@ -2,6 +2,8 @@ import six import warnings import argparse +import py + FILE_OR_DIR = "file_or_dir" @@ -70,7 +72,8 @@ class Parser(object): self.optparser = self._getparser() try_argcomplete(self.optparser) - return self.optparser.parse_args([str(x) for x in args], namespace=namespace) + args = [str(x) if isinstance(x, py.path.local) else x for x in args] + return self.optparser.parse_args(args, namespace=namespace) def _getparser(self): from _pytest._argcomplete import filescompleter @@ -106,7 +109,7 @@ class Parser(object): the remaining arguments unknown at this point. """ optparser = self._getparser() - args = [str(x) for x in args] + args = [str(x) if isinstance(x, py.path.local) else x for x in args] return optparser.parse_known_args(args, namespace=namespace) def addini(self, name, help, type=None, default=None): diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index cc8921e65..c12691caa 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -858,7 +858,7 @@ class FixtureDef(object): if exceptions: e = exceptions[0] del exceptions # ensure we don't keep all frames alive because of the traceback - py.builtin._reraise(*e) + six.reraise(*e) finally: hook = self._fixturemanager.session.gethookproxy(request.node.fspath) @@ -885,7 +885,7 @@ class FixtureDef(object): result, cache_key, err = cached_result if my_cache_key == cache_key: if err is not None: - py.builtin._reraise(*err) + six.reraise(*err) else: return result # we have a previous but differently parametrized fixture instance diff --git a/src/_pytest/outcomes.py b/src/_pytest/outcomes.py index 63b8453b7..0a66fcab4 100644 --- a/src/_pytest/outcomes.py +++ b/src/_pytest/outcomes.py @@ -3,7 +3,6 @@ exception classes and constants handling test outcomes as well as functions creating them """ from __future__ import absolute_import, division, print_function -import py import sys @@ -21,7 +20,7 @@ class OutcomeException(BaseException): if self.msg: val = self.msg if isinstance(val, bytes): - val = py._builtin._totext(val, errors="replace") + val = val.decode("UTF-8", errors="replace") return val return "<%s instance>" % (self.__class__.__name__,) diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index b40a9e267..2372ea663 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -22,6 +22,7 @@ import pytest from _pytest.main import Session, EXIT_OK from _pytest.assertion.rewrite import AssertionRewritingHook from _pytest.compat import Path +from _pytest.compat import safe_str IGNORE_PAM = [ # filenames added when obtaining details about the current user u"/var/lib/sss/mc/passwd" @@ -34,7 +35,7 @@ def pytest_addoption(parser): action="store_true", dest="lsof", default=False, - help=("run FD checks if lsof is available"), + help="run FD checks if lsof is available", ) parser.addoption( @@ -273,7 +274,7 @@ class HookRecorder(object): del self.calls[i] return call lines = ["could not find call %r, in:" % (name,)] - lines.extend([" %s" % str(x) for x in self.calls]) + lines.extend([" %s" % x for x in self.calls]) pytest.fail("\n".join(lines)) def getcall(self, name): @@ -885,14 +886,12 @@ class Testdir(object): return self._runpytest_method(*args, **kwargs) def _ensure_basetemp(self, args): - args = [str(x) for x in args] + args = list(args) for x in args: - if str(x).startswith("--basetemp"): - # print("basedtemp exists: %s" %(args,)) + if safe_str(x).startswith("--basetemp"): break else: args.append("--basetemp=%s" % self.tmpdir.dirpath("basetemp")) - # print("added basetemp: %s" %(args,)) return args def parseconfig(self, *args): @@ -1018,7 +1017,7 @@ class Testdir(object): """ env = os.environ.copy() env["PYTHONPATH"] = os.pathsep.join( - filter(None, [str(os.getcwd()), env.get("PYTHONPATH", "")]) + filter(None, [os.getcwd(), env.get("PYTHONPATH", "")]) ) kw["env"] = env @@ -1037,14 +1036,13 @@ class Testdir(object): Returns a :py:class:`RunResult`. """ - return self._run(*cmdargs) - - def _run(self, *cmdargs): - cmdargs = [str(x) for x in cmdargs] + cmdargs = [ + str(arg) if isinstance(arg, py.path.local) else arg for arg in cmdargs + ] p1 = self.tmpdir.join("stdout") p2 = self.tmpdir.join("stderr") - print("running:", " ".join(cmdargs)) - print(" in:", str(py.path.local())) + print("running:", *cmdargs) + print(" in:", py.path.local()) f1 = codecs.open(str(p1), "w", encoding="utf8") f2 = codecs.open(str(p2), "w", encoding="utf8") try: @@ -1076,7 +1074,7 @@ class Testdir(object): print("couldn't print to %s because of encoding" % (fp,)) def _getpytestargs(self): - return (sys.executable, "-mpytest") + return sys.executable, "-mpytest" def runpython(self, script): """Run a python script using sys.executable as interpreter. diff --git a/src/_pytest/python.py b/src/_pytest/python.py index d694ba676..7fb7ff9ef 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -752,7 +752,7 @@ class FunctionMixin(PyobjMixin): def _repr_failure_py(self, excinfo, style="long"): if excinfo.errisinstance(fail.Exception): if not excinfo.value.pytrace: - return py._builtin._totext(excinfo.value) + return six.text_type(excinfo.value) return super(FunctionMixin, self)._repr_failure_py(excinfo, style=style) def repr_failure(self, excinfo, outerr=None): diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index abc4d1e17..6cd17de25 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -4,7 +4,7 @@ import sys from numbers import Number from decimal import Decimal -import py +import six from six.moves import zip, filterfalse from more_itertools.more import always_iterable @@ -680,8 +680,8 @@ def raises(expected_exception, *args, **kwargs): # print "raises frame scope: %r" % frame.f_locals try: code = _pytest._code.Source(code).compile() - py.builtin.exec_(code, frame.f_globals, loc) - # XXX didn'T mean f_globals == f_locals something special? + six.exec_(code, frame.f_globals, loc) + # XXX didn't mean f_globals == f_locals something special? # this is destroyed here ... except expected_exception: return _pytest._code.ExceptionInfo() diff --git a/src/_pytest/recwarn.py b/src/_pytest/recwarn.py index 177757f27..0eee4c841 100644 --- a/src/_pytest/recwarn.py +++ b/src/_pytest/recwarn.py @@ -4,11 +4,11 @@ from __future__ import absolute_import, division, print_function import inspect import _pytest._code -import py +import re import sys import warnings -import re +import six from _pytest.fixtures import yield_fixture from _pytest.outcomes import fail @@ -130,7 +130,7 @@ def warns(expected_warning, *args, **kwargs): with WarningsChecker(expected_warning, match_expr=match_expr): code = _pytest._code.Source(code).compile() - py.builtin.exec_(code, frame.f_globals, loc) + six.exec_(code, frame.f_globals, loc) else: func = args[0] with WarningsChecker(expected_warning, match_expr=match_expr): diff --git a/src/_pytest/runner.py b/src/_pytest/runner.py index 5739bbef0..1ba9ff310 100644 --- a/src/_pytest/runner.py +++ b/src/_pytest/runner.py @@ -6,7 +6,7 @@ import os import sys from time import time -import py +import six from _pytest._code.code import ExceptionInfo from _pytest.outcomes import skip, Skipped, TEST_OUTCOME @@ -317,7 +317,7 @@ class SetupState(object): if exc is None: exc = sys.exc_info() if exc: - py.builtin._reraise(*exc) + six.reraise(*exc) def _teardown_with_finalization(self, colitem): self._callfinalizers(colitem) @@ -352,7 +352,7 @@ class SetupState(object): if exc is None: exc = sys.exc_info() if exc: - py.builtin._reraise(*exc) + six.reraise(*exc) def prepare(self, colitem): """ setup objects along the collector chain to the test-method @@ -363,7 +363,7 @@ class SetupState(object): # check if the last collection node has raised an error for col in self.stack: if hasattr(col, "_prepare_exc"): - py.builtin._reraise(*col._prepare_exc) + six.reraise(*col._prepare_exc) for col in needed_collectors[len(self.stack) :]: self.stack.append(col) try: diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 5d6baf121..428ac464c 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -2,11 +2,11 @@ from __future__ import absolute_import, division, print_function import os import sys +import textwrap import types import six -import _pytest._code import py import pytest from _pytest.main import EXIT_NOTESTSCOLLECTED, EXIT_USAGEERROR @@ -131,7 +131,7 @@ class TestGeneralUsage(object): p2 = testdir.makefile(".pyc", "123") result = testdir.runpytest(p1, p2) assert result.ret - result.stderr.fnmatch_lines(["*ERROR: not found:*%s" % (p2.basename,)]) + result.stderr.fnmatch_lines(["*ERROR: not found:*{}".format(p2.basename)]) def test_issue486_better_reporting_on_conftest_load_failure(self, testdir): testdir.makepyfile("") @@ -201,16 +201,16 @@ class TestGeneralUsage(object): testdir.tmpdir.join("py").mksymlinkto(py._pydir) p = testdir.tmpdir.join("main.py") p.write( - _pytest._code.Source( + textwrap.dedent( + """\ + import sys, os + sys.path.insert(0, '') + import py + print(py.__file__) + print(py.__path__) + os.chdir(os.path.dirname(os.getcwd())) + print(py.log) """ - import sys, os - sys.path.insert(0, '') - import py - print (py.__file__) - print (py.__path__) - os.chdir(os.path.dirname(os.getcwd())) - print (py.log) - """ ) ) result = testdir.runpython(p) @@ -453,7 +453,7 @@ class TestInvocationVariants(object): @pytest.mark.xfail("sys.platform.startswith('java')") def test_pydoc(self, testdir): for name in ("py.test", "pytest"): - result = testdir.runpython_c("import %s;help(%s)" % (name, name)) + result = testdir.runpython_c("import {};help({})".format(name, name)) assert result.ret == 0 s = result.stdout.str() assert "MarkGenerator" in s @@ -836,7 +836,7 @@ class TestDurations(object): if ("test_%s" % x) in line and y in line: break else: - raise AssertionError("not found %s %s" % (x, y)) + raise AssertionError("not found {} {}".format(x, y)) def test_with_deselected(self, testdir): testdir.makepyfile(self.source) diff --git a/testing/code/test_code.py b/testing/code/test_code.py index e098f136d..f7a8a4dbd 100644 --- a/testing/code/test_code.py +++ b/testing/code/test_code.py @@ -3,8 +3,8 @@ from __future__ import absolute_import, division, print_function import sys import _pytest._code -import py import pytest +import mock from test_excinfo import TWMock from six import text_type @@ -68,12 +68,8 @@ def test_getstatement_empty_fullsource(): f = func() f = _pytest._code.Frame(f) - prop = f.code.__class__.fullsource - try: - f.code.__class__.fullsource = None - assert f.statement == _pytest._code.Source("") - finally: - f.code.__class__.fullsource = prop + with mock.patch.object(f.code.__class__, "fullsource", None): + assert f.statement == "" def test_code_from_func(): @@ -83,7 +79,7 @@ def test_code_from_func(): def test_unicode_handling(): - value = py.builtin._totext("\xc4\x85\xc4\x87\n", "utf-8").encode("utf8") + value = u"ąć".encode("UTF-8") def f(): raise Exception(value) @@ -96,7 +92,7 @@ def test_unicode_handling(): @pytest.mark.skipif(sys.version_info[0] >= 3, reason="python 2 only issue") def test_unicode_handling_syntax_error(): - value = py.builtin._totext("\xc4\x85\xc4\x87\n", "utf-8").encode("utf8") + value = u"ąć".encode("UTF-8") def f(): raise SyntaxError("invalid syntax", (None, 1, 3, value)) diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index fbdaeacf7..6723a8806 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -8,6 +8,7 @@ import textwrap import _pytest import py import pytest +import six from _pytest._code.code import ( ExceptionInfo, FormattedExcinfo, @@ -148,7 +149,7 @@ class TestTraceback_f_g_h(object): except somenoname: pass xyz() - """ + """ ) try: exec(source.compile()) @@ -251,7 +252,7 @@ class TestTraceback_f_g_h(object): import sys exc, val, tb = sys.exc_info() - py.builtin._reraise(exc, val, tb) + six.reraise(exc, val, tb) def f(n): try: @@ -269,7 +270,7 @@ class TestTraceback_f_g_h(object): decorator = pytest.importorskip("decorator").decorator def log(f, *k, **kw): - print("%s %s" % (k, kw)) + print("{} {}".format(k, kw)) f(*k, **kw) log = decorator(log) @@ -425,7 +426,7 @@ class TestFormattedExcinfo(object): @pytest.fixture def importasmod(self, request): def importasmod(source): - source = _pytest._code.Source(source) + source = textwrap.dedent(source) tmpdir = request.getfixturevalue("tmpdir") modpath = tmpdir.join("mod.py") tmpdir.ensure("__init__.py") @@ -449,10 +450,10 @@ class TestFormattedExcinfo(object): def test_repr_source(self): pr = FormattedExcinfo() source = _pytest._code.Source( - """ + """\ def f(x): pass - """ + """ ).strip() pr.flow_marker = "|" lines = pr.get_source(source, 0) @@ -884,10 +885,10 @@ raise ValueError() class MyRepr(TerminalRepr): def toterminal(self, tw): - tw.line(py.builtin._totext("я", "utf-8")) + tw.line(u"я") - x = py.builtin._totext(MyRepr()) - assert x == py.builtin._totext("я", "utf-8") + x = six.text_type(MyRepr()) + assert x == u"я" def test_toterminal_long(self, importasmod): mod = importasmod( diff --git a/testing/code/test_source.py b/testing/code/test_source.py index 995fabcf4..d7e8fe422 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -6,8 +6,8 @@ import inspect import sys import _pytest._code -import py import pytest +import six from _pytest._code import Source from _pytest._code.source import ast @@ -323,7 +323,7 @@ class TestSourceParsingAndCompiling(object): def test_compile_and_getsource(self): co = self.source.compile() - py.builtin.exec_(co, globals()) + six.exec_(co, globals()) f(7) excinfo = pytest.raises(AssertionError, "f(6)") frame = excinfo.traceback[-1].frame @@ -392,7 +392,7 @@ def test_getfuncsource_dynamic(): def g(): pass """ co = _pytest._code.compile(source) - py.builtin.exec_(co, globals()) + six.exec_(co, globals()) assert str(_pytest._code.Source(f)).strip() == "def f():\n raise ValueError" assert str(_pytest._code.Source(g)).strip() == "def g(): pass" diff --git a/testing/example_scripts/acceptance/fixture_mock_integration.py b/testing/example_scripts/acceptance/fixture_mock_integration.py index 51f46f82c..c005c9193 100644 --- a/testing/example_scripts/acceptance/fixture_mock_integration.py +++ b/testing/example_scripts/acceptance/fixture_mock_integration.py @@ -1,6 +1,9 @@ """Reproduces issue #3774""" -import mock +try: + import mock +except ImportError: + import unittest.mock as mock import pytest diff --git a/testing/python/collect.py b/testing/python/collect.py index 7356597cb..52c06a42e 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import os import sys -from textwrap import dedent +import textwrap import _pytest._code import pytest @@ -47,13 +47,14 @@ class TestModule(object): p = root2.join("test_x456.py") monkeypatch.syspath_prepend(str(root1)) p.write( - dedent( + textwrap.dedent( """\ - import x456 - def test(): - assert x456.__file__.startswith(%r) - """ - % str(root2) + import x456 + def test(): + assert x456.__file__.startswith({!r}) + """.format( + str(root2) + ) ) ) with root2.as_cwd(): @@ -929,23 +930,23 @@ class TestConftestCustomization(object): def test_customized_pymakemodule_issue205_subdir(self, testdir): b = testdir.mkdir("a").mkdir("b") b.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + import pytest + @pytest.hookimpl(hookwrapper=True) + def pytest_pycollect_makemodule(): + outcome = yield + mod = outcome.get_result() + mod.obj.hello = "world" """ - import pytest - @pytest.hookimpl(hookwrapper=True) - def pytest_pycollect_makemodule(): - outcome = yield - mod = outcome.get_result() - mod.obj.hello = "world" - """ ) ) b.join("test_module.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + def test_hello(): + assert hello == "world" """ - def test_hello(): - assert hello == "world" - """ ) ) reprec = testdir.inline_run() @@ -954,31 +955,31 @@ class TestConftestCustomization(object): def test_customized_pymakeitem(self, testdir): b = testdir.mkdir("a").mkdir("b") b.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + import pytest + @pytest.hookimpl(hookwrapper=True) + def pytest_pycollect_makeitem(): + outcome = yield + if outcome.excinfo is None: + result = outcome.get_result() + if result: + for func in result: + func._some123 = "world" """ - import pytest - @pytest.hookimpl(hookwrapper=True) - def pytest_pycollect_makeitem(): - outcome = yield - if outcome.excinfo is None: - result = outcome.get_result() - if result: - for func in result: - func._some123 = "world" - """ ) ) b.join("test_module.py").write( - _pytest._code.Source( - """ - import pytest + textwrap.dedent( + """\ + import pytest - @pytest.fixture() - def obj(request): - return request.node._some123 - def test_hello(obj): - assert obj == "world" - """ + @pytest.fixture() + def obj(request): + return request.node._some123 + def test_hello(obj): + assert obj == "world" + """ ) ) reprec = testdir.inline_run() @@ -1033,7 +1034,7 @@ class TestConftestCustomization(object): ) testdir.makefile( ".narf", - """ + """\ def test_something(): assert 1 + 1 == 2""", ) @@ -1046,29 +1047,29 @@ def test_setup_only_available_in_subdir(testdir): sub1 = testdir.mkpydir("sub1") sub2 = testdir.mkpydir("sub2") sub1.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + import pytest + def pytest_runtest_setup(item): + assert item.fspath.purebasename == "test_in_sub1" + def pytest_runtest_call(item): + assert item.fspath.purebasename == "test_in_sub1" + def pytest_runtest_teardown(item): + assert item.fspath.purebasename == "test_in_sub1" """ - import pytest - def pytest_runtest_setup(item): - assert item.fspath.purebasename == "test_in_sub1" - def pytest_runtest_call(item): - assert item.fspath.purebasename == "test_in_sub1" - def pytest_runtest_teardown(item): - assert item.fspath.purebasename == "test_in_sub1" - """ ) ) sub2.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + import pytest + def pytest_runtest_setup(item): + assert item.fspath.purebasename == "test_in_sub2" + def pytest_runtest_call(item): + assert item.fspath.purebasename == "test_in_sub2" + def pytest_runtest_teardown(item): + assert item.fspath.purebasename == "test_in_sub2" """ - import pytest - def pytest_runtest_setup(item): - assert item.fspath.purebasename == "test_in_sub2" - def pytest_runtest_call(item): - assert item.fspath.purebasename == "test_in_sub2" - def pytest_runtest_teardown(item): - assert item.fspath.purebasename == "test_in_sub2" - """ ) ) sub1.join("test_in_sub1.py").write("def test_1(): pass") @@ -1547,12 +1548,12 @@ def test_skip_duplicates_by_default(testdir): a = testdir.mkdir("a") fh = a.join("test_a.py") fh.write( - _pytest._code.Source( + textwrap.dedent( + """\ + import pytest + def test_real(): + pass """ - import pytest - def test_real(): - pass - """ ) ) result = testdir.runpytest(a.strpath, a.strpath) @@ -1567,12 +1568,12 @@ def test_keep_duplicates(testdir): a = testdir.mkdir("a") fh = a.join("test_a.py") fh.write( - _pytest._code.Source( + textwrap.dedent( + """\ + import pytest + def test_real(): + pass """ - import pytest - def test_real(): - pass - """ ) ) result = testdir.runpytest("--keep-duplicates", a.strpath, a.strpath) diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 4170f8f37..8306ae315 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -1,6 +1,5 @@ -from textwrap import dedent +import textwrap -import _pytest._code import pytest from _pytest.pytester import get_public_names from _pytest.fixtures import FixtureLookupError, FixtureRequest @@ -208,23 +207,23 @@ class TestFillFixtures(object): ) subdir = testdir.mkpydir("subdir") subdir.join("conftest.py").write( - _pytest._code.Source( - """ - import pytest + textwrap.dedent( + """\ + import pytest - @pytest.fixture - def spam(): - return 'spam' - """ + @pytest.fixture + def spam(): + return 'spam' + """ ) ) testfile = subdir.join("test_spam.py") testfile.write( - _pytest._code.Source( + textwrap.dedent( + """\ + def test_spam(spam): + assert spam == "spam" """ - def test_spam(spam): - assert spam == "spam" - """ ) ) result = testdir.runpytest() @@ -276,26 +275,26 @@ class TestFillFixtures(object): ) subdir = testdir.mkpydir("subdir") subdir.join("conftest.py").write( - _pytest._code.Source( - """ - import pytest + textwrap.dedent( + """\ + import pytest - @pytest.fixture(params=[1, 2, 3]) - def spam(request): - return request.param - """ + @pytest.fixture(params=[1, 2, 3]) + def spam(request): + return request.param + """ ) ) testfile = subdir.join("test_spam.py") testfile.write( - _pytest._code.Source( - """ - params = {'spam': 1} + textwrap.dedent( + """\ + params = {'spam': 1} - def test_spam(spam): - assert spam == params['spam'] - params['spam'] += 1 - """ + def test_spam(spam): + assert spam == params['spam'] + params['spam'] += 1 + """ ) ) result = testdir.runpytest() @@ -320,26 +319,26 @@ class TestFillFixtures(object): ) subdir = testdir.mkpydir("subdir") subdir.join("conftest.py").write( - _pytest._code.Source( - """ - import pytest + textwrap.dedent( + """\ + import pytest - @pytest.fixture(params=[1, 2, 3]) - def spam(request): - return request.param - """ + @pytest.fixture(params=[1, 2, 3]) + def spam(request): + return request.param + """ ) ) testfile = subdir.join("test_spam.py") testfile.write( - _pytest._code.Source( - """ - params = {'spam': 1} + textwrap.dedent( + """\ + params = {'spam': 1} - def test_spam(spam): - assert spam == params['spam'] - params['spam'] += 1 - """ + def test_spam(spam): + assert spam == params['spam'] + params['spam'] += 1 + """ ) ) result = testdir.runpytest() @@ -807,13 +806,13 @@ class TestRequestBasic(object): # this tests that normalization of nodeids takes place b = testdir.mkdir("tests").mkdir("unit") b.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + import pytest + @pytest.fixture + def arg1(): + pass """ - import pytest - @pytest.fixture - def arg1(): - pass - """ ) ) p = b.join("test_module.py") @@ -1484,41 +1483,41 @@ class TestFixtureManagerParseFactories(object): runner = testdir.mkdir("runner") package = testdir.mkdir("package") package.join("conftest.py").write( - dedent( + textwrap.dedent( """\ import pytest @pytest.fixture def one(): return 1 - """ + """ ) ) package.join("test_x.py").write( - dedent( + textwrap.dedent( """\ - def test_x(one): - assert one == 1 - """ + def test_x(one): + assert one == 1 + """ ) ) sub = package.mkdir("sub") sub.join("__init__.py").ensure() sub.join("conftest.py").write( - dedent( + textwrap.dedent( """\ - import pytest - @pytest.fixture - def one(): - return 2 - """ + import pytest + @pytest.fixture + def one(): + return 2 + """ ) ) sub.join("test_y.py").write( - dedent( + textwrap.dedent( """\ - def test_x(one): - assert one == 2 - """ + def test_x(one): + assert one == 2 + """ ) ) reprec = testdir.inline_run() @@ -1535,44 +1534,44 @@ class TestFixtureManagerParseFactories(object): ) package = testdir.mkdir("package") package.join("__init__.py").write( - dedent( + textwrap.dedent( """\ - from .. import values - def setup_module(): - values.append("package") - def teardown_module(): - values[:] = [] - """ + from .. import values + def setup_module(): + values.append("package") + def teardown_module(): + values[:] = [] + """ ) ) package.join("test_x.py").write( - dedent( + textwrap.dedent( """\ - from .. import values - def test_x(): - assert values == ["package"] - """ + from .. import values + def test_x(): + assert values == ["package"] + """ ) ) package = testdir.mkdir("package2") package.join("__init__.py").write( - dedent( + textwrap.dedent( """\ - from .. import values - def setup_module(): - values.append("package2") - def teardown_module(): - values[:] = [] - """ + from .. import values + def setup_module(): + values.append("package2") + def teardown_module(): + values[:] = [] + """ ) ) package.join("test_x.py").write( - dedent( + textwrap.dedent( """\ - from .. import values - def test_x(): - assert values == ["package2"] - """ + from .. import values + def test_x(): + assert values == ["package2"] + """ ) ) reprec = testdir.inline_run() @@ -1587,32 +1586,32 @@ class TestFixtureManagerParseFactories(object): package = testdir.mkdir("package") package.join("__init__.py").write("") package.join("conftest.py").write( - dedent( + textwrap.dedent( """\ - import pytest - from .. import values - @pytest.fixture(scope="package") - def one(): - values.append("package") - yield values - values.pop() - @pytest.fixture(scope="package", autouse=True) - def two(): - values.append("package-auto") - yield values - values.pop() - """ + import pytest + from .. import values + @pytest.fixture(scope="package") + def one(): + values.append("package") + yield values + values.pop() + @pytest.fixture(scope="package", autouse=True) + def two(): + values.append("package-auto") + yield values + values.pop() + """ ) ) package.join("test_x.py").write( - dedent( + textwrap.dedent( """\ - from .. import values - def test_package_autouse(): - assert values == ["package-auto"] - def test_package(one): - assert values == ["package-auto", "package"] - """ + from .. import values + def test_package_autouse(): + assert values == ["package-auto"] + def test_package(one): + assert values == ["package-auto", "package"] + """ ) ) reprec = testdir.inline_run() @@ -1804,24 +1803,24 @@ class TestAutouseManagement(object): def test_autouse_conftest_mid_directory(self, testdir): pkgdir = testdir.mkpydir("xyz123") pkgdir.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + import pytest + @pytest.fixture(autouse=True) + def app(): + import sys + sys._myapp = "hello" """ - import pytest - @pytest.fixture(autouse=True) - def app(): - import sys - sys._myapp = "hello" - """ ) ) t = pkgdir.ensure("tests", "test_app.py") t.write( - _pytest._code.Source( + textwrap.dedent( + """\ + import sys + def test_app(): + assert sys._myapp == "hello" """ - import sys - def test_app(): - assert sys._myapp == "hello" - """ ) ) reprec = testdir.inline_run("-s") @@ -2715,17 +2714,17 @@ class TestFixtureMarker(object): ) b = testdir.mkdir("subdir") b.join("test_overridden_fixture_finalizer.py").write( - dedent( - """ - import pytest - @pytest.fixture - def browser(browser): - browser['visited'] = True - return browser + textwrap.dedent( + """\ + import pytest + @pytest.fixture + def browser(browser): + browser['visited'] = True + return browser - def test_browser(browser): - assert browser['visited'] is True - """ + def test_browser(browser): + assert browser['visited'] is True + """ ) ) reprec = testdir.runpytest("-s") @@ -3217,120 +3216,119 @@ class TestShowFixtures(object): def test_show_fixtures_trimmed_doc(self, testdir): p = testdir.makepyfile( - dedent( + textwrap.dedent( + '''\ + import pytest + @pytest.fixture + def arg1(): + """ + line1 + line2 + + """ + @pytest.fixture + def arg2(): + """ + line1 + line2 + + """ ''' - import pytest - @pytest.fixture - def arg1(): - """ - line1 - line2 - - """ - @pytest.fixture - def arg2(): - """ - line1 - line2 - - """ - ''' ) ) result = testdir.runpytest("--fixtures", p) result.stdout.fnmatch_lines( - dedent( + textwrap.dedent( + """\ + * fixtures defined from test_show_fixtures_trimmed_doc * + arg2 + line1 + line2 + arg1 + line1 + line2 """ - * fixtures defined from test_show_fixtures_trimmed_doc * - arg2 - line1 - line2 - arg1 - line1 - line2 - - """ ) ) def test_show_fixtures_indented_doc(self, testdir): p = testdir.makepyfile( - dedent( + textwrap.dedent( + '''\ + import pytest + @pytest.fixture + def fixture1(): + """ + line1 + indented line + """ ''' - import pytest - @pytest.fixture - def fixture1(): - """ - line1 - indented line - """ - ''' ) ) result = testdir.runpytest("--fixtures", p) result.stdout.fnmatch_lines( - dedent( + textwrap.dedent( + """\ + * fixtures defined from test_show_fixtures_indented_doc * + fixture1 + line1 + indented line """ - * fixtures defined from test_show_fixtures_indented_doc * - fixture1 - line1 - indented line - """ ) ) def test_show_fixtures_indented_doc_first_line_unindented(self, testdir): p = testdir.makepyfile( - dedent( + textwrap.dedent( + '''\ + import pytest + @pytest.fixture + def fixture1(): + """line1 + line2 + indented line + """ ''' - import pytest - @pytest.fixture - def fixture1(): - """line1 - line2 - indented line - """ - ''' ) ) result = testdir.runpytest("--fixtures", p) result.stdout.fnmatch_lines( - dedent( + textwrap.dedent( + """\ + * fixtures defined from test_show_fixtures_indented_doc_first_line_unindented * + fixture1 + line1 + line2 + indented line """ - * fixtures defined from test_show_fixtures_indented_doc_first_line_unindented * - fixture1 - line1 - line2 - indented line - """ ) ) def test_show_fixtures_indented_in_class(self, testdir): p = testdir.makepyfile( - dedent( + textwrap.dedent( + '''\ + import pytest + class TestClass(object): + @pytest.fixture + def fixture1(self): + """line1 + line2 + indented line + """ ''' - import pytest - class TestClass(object): - @pytest.fixture - def fixture1(self): - """line1 - line2 - indented line - """ - ''' ) ) result = testdir.runpytest("--fixtures", p) result.stdout.fnmatch_lines( - dedent( + textwrap.dedent( + """\ + * fixtures defined from test_show_fixtures_indented_in_class * + fixture1 + line1 + line2 + indented line """ - * fixtures defined from test_show_fixtures_indented_in_class * - fixture1 - line1 - line2 - indented line - """ ) ) @@ -3667,26 +3665,26 @@ class TestParameterizedSubRequest(object): fixdir = testdir.mkdir("fixtures") fixfile = fixdir.join("fix.py") fixfile.write( - _pytest._code.Source( - """ - import pytest + textwrap.dedent( + """\ + import pytest - @pytest.fixture(params=[0, 1, 2]) - def fix_with_param(request): - return request.param - """ + @pytest.fixture(params=[0, 1, 2]) + def fix_with_param(request): + return request.param + """ ) ) testfile = tests_dir.join("test_foos.py") testfile.write( - _pytest._code.Source( - """ - from fix import fix_with_param + textwrap.dedent( + """\ + from fix import fix_with_param - def test_foo(request): - request.getfixturevalue('fix_with_param') - """ + def test_foo(request): + request.getfixturevalue('fix_with_param') + """ ) ) @@ -3698,9 +3696,9 @@ class TestParameterizedSubRequest(object): E*Failed: The requested fixture has no parameter defined for the current test. E* E*Requested fixture 'fix_with_param' defined in: - E*fix.py:5 + E*fix.py:4 E*Requested here: - E*test_foos.py:5 + E*test_foos.py:4 *1 failed* """ ) diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 7ef34678c..f5d839f08 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -2,8 +2,7 @@ import re import sys import attr -import _pytest._code -import py +import textwrap import pytest from _pytest import python, fixtures @@ -295,9 +294,7 @@ class TestMetafunc(object): ) assert result == ["a0-1.0", "a1-b1"] # unicode mixing, issue250 - result = idmaker( - (py.builtin._totext("a"), "b"), [pytest.param({}, b"\xc3\xb4")] - ) + result = idmaker((u"a", "b"), [pytest.param({}, b"\xc3\xb4")]) assert result == ["a0-\\xc3\\xb4"] def test_idmaker_with_bytes_regex(self): @@ -309,7 +306,6 @@ class TestMetafunc(object): def test_idmaker_native_strings(self): from _pytest.python import idmaker - totext = py.builtin._totext result = idmaker( ("a", "b"), [ @@ -324,7 +320,7 @@ class TestMetafunc(object): pytest.param({7}, set("seven")), pytest.param(tuple("eight"), (8, -8, 8)), pytest.param(b"\xc3\xb4", b"name"), - pytest.param(b"\xc3\xb4", totext("other")), + pytest.param(b"\xc3\xb4", u"other"), ], ) assert result == [ @@ -1275,19 +1271,19 @@ class TestMetafuncFunctional(object): sub1 = testdir.mkpydir("sub1") sub2 = testdir.mkpydir("sub2") sub1.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + def pytest_generate_tests(metafunc): + assert metafunc.function.__name__ == "test_1" """ - def pytest_generate_tests(metafunc): - assert metafunc.function.__name__ == "test_1" - """ ) ) sub2.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + def pytest_generate_tests(metafunc): + assert metafunc.function.__name__ == "test_2" """ - def pytest_generate_tests(metafunc): - assert metafunc.function.__name__ == "test_2" - """ ) ) sub1.join("test_in_sub1.py").write("def test_1(): pass") diff --git a/testing/test_argcomplete.py b/testing/test_argcomplete.py index 9e6b711a2..fc2306b00 100644 --- a/testing/test_argcomplete.py +++ b/testing/test_argcomplete.py @@ -11,7 +11,7 @@ def equal_with_bash(prefix, ffc, fc, out=None): res_bash = set(fc(prefix)) retval = set(res) == res_bash if out: - out.write("equal_with_bash %s %s\n" % (retval, res)) + out.write("equal_with_bash {} {}\n".format(retval, res)) if not retval: out.write(" python - bash: %s\n" % (set(res) - res_bash)) out.write(" bash - python: %s\n" % (res_bash - set(res))) diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 23763f078..a9e624713 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -6,6 +6,7 @@ import textwrap import _pytest.assertion as plugin import py import pytest +import six from _pytest.assertion import util from _pytest.assertion import truncate @@ -509,12 +510,12 @@ class TestAssert_reprcompare(object): assert "raised in repr()" not in expl def test_unicode(self): - left = py.builtin._totext("£€", "utf-8") - right = py.builtin._totext("£", "utf-8") + left = u"£€" + right = u"£" expl = callequal(left, right) - assert expl[0] == py.builtin._totext("'£€' == '£'", "utf-8") - assert expl[1] == py.builtin._totext("- £€", "utf-8") - assert expl[2] == py.builtin._totext("+ £", "utf-8") + assert expl[0] == u"'£€' == '£'" + assert expl[1] == u"- £€" + assert expl[2] == u"+ £" def test_nonascii_text(self): """ @@ -541,8 +542,8 @@ class TestAssert_reprcompare(object): right = bytes(right, "utf-8") expl = callequal(left, right) for line in expl: - assert isinstance(line, py.builtin.text) - msg = py.builtin._totext("\n").join(expl) + assert isinstance(line, six.text_type) + msg = u"\n".join(expl) assert msg diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index 6cec7f003..79e7cf0e3 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -9,6 +9,7 @@ import textwrap import zipfile import py import pytest +import six import _pytest._code from _pytest.assertion import util @@ -49,7 +50,7 @@ def getmsg(f, extra_ns=None, must_pass=False): ns = {} if extra_ns is not None: ns.update(extra_ns) - py.builtin.exec_(code, ns) + six.exec_(code, ns) func = ns[f.__name__] try: func() @@ -560,7 +561,7 @@ class TestAssertionRewrite(object): assert getmsg(f) == "assert 42" def my_reprcompare(op, left, right): - return "%s %s %s" % (left, op, right) + return "{} {} {}".format(left, op, right) monkeypatch.setattr(util, "_reprcompare", my_reprcompare) @@ -654,12 +655,10 @@ class TestRewriteOnImport(object): def test_readonly(self, testdir): sub = testdir.mkdir("testing") sub.join("test_readonly.py").write( - py.builtin._totext( - """ + b""" def test_rewritten(): assert "@py_builtins" in globals() - """ - ).encode("utf-8"), + """, "wb", ) old_mode = sub.stat().mode @@ -1040,14 +1039,14 @@ class TestAssertionRewriteHookDetails(object): """ path = testdir.mkpydir("foo") path.join("test_foo.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + class Test(object): + def test_foo(self): + import pkgutil + data = pkgutil.get_data('foo.test_foo', 'data.txt') + assert data == b'Hey' """ - class Test(object): - def test_foo(self): - import pkgutil - data = pkgutil.get_data('foo.test_foo', 'data.txt') - assert data == b'Hey' - """ ) ) path.join("data.txt").write("Hey") diff --git a/testing/test_cacheprovider.py b/testing/test_cacheprovider.py index 7ec73ec63..cfeb4a0cf 100644 --- a/testing/test_cacheprovider.py +++ b/testing/test_cacheprovider.py @@ -1,9 +1,9 @@ from __future__ import absolute_import, division, print_function import sys +import textwrap import py -import _pytest import pytest import os import shutil @@ -224,17 +224,17 @@ class TestLastFailed(object): result = testdir.runpytest() result.stdout.fnmatch_lines(["*2 failed*"]) p.write( - _pytest._code.Source( + textwrap.dedent( + """\ + def test_1(): + assert 1 + + def test_2(): + assert 1 + + def test_3(): + assert 0 """ - def test_1(): - assert 1 - - def test_2(): - assert 1 - - def test_3(): - assert 0 - """ ) ) result = testdir.runpytest("--lf") @@ -252,19 +252,19 @@ class TestLastFailed(object): def test_failedfirst_order(self, testdir): testdir.tmpdir.join("test_a.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + def test_always_passes(): + assert 1 """ - def test_always_passes(): - assert 1 - """ ) ) testdir.tmpdir.join("test_b.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + def test_always_fails(): + assert 0 """ - def test_always_fails(): - assert 0 - """ ) ) result = testdir.runpytest() @@ -277,14 +277,14 @@ class TestLastFailed(object): def test_lastfailed_failedfirst_order(self, testdir): testdir.makepyfile( **{ - "test_a.py": """ + "test_a.py": """\ def test_always_passes(): assert 1 - """, - "test_b.py": """ + """, + "test_b.py": """\ def test_always_fails(): assert 0 - """, + """, } ) result = testdir.runpytest() @@ -298,16 +298,16 @@ class TestLastFailed(object): def test_lastfailed_difference_invocations(self, testdir, monkeypatch): monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1) testdir.makepyfile( - test_a=""" + test_a="""\ def test_a1(): assert 0 def test_a2(): assert 1 - """, - test_b=""" + """, + test_b="""\ def test_b1(): assert 0 - """, + """, ) p = testdir.tmpdir.join("test_a.py") p2 = testdir.tmpdir.join("test_b.py") @@ -317,11 +317,11 @@ class TestLastFailed(object): result = testdir.runpytest("--lf", p2) result.stdout.fnmatch_lines(["*1 failed*"]) p2.write( - _pytest._code.Source( + textwrap.dedent( + """\ + def test_b1(): + assert 1 """ - def test_b1(): - assert 1 - """ ) ) result = testdir.runpytest("--lf", p2) @@ -332,18 +332,18 @@ class TestLastFailed(object): def test_lastfailed_usecase_splice(self, testdir, monkeypatch): monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1) testdir.makepyfile( - """ + """\ def test_1(): assert 0 - """ + """ ) p2 = testdir.tmpdir.join("test_something.py") p2.write( - _pytest._code.Source( + textwrap.dedent( + """\ + def test_2(): + assert 0 """ - def test_2(): - assert 0 - """ ) ) result = testdir.runpytest() diff --git a/testing/test_capture.py b/testing/test_capture.py index 93eaaa85c..75d82ecde 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function # note: py.io capture tests where copied from @@ -5,13 +6,13 @@ from __future__ import absolute_import, division, print_function import pickle import os import sys +import textwrap from io import UnsupportedOperation -import _pytest._code import py import pytest import contextlib -from six import binary_type, text_type +from six import text_type from _pytest import capture from _pytest.capture import CaptureManager from _pytest.main import EXIT_NOTESTSCOLLECTED @@ -23,12 +24,12 @@ needsosdup = pytest.mark.xfail("not hasattr(os, 'dup')") def tobytes(obj): if isinstance(obj, text_type): obj = obj.encode("UTF-8") - assert isinstance(obj, binary_type) + assert isinstance(obj, bytes) return obj def totext(obj): - if isinstance(obj, binary_type): + if isinstance(obj, bytes): obj = text_type(obj, "UTF-8") assert isinstance(obj, text_type) return obj @@ -268,7 +269,7 @@ class TestPerTestCapturing(object): def test_capturing_outerr(self, testdir): p1 = testdir.makepyfile( - """ + """\ import sys def test_capturing(): print (42) @@ -277,7 +278,7 @@ class TestPerTestCapturing(object): print (1) sys.stderr.write(str(2)) raise ValueError - """ + """ ) result = testdir.runpytest(p1) result.stdout.fnmatch_lines( @@ -297,21 +298,21 @@ class TestPerTestCapturing(object): class TestLoggingInteraction(object): def test_logging_stream_ownership(self, testdir): p = testdir.makepyfile( - """ + """\ def test_logging(): import logging import pytest stream = capture.CaptureIO() logging.basicConfig(stream=stream) stream.close() # to free memory/release resources - """ + """ ) result = testdir.runpytest_subprocess(p) assert result.stderr.str().find("atexit") == -1 def test_logging_and_immediate_setupteardown(self, testdir): p = testdir.makepyfile( - """ + """\ import logging def setup_function(function): logging.warn("hello1") @@ -323,7 +324,7 @@ class TestLoggingInteraction(object): def teardown_function(function): logging.warn("hello3") assert 0 - """ + """ ) for optargs in (("--capture=sys",), ("--capture=fd",)): print(optargs) @@ -337,7 +338,7 @@ class TestLoggingInteraction(object): def test_logging_and_crossscope_fixtures(self, testdir): p = testdir.makepyfile( - """ + """\ import logging def setup_module(function): logging.warn("hello1") @@ -349,7 +350,7 @@ class TestLoggingInteraction(object): def teardown_module(function): logging.warn("hello3") assert 0 - """ + """ ) for optargs in (("--capture=sys",), ("--capture=fd",)): print(optargs) @@ -363,11 +364,11 @@ class TestLoggingInteraction(object): def test_conftestlogging_is_shown(self, testdir): testdir.makeconftest( - """ + """\ import logging logging.basicConfig() logging.warn("hello435") - """ + """ ) # make sure that logging is still captured in tests result = testdir.runpytest_subprocess("-s", "-p", "no:capturelog") @@ -377,19 +378,19 @@ class TestLoggingInteraction(object): def test_conftestlogging_and_test_logging(self, testdir): testdir.makeconftest( - """ + """\ import logging logging.basicConfig() - """ + """ ) # make sure that logging is still captured in tests p = testdir.makepyfile( - """ + """\ def test_hello(): import logging logging.warn("hello433") assert 0 - """ + """ ) result = testdir.runpytest_subprocess(p, "-p", "no:capturelog") assert result.ret != 0 @@ -402,24 +403,24 @@ class TestCaptureFixture(object): @pytest.mark.parametrize("opt", [[], ["-s"]]) def test_std_functional(self, testdir, opt): reprec = testdir.inline_runsource( - """ + """\ def test_hello(capsys): print (42) out, err = capsys.readouterr() assert out.startswith("42") - """, + """, *opt ) reprec.assertoutcome(passed=1) def test_capsyscapfd(self, testdir): p = testdir.makepyfile( - """ + """\ def test_one(capsys, capfd): pass def test_two(capfd, capsys): pass - """ + """ ) result = testdir.runpytest(p) result.stdout.fnmatch_lines( @@ -437,12 +438,12 @@ class TestCaptureFixture(object): in the same test is an error. """ testdir.makepyfile( - """ + """\ def test_one(capsys, request): request.getfixturevalue("capfd") def test_two(capfd, request): request.getfixturevalue("capsys") - """ + """ ) result = testdir.runpytest() result.stdout.fnmatch_lines( @@ -457,10 +458,10 @@ class TestCaptureFixture(object): def test_capsyscapfdbinary(self, testdir): p = testdir.makepyfile( - """ + """\ def test_one(capsys, capfdbinary): pass - """ + """ ) result = testdir.runpytest(p) result.stdout.fnmatch_lines( @@ -470,12 +471,13 @@ class TestCaptureFixture(object): @pytest.mark.parametrize("method", ["sys", "fd"]) def test_capture_is_represented_on_failure_issue128(self, testdir, method): p = testdir.makepyfile( - """ - def test_hello(cap%s): + """\ + def test_hello(cap{}): print ("xxx42xxx") assert 0 - """ - % method + """.format( + method + ) ) result = testdir.runpytest(p) result.stdout.fnmatch_lines(["xxx42xxx"]) @@ -483,21 +485,21 @@ class TestCaptureFixture(object): @needsosdup def test_stdfd_functional(self, testdir): reprec = testdir.inline_runsource( - """ + """\ def test_hello(capfd): import os os.write(1, "42".encode('ascii')) out, err = capfd.readouterr() assert out.startswith("42") capfd.close() - """ + """ ) reprec.assertoutcome(passed=1) @needsosdup def test_capfdbinary(self, testdir): reprec = testdir.inline_runsource( - """ + """\ def test_hello(capfdbinary): import os # some likely un-decodable bytes @@ -505,7 +507,7 @@ class TestCaptureFixture(object): out, err = capfdbinary.readouterr() assert out == b'\\xfe\\x98\\x20' assert err == b'' - """ + """ ) reprec.assertoutcome(passed=1) @@ -514,7 +516,7 @@ class TestCaptureFixture(object): ) def test_capsysbinary(self, testdir): reprec = testdir.inline_runsource( - """ + """\ def test_hello(capsysbinary): import sys # some likely un-decodable bytes @@ -522,7 +524,7 @@ class TestCaptureFixture(object): out, err = capsysbinary.readouterr() assert out == b'\\xfe\\x98\\x20' assert err == b'' - """ + """ ) reprec.assertoutcome(passed=1) @@ -531,10 +533,10 @@ class TestCaptureFixture(object): ) def test_capsysbinary_forbidden_in_python2(self, testdir): testdir.makepyfile( - """ + """\ def test_hello(capsysbinary): pass - """ + """ ) result = testdir.runpytest() result.stdout.fnmatch_lines( @@ -547,10 +549,10 @@ class TestCaptureFixture(object): def test_partial_setup_failure(self, testdir): p = testdir.makepyfile( - """ + """\ def test_hello(capsys, missingarg): pass - """ + """ ) result = testdir.runpytest(p) result.stdout.fnmatch_lines(["*test_partial_setup_failure*", "*1 error*"]) @@ -558,12 +560,12 @@ class TestCaptureFixture(object): @needsosdup def test_keyboardinterrupt_disables_capturing(self, testdir): p = testdir.makepyfile( - """ + """\ def test_hello(capfd): import os os.write(1, str(42).encode('ascii')) raise KeyboardInterrupt() - """ + """ ) result = testdir.runpytest_subprocess(p) result.stdout.fnmatch_lines(["*KeyboardInterrupt*"]) @@ -572,7 +574,7 @@ class TestCaptureFixture(object): @pytest.mark.issue14 def test_capture_and_logging(self, testdir): p = testdir.makepyfile( - """ + """\ import logging def test_log(capsys): logging.error('x') @@ -585,7 +587,7 @@ class TestCaptureFixture(object): @pytest.mark.parametrize("no_capture", [True, False]) def test_disabled_capture_fixture(self, testdir, fixture, no_capture): testdir.makepyfile( - """ + """\ def test_disabled({fixture}): print('captured before') with {fixture}.disabled(): @@ -619,7 +621,7 @@ class TestCaptureFixture(object): Ensure that capsys and capfd can be used by other fixtures during setup and teardown. """ testdir.makepyfile( - """ + """\ from __future__ import print_function import sys import pytest @@ -655,7 +657,7 @@ class TestCaptureFixture(object): def test_fixture_use_by_other_fixtures_teardown(self, testdir, cap): """Ensure we can access setup and teardown buffers from teardown when using capsys/capfd (##3033)""" testdir.makepyfile( - """ + """\ import sys import pytest import os @@ -683,11 +685,11 @@ class TestCaptureFixture(object): def test_setup_failure_does_not_kill_capturing(testdir): sub1 = testdir.mkpydir("sub1") sub1.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + def pytest_runtest_setup(item): + raise ValueError(42) """ - def pytest_runtest_setup(item): - raise ValueError(42) - """ ) ) sub1.join("test_mod.py").write("def test_func1(): pass") @@ -1083,9 +1085,9 @@ class TestStdCapture(object): def test_capturing_readouterr_unicode(self): with self.getcapture() as cap: - print("hx\xc4\x85\xc4\x87") + print("hxąć") out, err = cap.readouterr() - assert out == py.builtin._totext("hx\xc4\x85\xc4\x87\n", "utf8") + assert out == u"hxąć\n" @pytest.mark.skipif( "sys.version_info >= (3,)", reason="text output different for bytes on python3" @@ -1095,7 +1097,7 @@ class TestStdCapture(object): # triggered an internal error in pytest print("\xa6") out, err = cap.readouterr() - assert out == py.builtin._totext("\ufffd\n", "unicode-escape") + assert out == u"\ufffd\n" def test_reset_twice_error(self): with self.getcapture() as cap: diff --git a/testing/test_collection.py b/testing/test_collection.py index 5b494ba31..ce0e3a920 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -1,9 +1,9 @@ from __future__ import absolute_import, division, print_function import pprint import sys +import textwrap import pytest -import _pytest._code from _pytest.main import Session, EXIT_NOTESTSCOLLECTED, _in_venv @@ -913,13 +913,13 @@ def test_fixture_scope_sibling_conftests(testdir): """Regression test case for https://github.com/pytest-dev/pytest/issues/2836""" foo_path = testdir.mkdir("foo") foo_path.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + import pytest + @pytest.fixture + def fix(): + return 1 """ - import pytest - @pytest.fixture - def fix(): - return 1 - """ ) ) foo_path.join("test_foo.py").write("def test_foo(fix): assert fix == 1") diff --git a/testing/test_config.py b/testing/test_config.py index ef9dacd9c..756b51de4 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -17,11 +17,11 @@ class TestParseIni(object): sub = tmpdir.mkdir("sub") sub.chdir() tmpdir.join(filename).write( - _pytest._code.Source( - """ - [{section}] - name = value - """.format( + textwrap.dedent( + """\ + [{section}] + name = value + """.format( section=section ) ) @@ -38,11 +38,11 @@ class TestParseIni(object): def test_append_parse_args(self, testdir, tmpdir, monkeypatch): monkeypatch.setenv("PYTEST_ADDOPTS", '--color no -rs --tb="short"') tmpdir.join("pytest.ini").write( - _pytest._code.Source( + textwrap.dedent( + """\ + [pytest] + addopts = --verbose """ - [pytest] - addopts = --verbose - """ ) ) config = testdir.parseconfig(tmpdir) @@ -438,11 +438,11 @@ class TestConfigFromdictargs(object): def test_inifilename(self, tmpdir): tmpdir.join("foo/bar.ini").ensure().write( - _pytest._code.Source( + textwrap.dedent( + """\ + [pytest] + name = value """ - [pytest] - name = value - """ ) ) @@ -453,12 +453,12 @@ class TestConfigFromdictargs(object): cwd = tmpdir.join("a/b") cwd.join("pytest.ini").ensure().write( - _pytest._code.Source( + textwrap.dedent( + """\ + [pytest] + name = wrong-value + should_not_be_set = true """ - [pytest] - name = wrong-value - should_not_be_set = true - """ ) ) with cwd.ensure(dir=True).as_cwd(): diff --git a/testing/test_conftest.py b/testing/test_conftest.py index 449ef5281..f3b5bac38 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -1,7 +1,6 @@ from __future__ import absolute_import, division, print_function -from textwrap import dedent +import textwrap -import _pytest._code import py import pytest from _pytest.config import PytestPluginManager @@ -174,11 +173,11 @@ def test_conftest_confcutdir(testdir): testdir.makeconftest("assert 0") x = testdir.mkdir("x") x.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + def pytest_addoption(parser): + parser.addoption("--xyz", action="store_true") """ - def pytest_addoption(parser): - parser.addoption("--xyz", action="store_true") - """ ) ) result = testdir.runpytest("-h", "--confcutdir=%s" % x, x) @@ -198,11 +197,11 @@ def test_no_conftest(testdir): def test_conftest_existing_resultlog(testdir): x = testdir.mkdir("tests") x.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + def pytest_addoption(parser): + parser.addoption("--xyz", action="store_true") """ - def pytest_addoption(parser): - parser.addoption("--xyz", action="store_true") - """ ) ) testdir.makefile(ext=".log", result="") # Writes result.log @@ -213,11 +212,11 @@ def test_conftest_existing_resultlog(testdir): def test_conftest_existing_junitxml(testdir): x = testdir.mkdir("tests") x.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + def pytest_addoption(parser): + parser.addoption("--xyz", action="store_true") """ - def pytest_addoption(parser): - parser.addoption("--xyz", action="store_true") - """ ) ) testdir.makefile(ext=".xml", junit="") # Writes junit.xml @@ -247,38 +246,38 @@ def test_fixture_dependency(testdir, monkeypatch): sub = testdir.mkdir("sub") sub.join("__init__.py").write("") sub.join("conftest.py").write( - dedent( + textwrap.dedent( + """\ + import pytest + + @pytest.fixture + def not_needed(): + assert False, "Should not be called!" + + @pytest.fixture + def foo(): + assert False, "Should not be called!" + + @pytest.fixture + def bar(foo): + return 'bar' """ - import pytest - - @pytest.fixture - def not_needed(): - assert False, "Should not be called!" - - @pytest.fixture - def foo(): - assert False, "Should not be called!" - - @pytest.fixture - def bar(foo): - return 'bar' - """ ) ) subsub = sub.mkdir("subsub") subsub.join("__init__.py").write("") subsub.join("test_bar.py").write( - dedent( + textwrap.dedent( + """\ + import pytest + + @pytest.fixture + def bar(): + return 'sub bar' + + def test_event_fixture(bar): + assert bar == 'sub bar' """ - import pytest - - @pytest.fixture - def bar(): - return 'sub bar' - - def test_event_fixture(bar): - assert bar == 'sub bar' - """ ) ) result = testdir.runpytest("sub") @@ -288,11 +287,11 @@ def test_fixture_dependency(testdir, monkeypatch): def test_conftest_found_with_double_dash(testdir): sub = testdir.mkdir("sub") sub.join("conftest.py").write( - dedent( + textwrap.dedent( + """\ + def pytest_addoption(parser): + parser.addoption("--hello-world", action="store_true") """ - def pytest_addoption(parser): - parser.addoption("--hello-world", action="store_true") - """ ) ) p = sub.join("test_hello.py") @@ -313,56 +312,54 @@ class TestConftestVisibility(object): package = testdir.mkdir("package") package.join("conftest.py").write( - dedent( + textwrap.dedent( """\ - import pytest - @pytest.fixture - def fxtr(): - return "from-package" - """ + import pytest + @pytest.fixture + def fxtr(): + return "from-package" + """ ) ) package.join("test_pkgroot.py").write( - dedent( + textwrap.dedent( """\ - def test_pkgroot(fxtr): - assert fxtr == "from-package" - """ + def test_pkgroot(fxtr): + assert fxtr == "from-package" + """ ) ) swc = package.mkdir("swc") swc.join("__init__.py").ensure() swc.join("conftest.py").write( - dedent( + textwrap.dedent( """\ - import pytest - @pytest.fixture - def fxtr(): - return "from-swc" - """ + import pytest + @pytest.fixture + def fxtr(): + return "from-swc" + """ ) ) swc.join("test_with_conftest.py").write( - dedent( + textwrap.dedent( """\ - def test_with_conftest(fxtr): - assert fxtr == "from-swc" - - """ + def test_with_conftest(fxtr): + assert fxtr == "from-swc" + """ ) ) snc = package.mkdir("snc") snc.join("__init__.py").ensure() snc.join("test_no_conftest.py").write( - dedent( + textwrap.dedent( """\ - def test_no_conftest(fxtr): - assert fxtr == "from-package" # No local conftest.py, so should - # use value from parent dir's - - """ + def test_no_conftest(fxtr): + assert fxtr == "from-package" # No local conftest.py, so should + # use value from parent dir's + """ ) ) print("created directory structure:") @@ -422,31 +419,31 @@ def test_search_conftest_up_to_inifile(testdir, confcutdir, passed, error): src = root.join("src").ensure(dir=1) src.join("pytest.ini").write("[pytest]") src.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + import pytest + @pytest.fixture + def fix1(): pass """ - import pytest - @pytest.fixture - def fix1(): pass - """ ) ) src.join("test_foo.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + def test_1(fix1): + pass + def test_2(out_of_reach): + pass """ - def test_1(fix1): - pass - def test_2(out_of_reach): - pass - """ ) ) root.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + import pytest + @pytest.fixture + def out_of_reach(): pass """ - import pytest - @pytest.fixture - def out_of_reach(): pass - """ ) ) @@ -464,19 +461,19 @@ def test_search_conftest_up_to_inifile(testdir, confcutdir, passed, error): def test_issue1073_conftest_special_objects(testdir): testdir.makeconftest( - """ + """\ class DontTouchMe(object): def __getattr__(self, x): raise Exception('cant touch me') x = DontTouchMe() - """ + """ ) testdir.makepyfile( - """ + """\ def test_some(): pass - """ + """ ) res = testdir.runpytest() assert res.ret == 0 @@ -484,15 +481,15 @@ def test_issue1073_conftest_special_objects(testdir): def test_conftest_exception_handling(testdir): testdir.makeconftest( - """ + """\ raise ValueError() - """ + """ ) testdir.makepyfile( - """ + """\ def test_some(): pass - """ + """ ) res = testdir.runpytest() assert res.ret == 4 @@ -507,7 +504,7 @@ def test_hook_proxy(testdir): **{ "root/demo-0/test_foo1.py": "def test1(): pass", "root/demo-a/test_foo2.py": "def test1(): pass", - "root/demo-a/conftest.py": """ + "root/demo-a/conftest.py": """\ def pytest_ignore_collect(path, config): return True """, @@ -525,11 +522,11 @@ def test_required_option_help(testdir): testdir.makeconftest("assert 0") x = testdir.mkdir("x") x.join("conftest.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + def pytest_addoption(parser): + parser.addoption("--xyz", action="store_true", required=True) """ - def pytest_addoption(parser): - parser.addoption("--xyz", action="store_true", required=True) - """ ) ) result = testdir.runpytest("-h", x) diff --git a/testing/test_doctest.py b/testing/test_doctest.py index 6a84c5feb..d7815b1cf 100644 --- a/testing/test_doctest.py +++ b/testing/test_doctest.py @@ -1,7 +1,7 @@ # encoding: utf-8 from __future__ import absolute_import, division, print_function import sys -import _pytest._code +import textwrap from _pytest.compat import MODULE_NOT_FOUND_ERROR from _pytest.doctest import DoctestItem, DoctestModule, DoctestTextfile import pytest @@ -258,16 +258,16 @@ class TestDoctests(object): def test_doctest_linedata_missing(self, testdir): testdir.tmpdir.join("hello.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + class Fun(object): + @property + def test(self): + ''' + >>> a = 1 + >>> 1/0 + ''' """ - class Fun(object): - @property - def test(self): - ''' - >>> a = 1 - >>> 1/0 - ''' - """ ) ) result = testdir.runpytest("--doctest-modules") @@ -300,10 +300,10 @@ class TestDoctests(object): def test_doctest_unex_importerror_with_module(self, testdir): testdir.tmpdir.join("hello.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + import asdalsdkjaslkdjasd """ - import asdalsdkjaslkdjasd - """ ) ) testdir.maketxtfile( @@ -339,27 +339,27 @@ class TestDoctests(object): def test_doctestmodule_external_and_issue116(self, testdir): p = testdir.mkpydir("hello") p.join("__init__.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + def somefunc(): + ''' + >>> i = 0 + >>> i + 1 + 2 + ''' """ - def somefunc(): - ''' - >>> i = 0 - >>> i + 1 - 2 - ''' - """ ) ) result = testdir.runpytest(p, "--doctest-modules") result.stdout.fnmatch_lines( [ - "004 *>>> i = 0", - "005 *>>> i + 1", + "003 *>>> i = 0", + "004 *>>> i + 1", "*Expected:", "* 2", "*Got:", "* 1", - "*:5: DocTestFailure", + "*:4: DocTestFailure", ] ) diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index b5424235b..ceea56ccc 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -7,7 +7,9 @@ def test_version(testdir, pytestconfig): result = testdir.runpytest("--version") assert result.ret == 0 # p = py.path.local(py.__file__).dirpath() - result.stderr.fnmatch_lines(["*pytest*%s*imported from*" % (pytest.__version__,)]) + result.stderr.fnmatch_lines( + ["*pytest*{}*imported from*".format(pytest.__version__)] + ) if pytestconfig.pluginmanager.list_plugin_distinfo(): result.stderr.fnmatch_lines(["*setuptools registered plugins:", "*at*"]) diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index ae2b4ea76..0678d59e8 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -941,7 +941,7 @@ def test_double_colon_split_method_issue469(testdir): def test_unicode_issue368(testdir): path = testdir.tmpdir.join("test.xml") log = LogXML(str(path), None) - ustr = py.builtin._totext("ВНИ!", "utf-8") + ustr = u"ВНИ!" class Report(BaseReport): longrepr = ustr diff --git a/testing/test_parseopt.py b/testing/test_parseopt.py index 3870ad419..fab288e7f 100644 --- a/testing/test_parseopt.py +++ b/testing/test_parseopt.py @@ -294,7 +294,7 @@ def test_argcomplete(testdir, monkeypatch): script = str(testdir.tmpdir.join("test_argcomplete")) pytest_bin = sys.argv[0] if "pytest" not in os.path.basename(pytest_bin): - pytest.skip("need to be run with pytest executable, not %s" % (pytest_bin,)) + pytest.skip("need to be run with pytest executable, not {}".format(pytest_bin)) with open(str(script), "w") as fp: # redirect output from argcomplete to stdin and stderr is not trivial diff --git a/testing/test_pdb.py b/testing/test_pdb.py index 43a78908c..ed1c49a1a 100644 --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -260,7 +260,9 @@ class TestPDB(object): assert False """ ) - child = testdir.spawn_pytest("--show-capture=%s --pdb %s" % (showcapture, p1)) + child = testdir.spawn_pytest( + "--show-capture={} --pdb {}".format(showcapture, p1) + ) if showcapture in ("all", "log"): child.expect("captured log") child.expect("get rekt") @@ -473,7 +475,7 @@ class TestPDB(object): x = 5 """ ) - child = testdir.spawn("%s %s" % (sys.executable, p1)) + child = testdir.spawn("{} {}".format(sys.executable, p1)) child.expect("x = 5") child.sendeof() self.flush(child) diff --git a/testing/test_pytester.py b/testing/test_pytester.py index 86dc35796..99e62e5bc 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -8,7 +8,7 @@ import _pytest.pytester as pytester from _pytest.pytester import HookRecorder from _pytest.pytester import CwdSnapshot, SysModulesSnapshot, SysPathsSnapshot from _pytest.config import PytestPluginManager -from _pytest.main import EXIT_OK, EXIT_TESTSFAILED +from _pytest.main import EXIT_OK, EXIT_TESTSFAILED, EXIT_NOTESTSCOLLECTED def test_make_hook_recorder(testdir): @@ -396,3 +396,8 @@ class TestSysPathsSnapshot(object): def test_testdir_subprocess(testdir): testfile = testdir.makepyfile("def test_one(): pass") assert testdir.runpytest_subprocess(testfile).ret == 0 + + +def test_unicode_args(testdir): + result = testdir.runpytest("-k", u"💩") + assert result.ret == EXIT_NOTESTSCOLLECTED diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 88e5287e8..f377c3ca9 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -4,9 +4,9 @@ terminal reporting of the full testing process. from __future__ import absolute_import, division, print_function import collections import sys +import textwrap import pluggy -import _pytest._code import py import pytest from _pytest.main import EXIT_NOTESTSCOLLECTED @@ -161,12 +161,12 @@ class TestTerminal(object): def test_itemreport_directclasses_not_shown_as_subclasses(self, testdir): a = testdir.mkpydir("a123") a.join("test_hello123.py").write( - _pytest._code.Source( + textwrap.dedent( + """\ + class TestClass(object): + def test_method(self): + pass """ - class TestClass(object): - def test_method(self): - pass - """ ) ) result = testdir.runpytest("-v") @@ -312,13 +312,13 @@ class TestCollectonly(object): result = testdir.runpytest("--collect-only", p) assert result.ret == 2 result.stdout.fnmatch_lines( - _pytest._code.Source( + textwrap.dedent( + """\ + *ERROR* + *ImportError* + *No module named *Errlk* + *1 error* """ - *ERROR* - *ImportError* - *No module named *Errlk* - *1 error* - """ ).strip() ) @@ -1118,9 +1118,9 @@ def test_terminal_summary_warnings_are_displayed(testdir): ) def test_summary_stats(exp_line, exp_color, stats_arg): print("Based on stats: %s" % stats_arg) - print('Expect summary: "%s"; with color "%s"' % (exp_line, exp_color)) + print('Expect summary: "{}"; with color "{}"'.format(exp_line, exp_color)) (line, color) = build_summary_stats_line(stats_arg) - print('Actually got: "%s"; with color "%s"' % (line, color)) + print('Actually got: "{}"; with color "{}"'.format(line, color)) assert line == exp_line assert color == exp_color