diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8e0ba82e4..22f3ac862 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -18,6 +18,31 @@ with advance notice in the **Deprecations** section of releases. .. towncrier release notes start +pytest 4.0.2 (2018-12-13) +========================= + +Bug Fixes +--------- + +- `#4265 `_: Validate arguments from the ``PYTEST_ADDOPTS`` environment variable and the ``addopts`` ini option separately. + + +- `#4435 `_: Fix ``raises(..., 'code(string)')`` frame filename. + + +- `#4500 `_: When a fixture yields and a log call is made after the test runs, and, if the test is interrupted, capture attributes are ``None``. + + +- `#4538 `_: Raise ``TypeError`` for ``with raises(..., match=)``. + + + +Improved Documentation +---------------------- + +- `#1495 `_: Document common doctest fixture directory tree structure pitfalls + + pytest 4.0.1 (2018-11-23) ========================= diff --git a/changelog/1495.doc.rst b/changelog/1495.doc.rst deleted file mode 100644 index ab7231333..000000000 --- a/changelog/1495.doc.rst +++ /dev/null @@ -1 +0,0 @@ -Document common doctest fixture directory tree structure pitfalls diff --git a/changelog/2169.removal.rst b/changelog/2169.removal.rst new file mode 100644 index 000000000..272ddbdfb --- /dev/null +++ b/changelog/2169.removal.rst @@ -0,0 +1 @@ +``pytest.mark.parametrize``: in previous versions, errors raised by id functions were suppressed and changed into warnings. Now the exceptions are propagated, along with a pytest message informing the node, parameter value and index where the exception occurred. diff --git a/changelog/3050.deprecation.rst b/changelog/3050.deprecation.rst index 2da417c85..fce5979d6 100644 --- a/changelog/3050.deprecation.rst +++ b/changelog/3050.deprecation.rst @@ -1 +1,3 @@ -Deprecate ``pytest.config`` global. See https://docs.pytest.org/en/latest/deprecations.html#pytest-config-global +Deprecated the ``pytest.config`` global. + +See https://docs.pytest.org/en/latest/deprecations.html#pytest-config-global for rationale. diff --git a/changelog/3079.removal.rst b/changelog/3079.removal.rst index 19a8612f0..cb2265ff3 100644 --- a/changelog/3079.removal.rst +++ b/changelog/3079.removal.rst @@ -1,3 +1,3 @@ -Remove support for yield tests - they are fundamentally broken because they don't support fixtures properly since collection and test execution were separated. +Removed support for yield tests - they are fundamentally broken because they don't support fixtures properly since collection and test execution were separated. See our `docs `__ on information on how to update your code. diff --git a/changelog/3083.removal.rst b/changelog/3083.removal.rst index ce689b94a..74d268a4e 100644 --- a/changelog/3083.removal.rst +++ b/changelog/3083.removal.rst @@ -1,3 +1,3 @@ -Remove ``Metafunc.addcall``. This was the predecessor mechanism to ``@pytest.mark.parametrize``. +Removed ``Metafunc.addcall``. This was the predecessor mechanism to ``@pytest.mark.parametrize``. See our `docs `__ on information on how to update your code. diff --git a/changelog/3085.removal.rst b/changelog/3085.removal.rst new file mode 100644 index 000000000..67ba04c28 --- /dev/null +++ b/changelog/3085.removal.rst @@ -0,0 +1,3 @@ +Removed support for passing strings to ``pytest.main``. Now, always pass a list of strings instead. + +See our `docs `__ on information on how to update your code. diff --git a/changelog/3191.feature.rst b/changelog/3191.feature.rst index 7eb4c3a15..dbf1c8304 100644 --- a/changelog/3191.feature.rst +++ b/changelog/3191.feature.rst @@ -1,16 +1,22 @@ A warning is now issued when assertions are made for ``None``. -This is a common source of confusion among new users, which write:: +This is a common source of confusion among new users, which write: - assert mocked_object.assert_called_with(3, 4, 5, key='value') +.. code-block:: python -When they should write:: + assert mocked_object.assert_called_with(3, 4, 5, key="value") - mocked_object.assert_called_with(3, 4, 5, key='value') +When they should write: + +.. code-block:: python + + mocked_object.assert_called_with(3, 4, 5, key="value") Because the ``assert_called_with`` method of mock objects already executes an assertion. -This warning will not be issued when ``None`` is explicitly checked. An assertion like:: +This warning will not be issued when ``None`` is explicitly checked. An assertion like: + +.. code-block:: python assert variable is None diff --git a/changelog/3616.removal.rst b/changelog/3616.removal.rst index a8f2f1c92..5d8c9134e 100644 --- a/changelog/3616.removal.rst +++ b/changelog/3616.removal.rst @@ -1,3 +1,3 @@ -Remove the deprecated compat properties for ``node.Class/Function/Module`` - use ``pytest.Class/Function/Module`` now. +Removed the deprecated compat properties for ``node.Class/Function/Module`` - use ``pytest.Class/Function/Module`` now. See our `docs `__ on information on how to update your code. diff --git a/changelog/4265.bugfix.rst b/changelog/4265.bugfix.rst deleted file mode 100644 index 7b40737c3..000000000 --- a/changelog/4265.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -Validate arguments from the ``PYTEST_ADDOPTS`` environment variable and the ``addopts`` ini option separately. diff --git a/changelog/4278.feature.rst b/changelog/4278.feature.rst new file mode 100644 index 000000000..332e64572 --- /dev/null +++ b/changelog/4278.feature.rst @@ -0,0 +1,4 @@ +``CACHEDIR.TAG`` files are now created inside cache directories. + +Those files are part of the `Cache Directory Tagging Standard `__, and can +be used by backup or synchronization programs to identify pytest's cache directory as such. diff --git a/changelog/4278.trivial.rst b/changelog/4278.trivial.rst deleted file mode 100644 index 126cabea8..000000000 --- a/changelog/4278.trivial.rst +++ /dev/null @@ -1 +0,0 @@ -A CACHEDIR.TAG file gets added to the cache directory. diff --git a/changelog/4292.feature.rst b/changelog/4292.feature.rst index 27d113ba0..760a27783 100644 --- a/changelog/4292.feature.rst +++ b/changelog/4292.feature.rst @@ -1 +1 @@ -``pytest.outcomes.Exit`` is derived from ``SystemExit`` instead of ``KeyboardInterrupt``. +``pytest.outcomes.Exit`` is derived from ``SystemExit`` instead of ``KeyboardInterrupt``. This allows us to better handle ``pdb`` exiting. diff --git a/changelog/4386.feature.rst b/changelog/4386.feature.rst index fe827cc23..5133a39a7 100644 --- a/changelog/4386.feature.rst +++ b/changelog/4386.feature.rst @@ -1 +1 @@ -Restructure ExceptionInfo object construction and ensure incomplete instances have a ``repr``/``str``. +Restructured ``ExceptionInfo`` object construction and ensure incomplete instances have a ``repr``/``str``. diff --git a/changelog/4416.feature.rst b/changelog/4416.feature.rst index 89c0a84b1..949e7c25a 100644 --- a/changelog/4416.feature.rst +++ b/changelog/4416.feature.rst @@ -1,4 +1,4 @@ -pdb: support keyword arguments with ``pdb.set_trace`` +pdb: added support for keyword arguments with ``pdb.set_trace``. It handles ``header`` similar to Python 3.7 does it, and forwards any other keyword arguments to the ``Pdb`` constructor. diff --git a/changelog/4421.removal.rst b/changelog/4421.removal.rst index 279587d06..4bebd5c19 100644 --- a/changelog/4421.removal.rst +++ b/changelog/4421.removal.rst @@ -1,3 +1,3 @@ -Remove the implementation of the ``pytest_namespace`` hook. +Removed the implementation of the ``pytest_namespace`` hook. See our `docs `__ on information on how to update your code. diff --git a/changelog/4435.bugfix.rst b/changelog/4435.bugfix.rst index de60b5e62..36ace1fab 100644 --- a/changelog/4435.bugfix.rst +++ b/changelog/4435.bugfix.rst @@ -1 +1 @@ -Fix ``raises(..., 'code(string)')`` frame filename. +Fixed ``raises(..., 'code(string)')`` frame filename. diff --git a/changelog/4435.deprecation.rst b/changelog/4435.deprecation.rst index f12f0bc6c..6815c1776 100644 --- a/changelog/4435.deprecation.rst +++ b/changelog/4435.deprecation.rst @@ -1 +1,3 @@ -Deprecate ``raises(..., 'code(as_a_string)')`` and ``warns(..., 'code(as_a_string)')``. See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec +Deprecated ``raises(..., 'code(as_a_string)')`` and ``warns(..., 'code(as_a_string)')``. + +See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec for rationale and examples. diff --git a/changelog/4483.feature.rst b/changelog/4483.feature.rst index d9bd4c717..9b3018707 100644 --- a/changelog/4483.feature.rst +++ b/changelog/4483.feature.rst @@ -1,2 +1,9 @@ -Add ini parameter ``junit_time`` to optionally report test call -durations less setup and teardown times. +Added ini parameter ``junit_duration_report`` to optionally report test call durations, excluding setup and teardown times. + +The JUnit XML specification and the default pytest behavior is to include setup and teardown times in the test duration +report. You can include just the call durations instead (excluding setup and teardown) by adding this to your ``pytest.ini`` file: + +.. code-block:: ini + + [pytest] + junit_duration_report = call diff --git a/changelog/4500.bugfix.rst b/changelog/4500.bugfix.rst deleted file mode 100644 index b84b6b117..000000000 --- a/changelog/4500.bugfix.rst +++ /dev/null @@ -1 +0,0 @@ -When a fixture yields and a log call is made after the test runs, and, if the test is interrupted, capture attributes are ``None``. diff --git a/changelog/4535.removal.rst b/changelog/4535.removal.rst index f89900587..89de6b744 100644 --- a/changelog/4535.removal.rst +++ b/changelog/4535.removal.rst @@ -1 +1 @@ -Removed deprecated ``PyCollector.makeitem`` method. This method was made public by mistake a long time ago. +Removed the deprecated ``PyCollector.makeitem`` method. This method was made public by mistake a long time ago. diff --git a/changelog/4543.removal.rst b/changelog/4543.removal.rst new file mode 100644 index 000000000..0a2b615f9 --- /dev/null +++ b/changelog/4543.removal.rst @@ -0,0 +1,3 @@ +Removed support to define fixtures using the ``pytest_funcarg__`` prefix. Use the ``@pytest.fixture`` decorator instead. + +See our `docs `__ on information on how to update your code. diff --git a/changelog/4547.removal.rst b/changelog/4547.removal.rst new file mode 100644 index 000000000..a30d5d7bd --- /dev/null +++ b/changelog/4547.removal.rst @@ -0,0 +1,3 @@ +The deprecated ``record_xml_property`` fixture has been removed, use the more generic ``record_property`` instead. + +See our `docs `__ for more information. diff --git a/doc/en/announce/index.rst b/doc/en/announce/index.rst index 4120ccfc9..d6379f1b3 100644 --- a/doc/en/announce/index.rst +++ b/doc/en/announce/index.rst @@ -6,6 +6,7 @@ Release announcements :maxdepth: 2 + release-4.0.2 release-4.0.1 release-4.0.0 release-3.10.1 diff --git a/doc/en/announce/release-4.0.2.rst b/doc/en/announce/release-4.0.2.rst new file mode 100644 index 000000000..3b6e4be71 --- /dev/null +++ b/doc/en/announce/release-4.0.2.rst @@ -0,0 +1,24 @@ +pytest-4.0.2 +======================================= + +pytest 4.0.2 has just been released to PyPI. + +This is a bug-fix release, being a drop-in replacement. To upgrade:: + + pip install --upgrade pytest + +The full changelog is available at https://docs.pytest.org/en/latest/changelog.html. + +Thanks to all who contributed to this release, among them: + +* Anthony Sottile +* Bruno Oliveira +* Daniel Hahler +* Pedro Algarvio +* Ronny Pfannschmidt +* Tomer Keren +* Yash Todi + + +Happy testing, +The pytest Development Team diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index f36423ad6..8cc259cb1 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -121,28 +121,6 @@ As part of a large :ref:`marker-revamp`, :meth:`_pytest.nodes.Node.get_marker` i :ref:`the documentation ` on tips on how to update your code. -record_xml_property -~~~~~~~~~~~~~~~~~~~ - -.. deprecated:: 3.5 - -The ``record_xml_property`` fixture is now deprecated in favor of the more generic ``record_property``, which -can be used by other consumers (for example ``pytest-html``) to obtain custom information about the test run. - -This is just a matter of renaming the fixture as the API is the same: - -.. code-block:: python - - def test_foo(record_xml_property): - ... - -Change to: - -.. code-block:: python - - def test_foo(record_property): - ... - pytest_plugins in non-top-level conftest files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -187,47 +165,6 @@ To update the code, use ``pytest.param``: -Passing command-line string to ``pytest.main()`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. deprecated:: 3.0 - -Passing a command-line string to ``pytest.main()`` is deprecated: - -.. code-block:: python - - pytest.main("-v -s") - -Pass a list instead: - -.. code-block:: python - - pytest.main(["-v", "-s"]) - - -By passing a string, users expect that pytest will interpret that command-line using the shell rules they are working -on (for example ``bash`` or ``Powershell``), but this is very hard/impossible to do in a portable way. - - -``pytest_funcarg__`` prefix -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. deprecated:: 3.0 - -In very early pytest versions fixtures could be defined using the ``pytest_funcarg__`` prefix: - -.. code-block:: python - - def pytest_funcarg__data(): - return SomeData() - -Switch over to the ``@pytest.fixture`` decorator: - -.. code-block:: python - - @pytest.fixture - def data(): - return SomeData() [pytest] section in setup.cfg files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -267,6 +204,27 @@ collection. This issue should affect only advanced plugins who create new collection types, so if you see this warning message please contact the authors so they can change the code. +``pytest_funcarg__`` prefix +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +*Removed in version 4.0.* + +In very early pytest versions fixtures could be defined using the ``pytest_funcarg__`` prefix: + +.. code-block:: python + + def pytest_funcarg__data(): + return SomeData() + +Switch over to the ``@pytest.fixture`` decorator: + +.. code-block:: python + + @pytest.fixture + def data(): + return SomeData() + + Metafunc.addcall ~~~~~~~~~~~~~~~~ @@ -350,6 +308,52 @@ Becomes: * ``node.warn("CI", "some message")``: this code/message form has been **removed** and should be converted to the warning instance form above. +record_xml_property +~~~~~~~~~~~~~~~~~~~ + +*Removed in version 4.0.* + +The ``record_xml_property`` fixture is now deprecated in favor of the more generic ``record_property``, which +can be used by other consumers (for example ``pytest-html``) to obtain custom information about the test run. + +This is just a matter of renaming the fixture as the API is the same: + +.. code-block:: python + + def test_foo(record_xml_property): + ... + +Change to: + +.. code-block:: python + + def test_foo(record_property): + ... + + +Passing command-line string to ``pytest.main()`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +*Removed in version 4.0.* + +Passing a command-line string to ``pytest.main()`` is deprecated: + +.. code-block:: python + + pytest.main("-v -s") + +Pass a list instead: + +.. code-block:: python + + pytest.main(["-v", "-s"]) + + +By passing a string, users expect that pytest will interpret that command-line using the shell rules they are working +on (for example ``bash`` or ``Powershell``), but this is very hard/impossible to do in a portable way. + + + ``yield`` tests ~~~~~~~~~~~~~~~ diff --git a/doc/en/example/parametrize.rst b/doc/en/example/parametrize.rst index bb8ea5996..d4540fe5e 100644 --- a/doc/en/example/parametrize.rst +++ b/doc/en/example/parametrize.rst @@ -538,7 +538,7 @@ Then run ``pytest`` with verbose mode and with only the ``basic`` marker: $ pytest -v -m basic =========================== test session starts ============================ - platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python + platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6 cachedir: .pytest_cache rootdir: $REGENDOC_TMPDIR, inifile: collecting ... collected 17 items / 14 deselected diff --git a/doc/en/usage.rst b/doc/en/usage.rst index 7c3ef19fb..865e007f5 100644 --- a/doc/en/usage.rst +++ b/doc/en/usage.rst @@ -301,12 +301,12 @@ should report total test execution times, including setup and teardown (`1 `_, `2 `_). It is the default pytest behavior. To report just call durations -instead, configure the ``junit_time`` option like this: +instead, configure the ``junit_duration_report`` option like this: .. code-block:: ini [pytest] - junit_time = call + junit_duration_report = call .. _record_property example: diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 248ed5857..9ad7da008 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -175,12 +175,9 @@ def _prepareconfig(args=None, plugins=None): elif isinstance(args, py.path.local): args = [str(args)] elif not isinstance(args, (tuple, list)): - if not isinstance(args, str): - raise ValueError("not a string or argument list: %r" % (args,)) - args = shlex.split(args, posix=sys.platform != "win32") - from _pytest import deprecated + msg = "`args` parameter expected to be a list or tuple of strings, got: {!r} (type: {})" + raise TypeError(msg.format(args, type(args))) - warning = deprecated.MAIN_STR_ARGS config = get_config() pluginmanager = config.pluginmanager try: @@ -256,8 +253,8 @@ class PytestPluginManager(PluginManager): # (see issue #1073) if not name.startswith("pytest_"): return - # ignore some historic special names which can not be hooks anyway - if name == "pytest_plugins" or name.startswith("pytest_funcarg__"): + # ignore names which can not be hooks + if name == "pytest_plugins": return method = getattr(plugin, name) diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index 4136328e1..30020a9ab 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -17,19 +17,8 @@ from _pytest.warning_types import RemovedInPytest4Warning from _pytest.warning_types import UnformattedWarning -MAIN_STR_ARGS = RemovedInPytest4Warning( - "passing a string to pytest.main() is deprecated, " - "pass a list of arguments instead." -) - YIELD_TESTS = "yield tests were removed in pytest 4.0 - {name} will be ignored" -FUNCARG_PREFIX = UnformattedWarning( - RemovedInPytest4Warning, - '{name}: declaring fixtures using "pytest_funcarg__" prefix is deprecated ' - "and scheduled to be removed in pytest 4.0. " - "Please remove the prefix and use the @pytest.fixture decorator instead.", -) FIXTURE_FUNCTION_CALL = UnformattedWarning( RemovedInPytest4Warning, @@ -84,20 +73,6 @@ WARNS_EXEC = PytestDeprecationWarning( "See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec" ) -RECORD_XML_PROPERTY = RemovedInPytest4Warning( - 'Fixture renamed from "record_xml_property" to "record_property" as user ' - "properties are now available to all reporters.\n" - '"record_xml_property" is now deprecated.' -) - -PLUGIN_MANAGER_ADDHOOKS = PytestDeprecationWarning( - "use pluginmanager.add_hookspecs instead of deprecated addhooks() method." -) - -COLLECTOR_MAKEITEM = RemovedInPytest4Warning( - "pycollector makeitem was removed as it is an accidentially leaked internal api" -) - PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST = RemovedInPytest4Warning( "Defining pytest_plugins in a non-top-level conftest is deprecated, " "because it affects the entire directory tree in a non-explicit way.\n" diff --git a/src/_pytest/fixtures.py b/src/_pytest/fixtures.py index 3e5ad5f73..0136dea09 100644 --- a/src/_pytest/fixtures.py +++ b/src/_pytest/fixtures.py @@ -38,8 +38,6 @@ from _pytest.deprecated import FIXTURE_NAMED_REQUEST from _pytest.outcomes import fail from _pytest.outcomes import TEST_OUTCOME -FIXTURE_MSG = 'fixtures cannot have "pytest_funcarg__" prefix and be decorated with @pytest.fixture:\n{}' - @attr.s(frozen=True) class PseudoFixtureDef(object): @@ -1117,7 +1115,6 @@ class FixtureManager(object): by a lookup of their FuncFixtureInfo. """ - _argprefix = "pytest_funcarg__" FixtureLookupError = FixtureLookupError FixtureLookupErrorRepr = FixtureLookupErrorRepr @@ -1255,8 +1252,6 @@ class FixtureManager(object): items[:] = reorder_items(items) def parsefactories(self, node_or_obj, nodeid=NOTSET, unittest=False): - from _pytest import deprecated - if nodeid is not NOTSET: holderobj = node_or_obj else: @@ -1272,31 +1267,13 @@ class FixtureManager(object): # access below can raise. safe_getatt() ignores such exceptions. obj = safe_getattr(holderobj, name, None) marker = getfixturemarker(obj) - # fixture functions have a pytest_funcarg__ prefix (pre-2.3 style) - # or are "@pytest.fixture" marked - if marker is None: - if not name.startswith(self._argprefix): - continue - if not callable(obj): - continue - marker = defaultfuncargprefixmarker - - filename, lineno = getfslineno(obj) - warnings.warn_explicit( - deprecated.FUNCARG_PREFIX.format(name=name), - category=None, - filename=str(filename), - lineno=lineno + 1, - ) - name = name[len(self._argprefix) :] - elif not isinstance(marker, FixtureFunctionMarker): + if not isinstance(marker, FixtureFunctionMarker): # magic globals with __getattr__ might have got us a wrong # fixture attribute continue - else: - if marker.name: - name = marker.name - assert not name.startswith(self._argprefix), FIXTURE_MSG.format(name) + + if marker.name: + name = marker.name # during fixture definition we wrap the original fixture function # to issue a warning if called directly, so here we unwrap it in order to not emit the warning diff --git a/src/_pytest/junitxml.py b/src/_pytest/junitxml.py index 696deb6e9..1a06ea6d1 100644 --- a/src/_pytest/junitxml.py +++ b/src/_pytest/junitxml.py @@ -263,16 +263,6 @@ def record_property(request): return append_property -@pytest.fixture -def record_xml_property(record_property, request): - """(Deprecated) use record_property.""" - from _pytest import deprecated - - request.node.warn(deprecated.RECORD_XML_PROPERTY) - - return record_property - - @pytest.fixture def record_xml_attribute(request): """Add extra xml attributes to the tag for the calling test. @@ -324,7 +314,9 @@ def pytest_addoption(parser): default="no", ) # choices=['no', 'stdout', 'stderr']) parser.addini( - "junit_time", "Duration time to report: one of total|call", default="total" + "junit_duration_report", + "Duration time to report: one of total|call", + default="total", ) # choices=['total', 'call']) @@ -337,7 +329,7 @@ def pytest_configure(config): config.option.junitprefix, config.getini("junit_suite_name"), config.getini("junit_logging"), - config.getini("junit_time"), + config.getini("junit_duration_report"), ) config.pluginmanager.register(config._xml) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index a872a86ed..5a77b09ad 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -45,7 +45,6 @@ from _pytest.mark.structures import transfer_markers from _pytest.outcomes import fail from _pytest.pathlib import parts from _pytest.warning_types import PytestWarning -from _pytest.warning_types import RemovedInPytest4Warning def pyobj_property(name): @@ -1059,13 +1058,11 @@ def _idval(val, argname, idx, idfn, item, config): s = idfn(val) except Exception as e: # See issue https://github.com/pytest-dev/pytest/issues/2169 - msg = ( - "While trying to determine id of parameter {} at position " - "{} the following exception was raised:\n".format(argname, idx) - ) + msg = "{}: error raised while trying to determine id of parameter '{}' at position {}\n" + msg = msg.format(item.nodeid, argname, idx) + # we only append the exception type and message because on Python 2 reraise does nothing msg += " {}: {}\n".format(type(e).__name__, e) - msg += "This warning will be an error error in pytest-4.0." - item.warn(RemovedInPytest4Warning(msg)) + six.raise_from(ValueError(msg), e) if s: return ascii_escaped(s) diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index 33e88b409..92674589f 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -718,6 +718,6 @@ class RaisesContext(object): suppress_exception = issubclass(self.excinfo.type, self.expected_exception) if sys.version_info[0] == 2 and suppress_exception: sys.exc_clear() - if self.match_expr and suppress_exception: + if self.match_expr is not None and suppress_exception: self.excinfo.match(self.match_expr) return suppress_exception diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index f81680d0d..b7f914335 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -560,12 +560,11 @@ class TestInvocationVariants(object): def test_equivalence_pytest_pytest(self): assert pytest.main == py.test.cmdline.main - def test_invoke_with_string(self, capsys): - retcode = pytest.main("-h") - assert not retcode - out, err = capsys.readouterr() - assert "--help" in out - pytest.raises(ValueError, lambda: pytest.main(0)) + def test_invoke_with_invalid_type(self, capsys): + with pytest.raises( + TypeError, match="expected to be a list or tuple of strings, got: '-h'" + ): + pytest.main("-h") def test_invoke_with_path(self, tmpdir, capsys): retcode = pytest.main(tmpdir) diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index c7515d2cb..56828f7c0 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -10,28 +10,6 @@ from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG pytestmark = pytest.mark.pytester_example_path("deprecated") -def test_funcarg_prefix_deprecation(testdir): - testdir.makepyfile( - """ - def pytest_funcarg__value(): - return 10 - - def test_funcarg_prefix(value): - assert value == 10 - """ - ) - result = testdir.runpytest("-ra", SHOW_PYTEST_WARNINGS_ARG) - result.stdout.fnmatch_lines( - [ - ( - "*test_funcarg_prefix_deprecation.py:1: *pytest_funcarg__value: " - 'declaring fixtures using "pytest_funcarg__" prefix is deprecated*' - ), - "*1 passed*", - ] - ) - - @pytest.mark.filterwarnings("default") def test_pytest_setup_cfg_deprecated(testdir): testdir.makefile( @@ -62,25 +40,6 @@ def test_pytest_custom_cfg_deprecated(testdir): ) -def test_str_args_deprecated(tmpdir): - """Deprecate passing strings to pytest.main(). Scheduled for removal in pytest-4.0.""" - from _pytest.main import EXIT_NOTESTSCOLLECTED - - warnings = [] - - class Collect(object): - def pytest_warning_captured(self, warning_message): - warnings.append(str(warning_message.message)) - - ret = pytest.main("%s -x" % tmpdir, plugins=[Collect()]) - msg = ( - "passing a string to pytest.main() is deprecated, " - "pass a list of arguments instead." - ) - assert msg in warnings - assert ret == EXIT_NOTESTSCOLLECTED - - def test_getfuncargvalue_is_deprecated(request): pytest.deprecated_call(request.getfuncargvalue, "tmpdir") diff --git a/testing/python/fixture.py b/testing/python/fixture.py index 2cc4122b4..a4ef5af87 100644 --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -627,25 +627,6 @@ class TestRequestBasic(object): print(ss.stack) assert teardownlist == [1] - def test_mark_as_fixture_with_prefix_and_decorator_fails(self, testdir): - testdir.makeconftest( - """ - import pytest - - @pytest.fixture - def pytest_funcarg__marked_with_prefix_and_decorator(): - pass - """ - ) - result = testdir.runpytest_subprocess() - assert result.ret != 0 - result.stdout.fnmatch_lines( - [ - "*AssertionError: fixtures cannot have*@pytest.fixture*", - "*pytest_funcarg__marked_with_prefix_and_decorator*", - ] - ) - def test_request_addfinalizer_failing_setup(self, testdir): testdir.makepyfile( """ diff --git a/testing/python/metafunc.py b/testing/python/metafunc.py index 7f9cdb5cc..0b05a7c5e 100644 --- a/testing/python/metafunc.py +++ b/testing/python/metafunc.py @@ -393,7 +393,6 @@ class TestMetafunc(object): ) assert result == ["a-a0", "a-a1", "a-a2"] - @pytest.mark.filterwarnings("default") def test_parametrize_ids_exception(self, testdir): """ :param testdir: the instance of Testdir class, a temporary @@ -411,14 +410,11 @@ class TestMetafunc(object): pass """ ) - result = testdir.runpytest("--collect-only", SHOW_PYTEST_WARNINGS_ARG) + result = testdir.runpytest() result.stdout.fnmatch_lines( [ - "", - " ", - " ", - "*test_parametrize_ids_exception.py:6: *parameter arg at position 0*", - "*test_parametrize_ids_exception.py:6: *parameter arg at position 1*", + "*test_foo: error raised while trying to determine id of parameter 'arg' at position 0", + "*Exception: bad ids", ] ) diff --git a/testing/python/raises.py b/testing/python/raises.py index aad60d775..4ff0b51bc 100644 --- a/testing/python/raises.py +++ b/testing/python/raises.py @@ -44,6 +44,11 @@ class TestRaises(object): except pytest.raises.Exception: pass + def test_raises_falsey_type_error(self): + with pytest.raises(TypeError): + with pytest.raises(AssertionError, match=0): + raise AssertionError("ohai") + def test_raises_repr_inflight(self): """Ensure repr() on an exception info inside a pytest.raises with block works (#4386)""" diff --git a/testing/test_assertion.py b/testing/test_assertion.py index bb54e394f..fcefdbb11 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -154,7 +154,8 @@ class TestImportHookInstallation(object): @pytest.mark.parametrize("mode", ["plain", "rewrite"]) @pytest.mark.parametrize("plugin_state", ["development", "installed"]) - def test_installed_plugin_rewrite(self, testdir, mode, plugin_state): + def test_installed_plugin_rewrite(self, testdir, mode, plugin_state, monkeypatch): + monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) # Make sure the hook is installed early enough so that plugins # installed via setuptools are rewritten. testdir.tmpdir.join("hampkg").ensure(dir=1) diff --git a/testing/test_config.py b/testing/test_config.py index f757bb018..b0b09f44a 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -510,6 +510,7 @@ def test_options_on_small_file_do_not_blow_up(testdir): def test_preparse_ordering_with_setuptools(testdir, monkeypatch): pkg_resources = pytest.importorskip("pkg_resources") + monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) def my_iter(name): assert name == "pytest11" @@ -547,6 +548,7 @@ def test_preparse_ordering_with_setuptools(testdir, monkeypatch): def test_setuptools_importerror_issue1479(testdir, monkeypatch): pkg_resources = pytest.importorskip("pkg_resources") + monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) def my_iter(name): assert name == "pytest11" @@ -575,6 +577,7 @@ def test_setuptools_importerror_issue1479(testdir, monkeypatch): @pytest.mark.parametrize("block_it", [True, False]) def test_plugin_preparse_prevents_setuptools_loading(testdir, monkeypatch, block_it): pkg_resources = pytest.importorskip("pkg_resources") + monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) plugin_module_placeholder = object() diff --git a/testing/test_junitxml.py b/testing/test_junitxml.py index aafbb8da9..cbadbf064 100644 --- a/testing/test_junitxml.py +++ b/testing/test_junitxml.py @@ -153,7 +153,7 @@ class TestPython(object): val = tnode["time"] assert round(float(val), 2) >= 0.03 - def test_call_time(self, testdir): + def test_junit_duration_report(self, testdir): testdir.makepyfile( """ import time, pytest @@ -165,7 +165,7 @@ class TestPython(object): time.sleep(0.1) """ ) - result, dom = runandparse(testdir, "-o", "junit_time=call") + result, dom = runandparse(testdir, "-o", "junit_duration_report=call") node = dom.find_first_by_tag("testsuite") tnode = node.find_first_by_tag("testcase") val = tnode["time"] @@ -1050,12 +1050,13 @@ def test_record_attribute(testdir): ) -def test_random_report_log_xdist(testdir): +def test_random_report_log_xdist(testdir, monkeypatch): """xdist calls pytest_runtest_logreport as they are executed by the slaves, with nodes from several nodes overlapping, so junitxml must cope with that to produce correct reports. #1064 """ pytest.importorskip("xdist") + monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) testdir.makepyfile( """ import pytest, time diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 20f4f0078..9cd79afcf 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -1341,13 +1341,15 @@ class TestProgressOutputStyle(object): ] ) - def test_xdist_normal(self, many_tests_files, testdir): + def test_xdist_normal(self, many_tests_files, testdir, monkeypatch): pytest.importorskip("xdist") + monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) output = testdir.runpytest("-n2") output.stdout.re_match_lines([r"\.{20} \s+ \[100%\]"]) - def test_xdist_normal_count(self, many_tests_files, testdir): + def test_xdist_normal_count(self, many_tests_files, testdir, monkeypatch): pytest.importorskip("xdist") + monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) testdir.makeini( """ [pytest] @@ -1357,8 +1359,9 @@ class TestProgressOutputStyle(object): output = testdir.runpytest("-n2") output.stdout.re_match_lines([r"\.{20} \s+ \[20/20\]"]) - def test_xdist_verbose(self, many_tests_files, testdir): + def test_xdist_verbose(self, many_tests_files, testdir, monkeypatch): pytest.importorskip("xdist") + monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) output = testdir.runpytest("-n2", "-v") output.stdout.re_match_lines_random( [ @@ -1452,7 +1455,8 @@ class TestProgressWithTeardown(object): ] ) - def test_xdist_normal(self, many_files, testdir): + def test_xdist_normal(self, many_files, testdir, monkeypatch): pytest.importorskip("xdist") + monkeypatch.delenv("PYTEST_DISABLE_PLUGIN_AUTOLOAD", raising=False) output = testdir.runpytest("-n2") output.stdout.re_match_lines([r"[\.E]{40} \s+ \[100%\]"])