Skip to content

gh-153782: Make traceback.print_list() delegate to format_list()#153783

Open
basil wants to merge 1 commit into
python:mainfrom
basil:format-list
Open

gh-153782: Make traceback.print_list() delegate to format_list()#153783
basil wants to merge 1 commit into
python:mainfrom
basil:format-list

Conversation

@basil

@basil basil commented Jul 15, 2026

Copy link
Copy Markdown

Fixes #153782

In Lib/traceback.py, the public helpers print_list() and format_list() independently contain the same formatting expression, so their outputs agree only by duplication. This PR routes print_list() through format_list() so that they share a single formatting path, with no change in behavior.

Problem

format_list() returns the formatted lines:

def format_list(extracted_list):
    return StackSummary.from_list(extracted_list).format()

print_list() writes those same lines, but re-derives them with the identical expression instead of reusing format_list():

def print_list(extracted_list, file=None):
    if file is None:
        file = sys.stderr
    for item in StackSummary.from_list(extracted_list).format():
        print(item, file=file, end="")

The outputs match only because StackSummary.from_list(extracted_list).format() is duplicated in both. Any future change to how a frame list is formatted has to be applied in both places to prevent the two public helpers from silently diverging.

Solution

Have print_list() iterate format_list():

def print_list(extracted_list, file=None):
    if file is None:
        file = sys.stderr
    for item in format_list(extracted_list):
        print(item, file=file, end="")

This eliminates the possibility of drift and mirrors the delegation already used in this module; for example, print_tb() calls print_list() rather than re-deriving extract_tb(...).format().

Testing Done

format_list() is exactly the same expression, so output is identical for every documented input type. Therefore, there is no change in behavior. This PR adds a regression test asserting this equality for tuple, FrameSummary, and StackSummary inputs.

Documentation

I have not proposed an entry in Misc/NEWS.d, as the developer guide says that strictly internal changes with no user-visible effect do not require one. I am happy to add one if a maintainer prefers.

print_list() and format_list() each formatted a StackSummary with the
same expression, so their outputs agreed only by duplication. Route
print_list() through format_list() so print_list(x), keeping the two
public helpers from drifting, and add a regression test that
print_list() matches format_list() for tuple, FrameSummary, and
StackSummary inputs.
@bedevere-app

bedevere-app Bot commented Jul 15, 2026

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@basil

basil commented Jul 15, 2026

Copy link
Copy Markdown
Author

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

Per my comment from the PR description:

I have not proposed an entry in Misc/NEWS.d, as the developer guide says that strictly internal changes with no user-visible effect do not require one. I am happy to add one if a maintainer prefers.


If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

I will wait for a maintainer to apply the skip news label.

@picnixz

picnixz commented Jul 15, 2026

Copy link
Copy Markdown
Member

I do not think it is really worth it. The current code is working and such change would create a drift in backports. We do not accept such changes in general. I think it is fine as is.

@picnixz

picnixz commented Jul 15, 2026

Copy link
Copy Markdown
Member

However the tests, if not already there, are worth it.

@picnixz

picnixz commented Jul 15, 2026

Copy link
Copy Markdown
Member

If tests do not yet exist, we can accept such changes. Can you confirm that?

@johnslavik

Copy link
Copy Markdown
Member

I think the current code is OK.

I understand your reasoning. However, these functions are essentially kept together and they are simple functions. They have not drifted for 11 years.

Test coverage would be cool to have, yes.

@basil

basil commented Jul 15, 2026

Copy link
Copy Markdown
Author

Thank you, that makes sense. This PR adds test_print_list_matches_format_list, covering tuple input, FrameSummary input, and StackSummary input. I confirmed that there was not an existing test checking that traceback.print_list() produces the same output as traceback.format_list().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove duplicate code by making traceback.print_list() delegate to format_list()

3 participants