From 2367e6e9bf4cf021510ed212e2e9f05cf35b8697 Mon Sep 17 00:00:00 2001 From: David Szotten Date: Thu, 19 Aug 2021 11:24:51 +0000 Subject: [PATCH 01/46] refactor ci helper to prepare for re-use --- src/_pytest/assertion/truncate.py | 10 ++-------- src/_pytest/assertion/util.py | 8 +++++++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/_pytest/assertion/truncate.py b/src/_pytest/assertion/truncate.py index 5ba9ddca7..ce148dca0 100644 --- a/src/_pytest/assertion/truncate.py +++ b/src/_pytest/assertion/truncate.py @@ -3,10 +3,10 @@ Current default behaviour is to truncate assertion explanations at ~8 terminal lines, unless running in "-vv" mode or running on CI. """ -import os from typing import List from typing import Optional +from _pytest.assertion import util from _pytest.nodes import Item @@ -27,13 +27,7 @@ def truncate_if_required( def _should_truncate_item(item: Item) -> bool: """Whether or not this test item is eligible for truncation.""" verbose = item.config.option.verbose - return verbose < 2 and not _running_on_ci() - - -def _running_on_ci() -> bool: - """Check if we're currently running on a CI system.""" - env_vars = ["CI", "BUILD_NUMBER"] - return any(var in os.environ for var in env_vars) + return verbose < 2 and not util.running_on_ci() def _truncate_explanation( diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index d29a2a010..493ab9142 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -1,5 +1,6 @@ """Utilities for assertion debugging.""" import collections.abc +import os import pprint from typing import AbstractSet from typing import Any @@ -17,7 +18,6 @@ from _pytest._io.saferepr import safeformat from _pytest._io.saferepr import saferepr from _pytest.config import Config - # The _reprcompare attribute on the util module is used by the new assertion # interpretation code and assertion rewriter to detect this plugin was # loaded and in turn call the hooks defined here as part of the @@ -490,3 +490,9 @@ def _notin_text(term: str, text: str, verbose: int = 0) -> List[str]: else: newdiff.append(line) return newdiff + + +def running_on_ci() -> bool: + """Check if we're currently running on a CI system.""" + env_vars = ["CI", "BUILD_NUMBER"] + return any(var in os.environ for var in env_vars) From d5c020d8c5958e14fb401f4e4c706ccc612d41af Mon Sep 17 00:00:00 2001 From: David Szotten Date: Thu, 19 Aug 2021 16:27:07 +0000 Subject: [PATCH 02/46] always show full diff in ci follow-up to #1314, for similar reasons closes #9023 --- changelog/9023.feature.rst | 4 ++++ src/_pytest/assertion/util.py | 2 +- testing/test_assertion.py | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 changelog/9023.feature.rst diff --git a/changelog/9023.feature.rst b/changelog/9023.feature.rst new file mode 100644 index 000000000..86a819a84 --- /dev/null +++ b/changelog/9023.feature.rst @@ -0,0 +1,4 @@ + +Full diffs are now always shown for equality assertions of iterables when +`CI` or ``BUILD_NUMBER`` is found in the environment, even when ``-v`` isn't +used. diff --git a/src/_pytest/assertion/util.py b/src/_pytest/assertion/util.py index 493ab9142..19f1089c2 100644 --- a/src/_pytest/assertion/util.py +++ b/src/_pytest/assertion/util.py @@ -287,7 +287,7 @@ def _surrounding_parens_on_own_lines(lines: List[str]) -> None: def _compare_eq_iterable( left: Iterable[Any], right: Iterable[Any], verbose: int = 0 ) -> List[str]: - if not verbose: + if not verbose and not running_on_ci(): return ["Use -v to get the full diff"] # dynamic import to speedup pytest import difflib diff --git a/testing/test_assertion.py b/testing/test_assertion.py index 289fe5b08..e8717590d 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -13,6 +13,7 @@ import pytest from _pytest import outcomes from _pytest.assertion import truncate from _pytest.assertion import util +from _pytest.monkeypatch import MonkeyPatch from _pytest.pytester import Pytester @@ -448,6 +449,25 @@ class TestAssert_reprcompare: assert verbose_expl is not None assert "\n".join(verbose_expl).endswith(textwrap.dedent(expected).strip()) + def test_iterable_full_diff_ci( + self, monkeypatch: MonkeyPatch, pytester: Pytester + ) -> None: + pytester.makepyfile( + r""" + def test_full_diff(): + left = [0, 1] + right = [0, 2] + assert left == right + """ + ) + monkeypatch.setenv("CI", "true") + result = pytester.runpytest() + result.stdout.fnmatch_lines(["E Full diff:"]) + + monkeypatch.delenv("CI", raising=False) + result = pytester.runpytest() + result.stdout.fnmatch_lines(["E Use -v to get the full diff"]) + def test_list_different_lengths(self) -> None: expl = callequal([0, 1], [0, 1, 2]) assert expl is not None From 59d314de3d6aff2f8af2b2ea1e96694900efe20e Mon Sep 17 00:00:00 2001 From: Emmanuel Arias Date: Tue, 31 Aug 2021 09:12:11 -0300 Subject: [PATCH 03/46] Show fullname on direct Node construction warning This commit add the fullname on the Node construction warning. Also add a test for this case. --- src/_pytest/nodes.py | 2 +- testing/test_nodes.py | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index e695f89bb..d3f0ddceb 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -123,7 +123,7 @@ class NodeMeta(type): "See " "https://docs.pytest.org/en/stable/deprecations.html#node-construction-changed-to-node-from-parent" " for more details." - ).format(name=self.__name__) + ).format(name=f"{self.__module__}.{self.__name__}") fail(msg, pytrace=False) def _create(self, *k, **kw): diff --git a/testing/test_nodes.py b/testing/test_nodes.py index 52cd0173c..57a942c25 100644 --- a/testing/test_nodes.py +++ b/testing/test_nodes.py @@ -6,6 +6,7 @@ from typing import Type import pytest from _pytest import nodes from _pytest.compat import legacy_path +from _pytest.outcomes import OutcomeException from _pytest.pytester import Pytester from _pytest.warning_types import PytestWarning @@ -40,6 +41,19 @@ def test_node_from_parent_disallowed_arguments() -> None: nodes.Node.from_parent(None, config=None) # type: ignore[arg-type] +def test_node_direct_construction_deprecated() -> None: + with pytest.raises( + OutcomeException, + match=( + "Direct construction of _pytest.nodes.Node has been deprecated, please " + "use _pytest.nodes.Node.from_parent.\nSee " + "https://docs.pytest.org/en/stable/deprecations.html#node-construction-changed-to-node-from-parent" + " for more details." + ), + ): + nodes.Node(None, session=None) # type: ignore[arg-type] + + def test_subclassing_both_item_and_collector_deprecated( request, tmp_path: Path ) -> None: From dc9192c8eb1fe18455934b56c9bd0ba6329a1ec5 Mon Sep 17 00:00:00 2001 From: Emmanuel Arias Date: Thu, 2 Sep 2021 00:14:19 -0300 Subject: [PATCH 04/46] add changelog file --- changelog/8994.improvement.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog/8994.improvement.rst diff --git a/changelog/8994.improvement.rst b/changelog/8994.improvement.rst new file mode 100644 index 000000000..2c8a2ef83 --- /dev/null +++ b/changelog/8994.improvement.rst @@ -0,0 +1,2 @@ +Included the module of the class in the error message about direct +node construction (without using ``from_parent``). From e929d15848da4d538f70a830f642a7bf913feaab Mon Sep 17 00:00:00 2001 From: Andrew Neitsch Date: Thu, 2 Sep 2021 17:40:41 -0600 Subject: [PATCH 05/46] Include figures in PDF docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PDF documentation on readthedocs was missing the figures in the fixtures reference chapter. This PR uses a Sphinx plugin that automatically converts the checked-in SVG files to the PDF input files that LaTeX requires. The SVG-to-PDF conversion is done by inkscape, which gave the best conversion among the tools I tried. However, it [does not yet understand][href-bug] that you can write a plain `href` instead of `xlink:href` in svg files, so I’ve had to edit the SVG files accordingly. [href-bug]: https://github.com/TeX-Live/luatex.git --- .readthedocs.yml | 4 ++++ doc/en/conf.py | 1 + .../example/fixtures/fixture_availability.svg | 10 +++++----- .../fixtures/fixture_availability_plugins.svg | 12 ++++++------ ..._fixtures_order_autouse_multiple_scopes.svg | 6 +++--- ...est_fixtures_order_autouse_temp_effects.svg | 6 +++--- .../fixtures/test_fixtures_order_scope.svg | 4 ++-- .../test_fixtures_request_different_scope.svg | 8 ++++---- doc/en/reference/fixtures.rst | 18 +++++++++--------- doc/en/requirements.txt | 1 + 10 files changed, 38 insertions(+), 32 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 0176c2640..10c21fd8f 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -7,6 +7,10 @@ python: - method: pip path: . +build: + apt_packages: + - inkscape + formats: - epub - pdf diff --git a/doc/en/conf.py b/doc/en/conf.py index ee71ffcae..35941080b 100644 --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -55,6 +55,7 @@ extensions = [ "sphinx.ext.viewcode", "sphinx_removed_in", "sphinxcontrib_trio", + "sphinxcontrib.inkscapeconverter", ] # Add any paths that contain templates here, relative to this directory. diff --git a/doc/en/example/fixtures/fixture_availability.svg b/doc/en/example/fixtures/fixture_availability.svg index 3ca28447c..066caac34 100644 --- a/doc/en/example/fixtures/fixture_availability.svg +++ b/doc/en/example/fixtures/fixture_availability.svg @@ -1,4 +1,4 @@ - +