diff --git a/changelog/5675.improvement.rst b/changelog/5675.improvement.rst new file mode 100644 index 00000000000..286bed94f37 --- /dev/null +++ b/changelog/5675.improvement.rst @@ -0,0 +1 @@ +When `--showlocals` is enabled, function arguments are no longer displayed in a separate block because they are already included in the locals output. diff --git a/src/_pytest/_code/code.py b/src/_pytest/_code/code.py index f6d2f27672c..0dd237ff9c4 100644 --- a/src/_pytest/_code/code.py +++ b/src/_pytest/_code/code.py @@ -1483,7 +1483,8 @@ def toterminal(self, tw: TerminalWriter) -> None: self.reprlocals.toterminal(tw, indent=" " * 8) return - if self.reprfuncargs: + # Locals already include the arguments; skip the separate block. + if self.reprfuncargs and self.reprlocals is None: self.reprfuncargs.toterminal(tw) self._write_entry_lines(tw) diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 73d944bf290..686fea4b142 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -1227,6 +1227,33 @@ def test_showlocals_short(): ] ) + def test_showlocals_no_duplicate_funcargs(self, pytester: Pytester) -> None: + """Helper params must not render twice with --showlocals (#5675).""" + p1 = pytester.makepyfile( + """ + class LargeRepr: + def __repr__(self): + return "X" * 10000 + + def helper(data, flag): + assert flag is False + + def test_failure(): + helper(LargeRepr(), True) + """ + ) + # Without --showlocals the funcargs block stays (truncated). + result = pytester.runpytest(p1) + result.stdout.fnmatch_lines(["data = X*"]) + # With --showlocals params show once, in the padded locals block. + result = pytester.runpytest(p1, "--showlocals") + result.stdout.no_fnmatch_line("data = X*") + result.stdout.fnmatch_lines(["data *= X*"]) + # Same at higher verbosity; locals keep their existing behavior. + result = pytester.runpytest(p1, "--showlocals", "-vv") + result.stdout.no_fnmatch_line("data = X*") + result.stdout.fnmatch_lines(["data *= X*"]) + @pytest.fixture def verbose_testfile(self, pytester: Pytester) -> Path: return pytester.makepyfile(