Subject: Re: bug#71440: Python Inferior Mode Can’tRecognize My Prompt

From: kobarity <[email-masked]>
Date: Wed, 12 Jun 2024 01:24:39 +0900

"shynur ." wrote:
> It works perfectly this time, except there’s a
>     Warning (python): Python shell prompts cannot be detected.

Thanks for testing.  Could you please try the improved patch I've
attached, which I believe will eliminate this warning as well?

> Eli Zaretskii wrote:
> > > > I wonder how PS1 and PS2 are at all relevant when using 
> > > > python-shell-send-buffer?  That function sends the buffer
> > > > text to Python, so where do PS1 and PS2 come into play,
> > > > and why does Python say "__PYTHON_EL_eval is not defined" 
> > > > just because you have PS1 and PS2 customized?

PS1 and PS2 are set to `comint-prompt-regexp', and used to identify
execution completion.  The prompts must also be identified to
determine if the command can be sent.

Python REPL cannot accept the Python code as is.  For example, try
pasting the following code to the REPL:

if True:
    print("True")
print("Hi")

You should see the message "SyntaxError: invalid syntax".  This is
because the REPL requires an empty line to recognize the completion of
a block.  For such reasons, `python-shell-send-*' sends a string as
the argument to __PYTHON_EL_eval instead of sending the code as is.

__PYTHON_EL_eval is defined during the initialization of inferior
Python, but if the prompt is not recognized, its definition cannot be
done either.

The prompts are recognized by `python-shell-prompt-detect'.  A small
Python code sends PS1, etc. to Emacs as an array of JSON strings.
However, the JSON strings are hand-crafted for compatibility, as noted
in the comments below.

                    ;; JSON is built manually for compatibility

The json package was added in Python 2.6, so I assume it is to support
Python 2.5 and earlier.  This is fine for prompts consisting only of
ordinary characters, but will not result in a correct JSON string if
it contains escape sequences.

The attached improved patch uses the json package if available, so it
can handle escape sequences; without the json package, it works as
before.  It means that prompts containing escape sequences can be
recognized in Python 2.6 or later.  I have also added an ERT to check
this.

In the Inferior Python buffer, the escape sequences are removed using
`ansi-color-filter-apply'.  Therefore, I used the same function to
remove escape sequences at the end of `python-shell-prompt-detect' to
make the prompts match.

Another approach would be to remove the escape sequences on the Python
side.  It seems to be possible to do this using regular expressions,
but there does not seem to be a dedicated function for this.