diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e91059b54..37570ed43 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -16,6 +16,9 @@ New Features * ``pytest.raises`` now asserts that the error message matches a text or regex with the ``match`` keyword argument. Thanks `@Kriechi`_ for the PR. +* ``pytest.param`` can be used to declare test parameter sets with marks and test ids. + Thanks `@RonnyPfannschmidt`_ for the PR. + Changes ------- diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 71dc04d91..edf71dad7 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -206,12 +206,12 @@ but here is a simple overview: #. Run all the tests - You need to have Python 2.7 and 3.5 available in your system. Now + You need to have Python 2.7 and 3.6 available in your system. Now running tests is as simple as issuing this command:: - $ tox -e linting,py27,py35 + $ tox -e linting,py27,py36 - This command will run tests via the "tox" tool against Python 2.7 and 3.5 + This command will run tests via the "tox" tool against Python 2.7 and 3.6 and also perform "lint" coding-style checks. #. You can now edit your local working copy. @@ -223,9 +223,9 @@ but here is a simple overview: $ tox -e py27 -- --pdb - Or to only run tests in a particular test module on Python 3.5:: + Or to only run tests in a particular test module on Python 3.6:: - $ tox -e py35 -- testing/test_config.py + $ tox -e py36 -- testing/test_config.py #. Commit and push once your tests pass and you are happy with your change(s):: diff --git a/_pytest/_argcomplete.py b/_pytest/_argcomplete.py index 8fbbf2660..12040b53a 100644 --- a/_pytest/_argcomplete.py +++ b/_pytest/_argcomplete.py @@ -57,7 +57,7 @@ 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, division, print_function import sys import os from glob import glob diff --git a/_pytest/_code/__init__.py b/_pytest/_code/__init__.py index 3463c11ea..815c13b42 100644 --- a/_pytest/_code/__init__.py +++ b/_pytest/_code/__init__.py @@ -1,4 +1,5 @@ """ python inspection/code generation API """ +from __future__ import absolute_import, division, print_function from .code import Code # noqa from .code import ExceptionInfo # noqa from .code import Frame # noqa diff --git a/_pytest/_code/_py2traceback.py b/_pytest/_code/_py2traceback.py index a830d9899..d45ee01fa 100644 --- a/_pytest/_code/_py2traceback.py +++ b/_pytest/_code/_py2traceback.py @@ -2,6 +2,7 @@ # CHANGES: # - some_str is replaced, trying to create unicode strings # +from __future__ import absolute_import, division, print_function import types def format_exception_only(etype, value): diff --git a/_pytest/_code/code.py b/_pytest/_code/code.py index 6eceb0c7f..2f1ac7fb0 100644 --- a/_pytest/_code/code.py +++ b/_pytest/_code/code.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import sys from inspect import CO_VARARGS, CO_VARKEYWORDS import re diff --git a/_pytest/_code/source.py b/_pytest/_code/source.py index fcec0f5ca..8e6148410 100644 --- a/_pytest/_code/source.py +++ b/_pytest/_code/source.py @@ -1,4 +1,4 @@ -from __future__ import generators +from __future__ import absolute_import, division, generators, print_function from bisect import bisect_right import sys diff --git a/_pytest/_pluggy.py b/_pytest/_pluggy.py index 87d32cf8d..6cc1d3d54 100644 --- a/_pytest/_pluggy.py +++ b/_pytest/_pluggy.py @@ -2,7 +2,7 @@ imports symbols from vendored "pluggy" if available, otherwise falls back to importing "pluggy" from the default namespace. """ - +from __future__ import absolute_import, division, print_function try: from _pytest.vendored_packages.pluggy import * # noqa from _pytest.vendored_packages.pluggy import __version__ # noqa diff --git a/_pytest/assertion/__init__.py b/_pytest/assertion/__init__.py index fe0653bb7..edda06345 100644 --- a/_pytest/assertion/__init__.py +++ b/_pytest/assertion/__init__.py @@ -1,6 +1,7 @@ """ support for presenting detailed information in failing assertions. """ +from __future__ import absolute_import, division, print_function import py import sys diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py index 7408c4746..484d5bd8b 100644 --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -1,5 +1,5 @@ """Rewrite assertion AST to produce nice error messages""" - +from __future__ import absolute_import, division, print_function import ast import _ast import errno diff --git a/_pytest/assertion/truncate.py b/_pytest/assertion/truncate.py index 3c031b11f..1e1306356 100644 --- a/_pytest/assertion/truncate.py +++ b/_pytest/assertion/truncate.py @@ -4,7 +4,7 @@ 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, division, print_function import os import py diff --git a/_pytest/assertion/util.py b/_pytest/assertion/util.py index 7b4edb6fd..06eda8d91 100644 --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -1,4 +1,5 @@ """Utilities for assertion debugging""" +from __future__ import absolute_import, division, print_function import pprint import _pytest._code diff --git a/_pytest/cacheprovider.py b/_pytest/cacheprovider.py index 782fdadd9..0b8e71a71 100755 --- a/_pytest/cacheprovider.py +++ b/_pytest/cacheprovider.py @@ -4,7 +4,7 @@ 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, division, print_function import py import pytest import json diff --git a/_pytest/capture.py b/_pytest/capture.py index 6a1cae41d..c6fc80c0b 100644 --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -2,7 +2,7 @@ per-test stdout/stderr capturing mechanism. """ -from __future__ import with_statement +from __future__ import absolute_import, division, print_function import contextlib import sys diff --git a/_pytest/compat.py b/_pytest/compat.py index 09df385d1..b688ae509 100644 --- a/_pytest/compat.py +++ b/_pytest/compat.py @@ -1,6 +1,7 @@ """ python version compatibility code """ +from __future__ import absolute_import, division, print_function import sys import inspect import types diff --git a/_pytest/config.py b/_pytest/config.py index 0874c4599..db37280ca 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -1,4 +1,5 @@ """ command line options, ini-file and conftest.py processing. """ +from __future__ import absolute_import, division, print_function import argparse import shlex import traceback diff --git a/_pytest/debugging.py b/_pytest/debugging.py index c21e0977d..1e7dcad5d 100644 --- a/_pytest/debugging.py +++ b/_pytest/debugging.py @@ -1,5 +1,5 @@ """ interactive debugging with PDB, the Python Debugger. """ -from __future__ import absolute_import +from __future__ import absolute_import, division, print_function import pdb import sys diff --git a/_pytest/deprecated.py b/_pytest/deprecated.py index 6edc475f6..e75ff099e 100644 --- a/_pytest/deprecated.py +++ b/_pytest/deprecated.py @@ -5,7 +5,7 @@ that is planned to be removed in the next pytest release. Keeping it in a central location makes it easy to track what is deprecated and should be removed when the time comes. """ - +from __future__ import absolute_import, division, print_function MAIN_STR_ARGS = 'passing a string to pytest.main() is deprecated, ' \ 'pass a list of arguments instead.' diff --git a/_pytest/doctest.py b/_pytest/doctest.py index 4ee21b12d..f9299be72 100644 --- a/_pytest/doctest.py +++ b/_pytest/doctest.py @@ -1,5 +1,5 @@ """ discover and run doctests in modules and test files.""" -from __future__ import absolute_import +from __future__ import absolute_import, division, print_function import traceback diff --git a/_pytest/fixtures.py b/_pytest/fixtures.py index cd5c673ca..9196e4fdd 100644 --- a/_pytest/fixtures.py +++ b/_pytest/fixtures.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import sys from py._code.code import FormattedExcinfo diff --git a/_pytest/freeze_support.py b/_pytest/freeze_support.py index f78ccd298..6c2120559 100644 --- a/_pytest/freeze_support.py +++ b/_pytest/freeze_support.py @@ -2,6 +2,8 @@ Provides a function to report all internal modules for using freezing tools pytest """ +from __future__ import absolute_import, division, print_function + def pytest_namespace(): return {'freeze_includes': freeze_includes} @@ -42,4 +44,4 @@ def _iter_all_modules(package, prefix=''): for m in _iter_all_modules(os.path.join(path, name), prefix=name + '.'): yield prefix + m else: - yield prefix + name \ No newline at end of file + yield prefix + name diff --git a/_pytest/helpconfig.py b/_pytest/helpconfig.py index 6e66b11c4..abc792f7e 100644 --- a/_pytest/helpconfig.py +++ b/_pytest/helpconfig.py @@ -1,4 +1,6 @@ """ version info, help messages, tracing configuration. """ +from __future__ import absolute_import, division, print_function + import py import pytest import os, sys diff --git a/_pytest/junitxml.py b/_pytest/junitxml.py index e5f20b6f6..4bd334a16 100644 --- a/_pytest/junitxml.py +++ b/_pytest/junitxml.py @@ -4,9 +4,11 @@ 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 """ -# 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, division, print_function import functools import py diff --git a/_pytest/main.py b/_pytest/main.py index f100b7974..3d7b456d2 100644 --- a/_pytest/main.py +++ b/_pytest/main.py @@ -1,4 +1,6 @@ """ core implementation of testing process: init, session, runtest loop. """ +from __future__ import absolute_import, division, print_function + import functools import os import sys diff --git a/_pytest/mark.py b/_pytest/mark.py index 582eb1277..a06b02b14 100644 --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -1,20 +1,77 @@ """ generic mechanism for marking and selecting python functions. """ +from __future__ import absolute_import, division, print_function + import inspect from collections import namedtuple from operator import attrgetter from .compat import imap + def alias(name): return property(attrgetter(name), doc='alias for ' + name) +class ParameterSet(namedtuple('ParameterSet', 'values, marks, id')): + @classmethod + def param(cls, *values, **kw): + marks = kw.pop('marks', ()) + if isinstance(marks, MarkDecorator): + marks = marks, + else: + assert isinstance(marks, (tuple, list, set)) + + def param_extract_id(id=None): + return id + + id = param_extract_id(**kw) + return cls(values, marks, id) + + @classmethod + def extract_from(cls, parameterset, legacy_force_tuple=False): + """ + :param parameterset: + a legacy style parameterset that may or may not be a tuple, + and may or may not be wrapped into a mess of mark objects + + :param legacy_force_tuple: + enforce tuple wrapping so single argument tuple values + don't get decomposed and break tests + + """ + + if isinstance(parameterset, cls): + return parameterset + if not isinstance(parameterset, MarkDecorator) and legacy_force_tuple: + return cls.param(parameterset) + + newmarks = [] + argval = parameterset + while isinstance(argval, MarkDecorator): + newmarks.append(MarkDecorator(Mark( + argval.markname, argval.args[:-1], argval.kwargs))) + argval = argval.args[-1] + assert not isinstance(argval, ParameterSet) + if legacy_force_tuple: + argval = argval, + + return cls(argval, marks=newmarks, id=None) + + @property + def deprecated_arg_dict(self): + return dict((mark.name, mark) for mark in self.marks) + + class MarkerError(Exception): """Error in use of a pytest marker/attribute.""" + def pytest_namespace(): - return {'mark': MarkGenerator()} + return { + 'mark': MarkGenerator(), + 'param': ParameterSet.param, + } def pytest_addoption(parser): @@ -210,6 +267,7 @@ def istestfunc(func): return hasattr(func, "__call__") and \ getattr(func, "__name__", "") != "" + class MarkDecorator(object): """ A decorator for test functions and test classes. When applied it will create :class:`MarkInfo` objects which may be @@ -255,8 +313,11 @@ class MarkDecorator(object): def markname(self): return self.name # for backward-compat (2.4.1 had this attr) + def __eq__(self, other): + return self.mark == other.mark + def __repr__(self): - return "" % self.mark + return "" % (self.mark,) def __call__(self, *args, **kwargs): """ if passed a single callable argument: decorate it with mark info. @@ -289,19 +350,7 @@ class MarkDecorator(object): return self.__class__(self.mark.combined_with(mark)) -def extract_argvalue(maybe_marked_args): - # TODO: incorrect mark data, the old code wanst able to collect lists - # individual parametrized argument sets can be wrapped in a series - # of markers in which case we unwrap the values and apply the mark - # at Function init - newmarks = {} - argval = maybe_marked_args - while isinstance(argval, MarkDecorator): - newmark = MarkDecorator(Mark( - argval.markname, argval.args[:-1], argval.kwargs)) - newmarks[newmark.name] = newmark - argval = argval.args[-1] - return argval, newmarks + class Mark(namedtuple('Mark', 'name, args, kwargs')): diff --git a/_pytest/monkeypatch.py b/_pytest/monkeypatch.py index 30618cc57..9151db3ad 100644 --- a/_pytest/monkeypatch.py +++ b/_pytest/monkeypatch.py @@ -1,4 +1,5 @@ """ monkeypatching and mocking functionality. """ +from __future__ import absolute_import, division, print_function import os, sys import re diff --git a/_pytest/nose.py b/_pytest/nose.py index 038746868..828a919f9 100644 --- a/_pytest/nose.py +++ b/_pytest/nose.py @@ -1,4 +1,5 @@ """ run test suites written for nose. """ +from __future__ import absolute_import, division, print_function import sys diff --git a/_pytest/pastebin.py b/_pytest/pastebin.py index 9f1cf9063..6f3ce8fed 100644 --- a/_pytest/pastebin.py +++ b/_pytest/pastebin.py @@ -1,4 +1,6 @@ """ submit failure or test session information to a pastebin service. """ +from __future__ import absolute_import, division, print_function + import pytest import sys import tempfile diff --git a/_pytest/pytester.py b/_pytest/pytester.py index 97fc62312..ee0e5bbe7 100644 --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -1,4 +1,6 @@ """ (disabled by default) support for testing pytest and pytest plugins. """ +from __future__ import absolute_import, division, print_function + import codecs import gc import os @@ -12,8 +14,6 @@ from fnmatch import fnmatch from weakref import WeakKeyDictionary -from py.builtin import print_ - from _pytest.capture import MultiCapture, SysCapture from _pytest._code import Source import py @@ -229,15 +229,15 @@ class HookRecorder(object): name, check = entries.pop(0) for ind, call in enumerate(self.calls[i:]): if call._name == name: - print_("NAMEMATCH", name, call) + print("NAMEMATCH", name, call) if eval(check, backlocals, call.__dict__): - print_("CHECKERMATCH", repr(check), "->", call) + print("CHECKERMATCH", repr(check), "->", call) else: - print_("NOCHECKERMATCH", repr(check), "-", call) + print("NOCHECKERMATCH", repr(check), "-", call) continue i += ind + 1 break - print_("NONAMEMATCH", name, "with", call) + print("NONAMEMATCH", name, "with", call) else: pytest.fail("could not find %r check %r" % (name, check)) @@ -924,8 +924,8 @@ class Testdir(object): cmdargs = [str(x) for x in cmdargs] p1 = self.tmpdir.join("stdout") p2 = self.tmpdir.join("stderr") - print_("running:", ' '.join(cmdargs)) - print_(" in:", str(py.path.local())) + print("running:", ' '.join(cmdargs)) + print(" in:", str(py.path.local())) f1 = codecs.open(str(p1), "w", encoding="utf8") f2 = codecs.open(str(p2), "w", encoding="utf8") try: @@ -951,7 +951,7 @@ class Testdir(object): def _dump_lines(self, lines, fp): try: for line in lines: - py.builtin.print_(line, file=fp) + print(line, file=fp) except UnicodeEncodeError: print("couldn't print to %s because of encoding" % (fp,)) diff --git a/_pytest/python.py b/_pytest/python.py index 471a9563f..81eed00f0 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1,4 +1,5 @@ """ Python test discovery, setup and run of test functions. """ +from __future__ import absolute_import, division, print_function import fnmatch import inspect @@ -787,36 +788,35 @@ class Metafunc(fixtures.FuncargnamesCompatAttr): to set a dynamic scope using test context or configuration. """ from _pytest.fixtures import scope2index - from _pytest.mark import extract_argvalue + from _pytest.mark import ParameterSet from py.io import saferepr - unwrapped_argvalues = [] - newkeywords = [] - for maybe_marked_args in argvalues: - argval, newmarks = extract_argvalue(maybe_marked_args) - unwrapped_argvalues.append(argval) - newkeywords.append(newmarks) - argvalues = unwrapped_argvalues - if not isinstance(argnames, (tuple, list)): argnames = [x.strip() for x in argnames.split(",") if x.strip()] - if len(argnames) == 1: - argvalues = [(val,) for val in argvalues] - if not argvalues: - argvalues = [(NOTSET,) * len(argnames)] - # we passed a empty list to parameterize, skip that test - # + force_tuple = len(argnames) == 1 + else: + force_tuple = False + parameters = [ + ParameterSet.extract_from(x, legacy_force_tuple=force_tuple) + for x in argvalues] + del argvalues + + + if not parameters: fs, lineno = getfslineno(self.function) - newmark = pytest.mark.skip( - reason="got empty parameter set %r, function %s at %s:%d" % ( - argnames, self.function.__name__, fs, lineno)) - newkeywords = [{newmark.markname: newmark}] + reason = "got empty parameter set %r, function %s at %s:%d" % ( + argnames, self.function.__name__, fs, lineno) + mark = pytest.mark.skip(reason=reason) + parameters.append(ParameterSet( + values=(NOTSET,) * len(argnames), + marks=[mark], + id=None, + )) if scope is None: scope = _find_parametrized_scope(argnames, self._arg2fixturedefs, indirect) - scopenum = scope2index( - scope, descr='call to {0}'.format(self.parametrize)) + scopenum = scope2index(scope, descr='call to {0}'.format(self.parametrize)) valtypes = {} for arg in argnames: if arg not in self.fixturenames: @@ -844,22 +844,22 @@ class Metafunc(fixtures.FuncargnamesCompatAttr): idfn = ids ids = None if ids: - if len(ids) != len(argvalues): - raise ValueError('%d tests specified with %d ids' %( - len(argvalues), len(ids))) + if len(ids) != len(parameters): + raise ValueError('%d tests specified with %d ids' % ( + len(parameters), len(ids))) for id_value in ids: if id_value is not None and not isinstance(id_value, py.builtin._basestring): msg = 'ids must be list of strings, found: %s (type: %s)' raise ValueError(msg % (saferepr(id_value), type(id_value).__name__)) - ids = idmaker(argnames, argvalues, idfn, ids, self.config) + ids = idmaker(argnames, parameters, idfn, ids, self.config) newcalls = [] for callspec in self._calls or [CallSpec2(self)]: - elements = zip(ids, argvalues, newkeywords, count()) - for a_id, valset, keywords, param_index in elements: - assert len(valset) == len(argnames) + elements = zip(ids, parameters, count()) + for a_id, param, param_index in elements: + assert len(param.values) == len(argnames) newcallspec = callspec.copy(self) - newcallspec.setmulti(valtypes, argnames, valset, a_id, - keywords, scopenum, param_index) + newcallspec.setmulti(valtypes, argnames, param.values, a_id, + param.deprecated_arg_dict, scopenum, param_index) newcalls.append(newcallspec) self._calls = newcalls @@ -958,17 +958,19 @@ def _idval(val, argname, idx, idfn, config=None): return val.__name__ return str(argname)+str(idx) -def _idvalset(idx, valset, argnames, idfn, ids, config=None): +def _idvalset(idx, parameterset, argnames, idfn, ids, config=None): + if parameterset.id is not None: + return parameterset.id if ids is None or (idx >= len(ids) or ids[idx] is None): this_id = [_idval(val, argname, idx, idfn, config) - for val, argname in zip(valset, argnames)] + for val, argname in zip(parameterset.values, argnames)] return "-".join(this_id) else: return _escape_strings(ids[idx]) -def idmaker(argnames, argvalues, idfn=None, ids=None, config=None): - ids = [_idvalset(valindex, valset, argnames, idfn, ids, config) - for valindex, valset in enumerate(argvalues)] +def idmaker(argnames, parametersets, idfn=None, ids=None, config=None): + ids = [_idvalset(valindex, parameterset, argnames, idfn, ids, config) + for valindex, parameterset in enumerate(parametersets)] if len(set(ids)) != len(ids): # The ids are not unique duplicates = [testid for testid in ids if ids.count(testid) > 1] diff --git a/_pytest/recwarn.py b/_pytest/recwarn.py index 319bcb836..579439fe4 100644 --- a/_pytest/recwarn.py +++ b/_pytest/recwarn.py @@ -1,4 +1,6 @@ """ recording warnings during test function execution. """ +from __future__ import absolute_import, division, print_function + import inspect import _pytest._code diff --git a/_pytest/resultlog.py b/_pytest/resultlog.py index fc0025983..3e4b00cf9 100644 --- a/_pytest/resultlog.py +++ b/_pytest/resultlog.py @@ -1,6 +1,7 @@ """ log machine-parseable test session result information in a plain text file. """ +from __future__ import absolute_import, division, print_function import py import os @@ -61,9 +62,9 @@ class ResultLog(object): self.logfile = logfile # preferably line buffered def write_log_entry(self, testpath, lettercode, longrepr): - py.builtin.print_("%s %s" % (lettercode, testpath), file=self.logfile) + print("%s %s" % (lettercode, testpath), file=self.logfile) for line in longrepr.splitlines(): - py.builtin.print_(" %s" % line, file=self.logfile) + print(" %s" % line, file=self.logfile) def log_outcome(self, report, lettercode, longrepr): testpath = getattr(report, 'nodeid', None) diff --git a/_pytest/runner.py b/_pytest/runner.py index f17155dae..4277f8ee3 100644 --- a/_pytest/runner.py +++ b/_pytest/runner.py @@ -1,4 +1,6 @@ """ basic collect and runtest protocol implementations """ +from __future__ import absolute_import, division, print_function + import bdb import sys from time import time diff --git a/_pytest/setuponly.py b/_pytest/setuponly.py index 1752c575f..15e195ad5 100644 --- a/_pytest/setuponly.py +++ b/_pytest/setuponly.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import, division, print_function + import pytest import sys diff --git a/_pytest/setupplan.py b/_pytest/setupplan.py index f0853dee5..e11bd4069 100644 --- a/_pytest/setupplan.py +++ b/_pytest/setupplan.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import, division, print_function + import pytest diff --git a/_pytest/skipping.py b/_pytest/skipping.py index 86176acaf..228c52935 100644 --- a/_pytest/skipping.py +++ b/_pytest/skipping.py @@ -1,4 +1,6 @@ """ support for skip/xfail functions and markers. """ +from __future__ import absolute_import, division, print_function + import os import sys import traceback diff --git a/_pytest/terminal.py b/_pytest/terminal.py index dd92ddfa3..528772764 100644 --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -2,8 +2,9 @@ This is a good source for looking at the various reporting hooks. """ -import itertools +from __future__ import absolute_import, division, print_function +import itertools from _pytest.main import EXIT_OK, EXIT_TESTSFAILED, EXIT_INTERRUPTED, \ EXIT_USAGEERROR, EXIT_NOTESTSCOLLECTED import pytest diff --git a/_pytest/tmpdir.py b/_pytest/tmpdir.py index 67f999e5a..7c5fac17c 100644 --- a/_pytest/tmpdir.py +++ b/_pytest/tmpdir.py @@ -1,4 +1,6 @@ """ support for providing temporary directories to test functions. """ +from __future__ import absolute_import, division, print_function + import re import pytest diff --git a/_pytest/unittest.py b/_pytest/unittest.py index 276b9ba16..5a8cb9d66 100644 --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -1,5 +1,5 @@ """ discovery and running of std-library "unittest" style tests. """ -from __future__ import absolute_import +from __future__ import absolute_import, division, print_function import sys import traceback diff --git a/doc/en/parametrize.rst b/doc/en/parametrize.rst index b93099e7d..10de065c7 100644 --- a/doc/en/parametrize.rst +++ b/doc/en/parametrize.rst @@ -55,17 +55,17 @@ them in turn:: $ pytest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.7, py-1.4.32, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 3 items - + test_expectation.py ..F - + ======= FAILURES ======== _______ test_eval[6*9-42] ________ - + test_input = '6*9', expected = 42 - + @pytest.mark.parametrize("test_input,expected", [ ("3+5", 8), ("2+4", 6), @@ -73,9 +73,9 @@ them in turn:: ]) def test_eval(test_input, expected): > assert eval(test_input) == expected - E AssertionError: assert 54 == 42 + E assert 54 == 42 E + where 54 = eval('6*9') - + test_expectation.py:8: AssertionError ======= 1 failed, 2 passed in 0.12 seconds ======== @@ -94,21 +94,42 @@ for example with the builtin ``mark.xfail``:: @pytest.mark.parametrize("test_input,expected", [ ("3+5", 8), ("2+4", 6), - pytest.mark.xfail(("6*9", 42)), + pytest.param("6*9", 42, + marks=pytest.mark.xfail), ]) def test_eval(test_input, expected): assert eval(test_input) == expected +.. note:: + + prior to version 3.1 the supported mechanism for marking values + used the syntax:: + + import pytest + @pytest.mark.parametrize("test_input,expected", [ + ("3+5", 8), + ("2+4", 6), + pytest.mark.xfail(("6*9", 42),), + ]) + def test_eval(test_input, expected): + assert eval(test_input) == expected + + + This was an initial hack to support the feature but soon was demonstrated to be incomplete, + broken for passing functions or applying multiple marks with the same name but different parameters. + The old syntax will be removed in pytest-4.0. + + Let's run this:: $ pytest ======= test session starts ======== - platform linux -- Python 3.5.2, pytest-3.0.7, py-1.4.32, pluggy-0.4.0 + platform linux -- Python 3.5.2, pytest-3.0.3, py-1.4.31, pluggy-0.4.0 rootdir: $REGENDOC_TMPDIR, inifile: collected 3 items - + test_expectation.py ..x - + ======= 2 passed, 1 xfailed in 0.12 seconds ======== The one parameter set which caused a failure previously now @@ -181,15 +202,15 @@ Let's also run with a stringinput that will lead to a failing test:: F ======= FAILURES ======== _______ test_valid_string[!] ________ - + stringinput = '!' - + def test_valid_string(stringinput): > assert stringinput.isalpha() - E AssertionError: assert False + E assert False E + where False = () E + where = '!'.isalpha - + test_strings.py:3: AssertionError 1 failed in 0.12 seconds diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 0d3fc1016..debda79ca 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function import os import sys diff --git a/testing/code/test_code.py b/testing/code/test_code.py index a1f31b4a9..479a2e7cc 100644 --- a/testing/code/test_code.py +++ b/testing/code/test_code.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import sys import _pytest._code diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index e2354ff5d..b7dafdb46 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function import operator import _pytest @@ -369,7 +370,7 @@ def test_codepath_Queue_example(): def test_match_succeeds(): with pytest.raises(ZeroDivisionError) as excinfo: - 0 / 0 + 0 // 0 excinfo.match(r'.*zero.*') def test_match_raises_error(testdir): diff --git a/testing/code/test_source.py b/testing/code/test_source.py index c161f75f8..bdbc00d19 100644 --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -1,6 +1,7 @@ # 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, division, print_function import sys import _pytest._code diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index ac1abda9c..0c41a71bf 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import pytest diff --git a/testing/python/collect.py b/testing/python/collect.py index 57dcaf54f..30beb5715 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -274,6 +274,7 @@ class TestGenerator(object): def test_order_of_execution_generator_same_codeline(self, testdir, tmpdir): o = testdir.makepyfile(""" + from __future__ import print_function def test_generative_order_of_execution(): import py, pytest test_list = [] @@ -283,8 +284,8 @@ class TestGenerator(object): test_list.append(item) def assert_order_of_execution(): - py.builtin.print_('expected order', expected_list) - py.builtin.print_('but got ', test_list) + print('expected order', expected_list) + print('but got ', test_list) assert test_list == expected_list for i in expected_list: @@ -298,6 +299,7 @@ class TestGenerator(object): def test_order_of_execution_generator_different_codeline(self, testdir): o = testdir.makepyfile(""" + from __future__ import print_function def test_generative_tests_different_codeline(): import py, pytest test_list = [] @@ -313,8 +315,8 @@ class TestGenerator(object): test_list.append(0) def assert_order_of_execution(): - py.builtin.print_('expected order', expected_list) - py.builtin.print_('but got ', test_list) + print('expected order', expected_list) + print('but got ', test_list) assert test_list == expected_list yield list_append_0 diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 949b265a3..c347dc9e2 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -207,37 +207,40 @@ class TestMetafunc(object): @pytest.mark.issue250 def test_idmaker_autoname(self): from _pytest.python import idmaker - result = idmaker(("a", "b"), [("string", 1.0), - ("st-ring", 2.0)]) + result = idmaker(("a", "b"), [pytest.param("string", 1.0), + pytest.param("st-ring", 2.0)]) assert result == ["string-1.0", "st-ring-2.0"] - result = idmaker(("a", "b"), [(object(), 1.0), - (object(), object())]) + result = idmaker(("a", "b"), [pytest.param(object(), 1.0), + pytest.param(object(), object())]) assert result == ["a0-1.0", "a1-b1"] # unicode mixing, issue250 - result = idmaker((py.builtin._totext("a"), "b"), [({}, b'\xc3\xb4')]) + result = idmaker( + (py.builtin._totext("a"), "b"), + [pytest.param({}, b'\xc3\xb4')]) assert result == ['a0-\\xc3\\xb4'] def test_idmaker_with_bytes_regex(self): from _pytest.python import idmaker - result = idmaker(("a"), [(re.compile(b'foo'), 1.0)]) + result = idmaker(("a"), [pytest.param(re.compile(b'foo'), 1.0)]) assert result == ["foo"] def test_idmaker_native_strings(self): from _pytest.python import idmaker totext = py.builtin._totext - result = idmaker(("a", "b"), [(1.0, -1.1), - (2, -202), - ("three", "three hundred"), - (True, False), - (None, None), - (re.compile('foo'), re.compile('bar')), - (str, int), - (list("six"), [66, 66]), - (set([7]), set("seven")), - (tuple("eight"), (8, -8, 8)), - (b'\xc3\xb4', b"name"), - (b'\xc3\xb4', totext("other")), + result = idmaker(("a", "b"), [ + pytest.param(1.0, -1.1), + pytest.param(2, -202), + pytest.param("three", "three hundred"), + pytest.param(True, False), + pytest.param(None, None), + pytest.param(re.compile('foo'), re.compile('bar')), + pytest.param(str, int), + pytest.param(list("six"), [66, 66]), + pytest.param(set([7]), set("seven")), + pytest.param(tuple("eight"), (8, -8, 8)), + pytest.param(b'\xc3\xb4', b"name"), + pytest.param(b'\xc3\xb4', totext("other")), ]) assert result == ["1.0--1.1", "2--202", @@ -257,7 +260,7 @@ class TestMetafunc(object): from _pytest.python import idmaker enum = pytest.importorskip("enum") e = enum.Enum("Foo", "one, two") - result = idmaker(("a", "b"), [(e.one, e.two)]) + result = idmaker(("a", "b"), [pytest.param(e.one, e.two)]) assert result == ["Foo.one-Foo.two"] @pytest.mark.issue351 @@ -268,9 +271,10 @@ class TestMetafunc(object): if isinstance(val, Exception): return repr(val) - result = idmaker(("a", "b"), [(10.0, IndexError()), - (20, KeyError()), - ("three", [1, 2, 3]), + result = idmaker(("a", "b"), [ + pytest.param(10.0, IndexError()), + pytest.param(20, KeyError()), + pytest.param("three", [1, 2, 3]), ], idfn=ids) assert result == ["10.0-IndexError()", "20-KeyError()", @@ -284,9 +288,9 @@ class TestMetafunc(object): def ids(val): return 'a' - result = idmaker(("a", "b"), [(10.0, IndexError()), - (20, KeyError()), - ("three", [1, 2, 3]), + result = idmaker(("a", "b"), [pytest.param(10.0, IndexError()), + pytest.param(20, KeyError()), + pytest.param("three", [1, 2, 3]), ], idfn=ids) assert result == ["a-a0", "a-a1", @@ -306,9 +310,10 @@ class TestMetafunc(object): rec = WarningsRecorder() with rec: - idmaker(("a", "b"), [(10.0, IndexError()), - (20, KeyError()), - ("three", [1, 2, 3]), + idmaker(("a", "b"), [ + pytest.param(10.0, IndexError()), + pytest.param(20, KeyError()), + pytest.param("three", [1, 2, 3]), ], idfn=ids) assert [str(i.message) for i in rec.list] == [ @@ -351,14 +356,21 @@ class TestMetafunc(object): def test_idmaker_with_ids(self): from _pytest.python import idmaker - result = idmaker(("a", "b"), [(1, 2), - (3, 4)], + result = idmaker(("a", "b"), [pytest.param(1, 2), + pytest.param(3, 4)], ids=["a", None]) assert result == ["a", "3-4"] + def test_idmaker_with_paramset_id(self): + from _pytest.python import idmaker + result = idmaker(("a", "b"), [pytest.param(1, 2, id="me"), + pytest.param(3, 4, id="you")], + ids=["a", None]) + assert result == ["me", "you"] + def test_idmaker_with_ids_unique_names(self): from _pytest.python import idmaker - result = idmaker(("a"), [1,2,3,4,5], + result = idmaker(("a"), map(pytest.param, [1,2,3,4,5]), ids=["a", "a", "b", "c", "b"]) assert result == ["a0", "a1", "b0", "c", "b1"] @@ -1438,6 +1450,31 @@ class TestMarkersWithParametrization(object): reprec = testdir.inline_run() reprec.assertoutcome(passed=2) + + @pytest.mark.parametrize('strict', [True, False]) + def test_parametrize_marked_value(self, testdir, strict): + s = """ + import pytest + + @pytest.mark.parametrize(("n", "expected"), [ + pytest.param( + 2,3, + marks=pytest.mark.xfail("sys.version_info > (0, 0, 0)", reason="some bug", strict={strict}), + ), + pytest.param( + 2,3, + marks=[pytest.mark.xfail("sys.version_info > (0, 0, 0)", reason="some bug", strict={strict})], + ), + ]) + def test_increment(n, expected): + assert n + 1 == expected + """.format(strict=strict) + testdir.makepyfile(s) + reprec = testdir.inline_run() + passed, failed = (0, 2) if strict else (2, 0) + reprec.assertoutcome(passed=passed, failed=failed) + + def test_pytest_make_parametrize_id(self, testdir): testdir.makeconftest(""" def pytest_make_parametrize_id(config, val): diff --git a/testing/test_argcomplete.py b/testing/test_argcomplete.py index ed6db4c78..6887c419c 100644 --- a/testing/test_argcomplete.py +++ b/testing/test_argcomplete.py @@ -1,4 +1,4 @@ -from __future__ import with_statement +from __future__ import absolute_import, division, print_function import py, pytest # test for _argcomplete but not specific for any application diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 2c04df63e..c385f6aa1 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function import sys import textwrap diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index 047a2ac6e..f4fc0c464 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import glob import os import py_compile diff --git a/testing/test_cache.py b/testing/test_cache.py index c1b98489e..47072e07e 100755 --- a/testing/test_cache.py +++ b/testing/test_cache.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import sys import _pytest diff --git a/testing/test_capture.py b/testing/test_capture.py index 28326fa73..aa2a3bae5 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function # note: py.io capture tests where copied from # pylib 1.4.20.dev2 (rev 13d9af95547e) from __future__ import with_statement @@ -13,7 +14,7 @@ import contextlib from _pytest import capture from _pytest.capture import CaptureManager from _pytest.main import EXIT_NOTESTSCOLLECTED -from py.builtin import print_ + needsosdup = pytest.mark.xfail("not hasattr(os, 'dup')") @@ -711,7 +712,7 @@ def test_dupfile(tmpfile): assert nf != tmpfile assert nf.fileno() != tmpfile.fileno() assert nf not in flist - print_(i, end="", file=nf) + print(i, end="", file=nf) flist.append(nf) for i in range(5): f = flist[i] @@ -785,7 +786,7 @@ class TestFDCapture(object): def test_stderr(self): cap = capture.FDCapture(2) cap.start() - print_("hello", file=sys.stderr) + print("hello", file=sys.stderr) s = cap.snap() cap.done() assert s == "hello\n" diff --git a/testing/test_collection.py b/testing/test_collection.py index 8575aa63a..c19fc0e72 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import pytest, py from _pytest.main import Session, EXIT_NOTESTSCOLLECTED diff --git a/testing/test_compat.py b/testing/test_compat.py index 1736e8e2a..7b2251ef6 100644 --- a/testing/test_compat.py +++ b/testing/test_compat.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import sys import pytest diff --git a/testing/test_config.py b/testing/test_config.py index 40b944adc..fed781ce0 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import py, pytest import _pytest._code diff --git a/testing/test_conftest.py b/testing/test_conftest.py index e9fd1927a..db67a0cc8 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function from textwrap import dedent import _pytest._code diff --git a/testing/test_doctest.py b/testing/test_doctest.py index 429bb8de9..82597b477 100644 --- a/testing/test_doctest.py +++ b/testing/test_doctest.py @@ -1,4 +1,5 @@ # encoding: utf-8 +from __future__ import absolute_import, division, print_function import sys import _pytest._code from _pytest.compat import MODULE_NOT_FOUND_ERROR diff --git a/testing/test_entry_points.py b/testing/test_entry_points.py index 370b93129..6ca68b481 100644 --- a/testing/test_entry_points.py +++ b/testing/test_entry_points.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import pkg_resources import pytest diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index fc3c8fdf6..6eecbfd37 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function from _pytest.main import EXIT_NOTESTSCOLLECTED import pytest diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index a87745350..7003d9f5f 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- - +from __future__ import absolute_import, division, print_function from xml.dom import minidom import py import sys diff --git a/testing/test_mark.py b/testing/test_mark.py index 9474d1033..9a8c35bf3 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -1,7 +1,9 @@ +from __future__ import absolute_import, division, print_function import os +import sys -import py, pytest -from _pytest.mark import MarkGenerator as Mark +import pytest +from _pytest.mark import MarkGenerator as Mark, ParameterSet class TestMark(object): def test_markinfo_repr(self): @@ -9,9 +11,11 @@ class TestMark(object): m = MarkInfo(Mark("hello", (1,2), {})) repr(m) - def test_pytest_exists_in_namespace_all(self): - assert 'mark' in py.test.__all__ - assert 'mark' in pytest.__all__ + @pytest.mark.parametrize('attr', ['mark', 'param']) + @pytest.mark.parametrize('modulename', ['py.test', 'pytest']) + def test_pytest_exists_in_namespace_all(self, attr, modulename): + module = sys.modules[modulename] + assert attr in module.__all__ def test_pytest_mark_notcallable(self): mark = Mark() @@ -414,7 +418,7 @@ class TestFunctional(object): """) items, rec = testdir.inline_genitems(p) for item in items: - print (item, item.keywords) + print(item, item.keywords) assert 'a' in item.keywords def test_mark_decorator_subclass_does_not_propagate_to_base(self, testdir): @@ -673,7 +677,7 @@ class TestKeywordSelection(object): item.extra_keyword_matches.add("xxx") """) reprec = testdir.inline_run(p.dirpath(), '-s', '-k', keyword) - py.builtin.print_("keyword", repr(keyword)) + print("keyword", repr(keyword)) passed, skipped, failed = reprec.listoutcomes() assert len(passed) == 1 assert passed[0].nodeid.endswith("test_2") @@ -738,3 +742,16 @@ class TestKeywordSelection(object): assert_test_is_not_selected("__") assert_test_is_not_selected("()") + + +@pytest.mark.parametrize('argval, expected', [ + (pytest.mark.skip()((1, 2)), + ParameterSet(values=(1, 2), marks=[pytest.mark.skip], id=None)), + (pytest.mark.xfail(pytest.mark.skip()((1, 2))), + ParameterSet(values=(1, 2), + marks=[pytest.mark.xfail, pytest.mark.skip], id=None)), + +]) +def test_parameterset_extractfrom(argval, expected): + extracted = ParameterSet.extract_from(argval) + assert extracted == expected diff --git a/testing/test_monkeypatch.py b/testing/test_monkeypatch.py index 04a53d93a..1efcf7f95 100644 --- a/testing/test_monkeypatch.py +++ b/testing/test_monkeypatch.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import os import sys import textwrap diff --git a/testing/test_nose.py b/testing/test_nose.py index 11fb83176..798badc1c 100644 --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import pytest def setup_module(mod): diff --git a/testing/test_parseopt.py b/testing/test_parseopt.py index 03d71de43..f990e8b04 100644 --- a/testing/test_parseopt.py +++ b/testing/test_parseopt.py @@ -1,4 +1,4 @@ -from __future__ import with_statement +from __future__ import absolute_import, division, print_function import sys import os import py, pytest diff --git a/testing/test_pastebin.py b/testing/test_pastebin.py index f0d2a9ba2..3fe66e972 100644 --- a/testing/test_pastebin.py +++ b/testing/test_pastebin.py @@ -1,4 +1,5 @@ # encoding: utf-8 +from __future__ import absolute_import, division, print_function import sys import pytest diff --git a/testing/test_pdb.py b/testing/test_pdb.py index 161b4f5f7..ec5862082 100644 --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import sys import platform diff --git a/testing/test_pluginmanager.py b/testing/test_pluginmanager.py index 3f4ce9aad..1f0f4f602 100644 --- a/testing/test_pluginmanager.py +++ b/testing/test_pluginmanager.py @@ -1,4 +1,5 @@ # encoding: UTF-8 +from __future__ import absolute_import, division, print_function import pytest import py import os diff --git a/testing/test_pytester.py b/testing/test_pytester.py index 9c9b56371..932427ad3 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import pytest import os from _pytest.pytester import HookRecorder diff --git a/testing/test_recwarn.py b/testing/test_recwarn.py index 5d5a68c89..0f921f057 100644 --- a/testing/test_recwarn.py +++ b/testing/test_recwarn.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import warnings import re import py diff --git a/testing/test_resultlog.py b/testing/test_resultlog.py index c2f4a801c..cb083225c 100644 --- a/testing/test_resultlog.py +++ b/testing/test_resultlog.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import os import _pytest._code diff --git a/testing/test_runner.py b/testing/test_runner.py index 265e99d54..51d430fc8 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import with_statement +from __future__ import absolute_import, division, print_function import _pytest._code import os diff --git a/testing/test_runner_xunit.py b/testing/test_runner_xunit.py index 9bf15bd66..92ba97202 100644 --- a/testing/test_runner_xunit.py +++ b/testing/test_runner_xunit.py @@ -1,6 +1,8 @@ -# -# test correct setup/teardowns at -# module, class, and instance level +""" + test correct setup/teardowns at + module, class, and instance level +""" +from __future__ import absolute_import, division, print_function import pytest diff --git a/testing/test_session.py b/testing/test_session.py index 66a0f5978..d08f7b3e2 100644 --- a/testing/test_session.py +++ b/testing/test_session.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import pytest from _pytest.main import EXIT_NOTESTSCOLLECTED diff --git a/testing/test_skipping.py b/testing/test_skipping.py index f621a010f..5f25c3e6e 100644 --- a/testing/test_skipping.py +++ b/testing/test_skipping.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import pytest import sys diff --git a/testing/test_terminal.py b/testing/test_terminal.py index e2d92cb98..5a90b3dd4 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -1,6 +1,7 @@ """ terminal reporting of the full testing process. """ +from __future__ import absolute_import, division, print_function import collections import sys diff --git a/testing/test_tmpdir.py b/testing/test_tmpdir.py index 32ac76331..ccd70ed8b 100644 --- a/testing/test_tmpdir.py +++ b/testing/test_tmpdir.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function import sys import py import pytest diff --git a/testing/test_unittest.py b/testing/test_unittest.py index 832ea08cc..af9851997 100644 --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -1,3 +1,4 @@ +from __future__ import absolute_import, division, print_function from _pytest.main import EXIT_NOTESTSCOLLECTED import pytest import gc