Conversation
tlikhit
force-pushed
the
fix/preserve-string-prompts
branch
from
September 7, 2026 23:58
406efb8 to
6ede4c7
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Preserve literal
>>>and...text inside Python strings while still removing the outer prompts from pasted Python sessions.Fixes #14600. The original bare-string examples now work, but assigned multiline strings still lose content in IPython 9.17.1 and main at
e18b391ad.Problem
Before Python executes a cell, IPython transforms its input. One step removes prompts such as
>>>and..., so code copied from an interactive session can run.Those characters can also be part of a string. The current code uses a regular expression to find
'''and""", then tracks whether subsequent lines are inside a string. This approximate quote-tracking logic is the "triple-quote regex heuristic."One of its protection rules requires the text before the opening quotes, after removing any prompt and surrounding whitespace, to be empty or only a string prefix such as
forr. An assignment such astext = f"""fails that check, so literal prompt text inside the string can be stripped. For example, this is ordinary Python code, not a pasted session:text"\n>>> 1\n... tail\n""\n1\ntail\n"The cell runs without a syntax error, but its string value changes silently.
Fix
Use Python's tokenizer to locate strings instead of the triple-quote heuristic. The opening line determines how to handle each string:
For example, this pasted session must still have its outer prompts removed:
The resulting string is
"\n>>> literal\n... tail\n".The tokenizer reads a temporary copy with prompts removed. The transformer retains the original lines for output. It also protects incomplete strings and resumes tokenization after lexical errors in shell or magic input.
Related behavior changes
Keep statements inside their enclosing block
Previously, indentation cleanup treated the code before and after a protected string as separate chunks. Consider a function and docstring followed by a pasted
returnline:After removing
>>>, the old code also removed the four spaces beforereturn, moving it outside the function. The fix uses the whole cell's indentation context, so the result is:Remove outer prompts from a bare string
A bare string is a string expression without an assignment such as
text =. For this pasted session:The old code left the entire input untouched, including the outer prompts. The fix removes those prompts but retains the literal
>>>inside the string:The existing
CLASSIC_PROMPT_L3test expected the old, invalid transformed source. Its expected result is updated to reflect this correction.Documentation and scope
A release note documents the changes. IPython's numbered
In [n]:prompts use a separate removal path, which this PR does not change.Test coverage
Add parameterized regression tests and controls for:
InteractiveShell.run_cell.Valid examples check both transformed source and resulting values, not just whether the code parses.
Review focus
This remains a draft for feedback on the opening-line rule and the changed bare-string expectation. Tokenization adds work when a cell contains a line matching
>>>; cells without such a line return early.AI-assisted implementation: 🤖 🤖