Skip to content

gh-137576: Fix for Basic REPL Showing Incorrect Code in Tracebacks with PYTHONSTARTUP #137625

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

adqm
Copy link
Contributor

@adqm adqm commented Aug 11, 2025

This patch attempts to fix #137576 by changing the way interactive_filename is computed for the basic REPL to make sure that it always begins with < and ends with > so that doesn't get an entry in linecache.cache (which was causing the source from PYTHONSTARTUP to be used instead of the interactive input when generating tracebacks).

Updated behavior:

$ echo "print('hello from PYTHONSTARTUP')" > /tmp/foo.py
$ PYTHON_BASIC_REPL=1 PYTHONSTARTUP=/tmp/foo.py ./python
Python 3.15.0a0 (heads/basic_repl_error_reporting:3d46e8feed, Aug 10 2025, 21:12:17) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
hello from PYTHONSTARTUP
>>> 1/0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    1/0
    ~^~
ZeroDivisionError: division by zero
$ echo "def foo(x):  return 1/x" > /tmp/foo.py
$ PYTHON_BASIC_REPL=1 PYTHONSTARTUP=/tmp/foo.py ./python
Python 3.15.0a0 (heads/basic_repl_error_reporting:3d46e8feed, Aug 10 2025, 21:12:17) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def bar(x):
...     return foo(x)
... 
>>> bar(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    bar(0)
    ~~~^^^
  File "<stdin>", line 2, in bar
    return foo(x)
  File "/tmp/foo.py", line 1, in foo
    def foo(x):  return 1/x
                        ~^~
ZeroDivisionError: division by zero

@adqm
Copy link
Contributor Author

adqm commented Aug 11, 2025

My original patch here also caused the tracebacks to report the filename as <stdin-N> instead of <stdin>. I think there's something nice about that (from the REPL, it's nice to see when the sources shown in the traceback came from different interactive inputs, better symmetry with pyrepl's reporting, etc.), but for now I added a commit to keep the reported filename as <stdin>.

Copy link
Member

@Eclips4 Eclips4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!
A couple of nits.

if (len >= 2
&& PyUnicode_ReadChar(filename, 0) == '<'
&& PyUnicode_ReadChar(filename, len - 1) == '>') {
PyObject *middle = PyUnicode_Substring(filename, 1, len-1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add error checks for PyUnicode_Substring, since it could return NULL?
If that happens, simply return NULL.
Also, in run_mode, please add an error check for when get_interactive_filename returns NULL (just propagate that NULL).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review!

Could you please add error checks for PyUnicode_Substring, since it could return NULL?

Yep, I added a check there.

Also, in run_mode, please add an error check for when get_interactive_filename returns NULL (just propagate that NULL).

I think this one is already handled, on lines 1406-1408 (which happen just after get_interactive_filename is called).

        if (interactive_filename == NULL) {
            return NULL;
        }

adqm and others added 2 commits August 11, 2025 14:45
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.

traceback shows wrong source code in basic REPL when PYTHONSTARTUP is set
2 participants