GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Pasting in new REPL is slow · Issue #130328 · python/cpython

Pasting in new REPL is slow #130328

New issue
Copy link
New issue
Copy link
Closed
Closed
Pasting in new REPL is slow#130328
Copy link
Labels
OS-windowsperformancePerformance or resource usagePerformance or resource usagerelease-blockerstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-replRelated to the interactive shellRelated to the interactive shelltype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@natedogith1
natedogith1
opened on Feb 20, 2025
Issue body actions

Bug report

Bug description:

Pasting large blocks of text in the new REPL is slow. Tested by pasting the following string (3035 characters):

test value
"""1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"""

When using the old repl (started via $env:PYTHON_BASIC_REPL="true"; python in powershell), pasting the string is near immediate. When using the new repl (started via python in powershell), pasting the string takes 15 seconds.

The closed issue #119517 also mentioned some pasting performance issues, though that was for Linux with significantly more characters.

CPython versions tested on:

3.13

Operating systems tested on:

Windows

Linked PRs

  • gh-130328: Faster Windows new REPL paste #130677
  • GH-130328: pasting in new REPL is slow on Windows #132884
  • GH-130328: further speedup of pasting in new REPL on Windows by reading in chunks #132889
  • GH-130328: Speedup pasting in legacy console on Windows #133728
  • [3.14] GH-130328: Speedup pasting in legacy console on Windows (gh-133728) #134653
  • GH-130328: Fix WindowsConsoleGetEventTests after gh-133728 #134660
  • [3.14] GH-130328: Fix WindowsConsoleGetEventTests after gh-133728 (gh-134660) #134666

Activity

Next
  1. natedogith1
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Feb 20, 2025
  2. ZeroIntensity
    added
    topic-replRelated to the interactive shellRelated to the interactive shell
    on Feb 20, 2025
  3. StanFromIreland commented on Feb 20, 2025

    @StanFromIreland
    StanFromIreland
    on Feb 20, 2025
    Member
    More actions

    Possibly a windows issue, something to do with powershell? On linux (main branch build) it pastes as expected, instantly.

    cc windows expert @zooba

  4. zooba commented on Feb 20, 2025

    @zooba
    zooba
    on Feb 20, 2025
    Member
    More actions

    It's no good looking at me, I know nothing about the new repl (other than that I've suggested a couple of times that it should stop using ctypes and use native code instead, which could be the cause of any performance issue).

    @pablogsal @lysnikolaou @ambv are code owners for the REPL.

  5. natedogith1 commented on Feb 21, 2025

    @natedogith1
    natedogith1
    on Feb 21, 2025
    Author
    More actions

    I also see this when python is started from the win-r run dialog.

    Tested some other environments, using the first 604 lines of this copy of Frankenstein (32,003 characters) (same as #119517 did). WSL old REPL takes ~2 seconds. WSL new REPL takes ~4 seconds, Powershell old REPL takes ~1 second. Powershell new REPL takes ~55 seconds for just the first 25 lines to appear; when pasting only the first 25 lines (659 characters) it takes ~2 seconds.

  6. picnixz
    added
    performancePerformance or resource usagePerformance or resource usage
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    on Feb 21, 2025
  7. devdanzin commented on Feb 22, 2025

    @devdanzin
    devdanzin
    on Feb 22, 2025
    Member
    More actions

    I think it's caused by the Windows console reading one character at a time from input:

    cpython/Lib/_pyrepl/windows_console.py

    Lines 386 to 389 in 65b339c

    rec = INPUT_RECORD()
    read = DWORD()
    if not ReadConsoleInput(InHandle, rec, 1, read):
    raise WinError(GetLastError())

    But I don't know enough about ctypes or Windows API to know how to increase that value, naively using larger ints results in errors.

    cc @DinoV, who implemented the Windows console.

  8. devdanzin commented on Feb 22, 2025

    @devdanzin
    devdanzin
    on Feb 22, 2025
    Member
    More actions

    I was able to make ReadConsoleInput read 1024 chars at a time and also reduced self.console.wait() in Reader.handle1 from 100 to 0.1. That reduced time to paste the content from first post from 10s to 6s, which isn't a significant improvement given the numbers from WSL and basic REPL.

  9. devdanzin commented on Feb 22, 2025

    @devdanzin
    devdanzin
    on Feb 22, 2025
    Member
    More actions

    #124119 seems to improve things, but nowhere near WSL numbers.

    Edit: With that PR, time to past the sample from first post goes from 10s to 2.5s. Reading 32 chars of input instead of 1 and reducing Reader.console.wait from 100 to 10 further reduces time to 1.7s. So we can paste 5x faster than current version, which pales compared to the near instant paste in WSL.

    Reacted by stonebig
  10. devdanzin commented on Feb 23, 2025

    @devdanzin
    devdanzin
    on Feb 23, 2025
    Member
    More actions

    Can you check whether devdanzin#1 speeds up pasting significantly for you?

    It's a quick and dirty POC built on top of #124119 that:

    • Batches event processing;
    • Reads 32 chars from input instead of 1;
    • Enables virtual terminal (from the mentioned PR);
    • Reduces Reader.console.wait() from 100 to 10.

    It fails some tests and the code is ugly, but if it makes things better we can try to improve on this.

  11. encukou
    added
    OS-windows
    on Feb 24, 2025
  12. devdanzin commented on Feb 28, 2025

    @devdanzin
    devdanzin
    on Feb 28, 2025
    Member
    More actions

    Please test the #130677 PR to check whether it significantly improves pasting time for you.

  13. chris-eibl commented on Apr 24, 2025

    @chris-eibl
    chris-eibl
    on Apr 24, 2025
    Member
    More actions

    The reason why pasting is so slow on Windows (especially in the legacy console case where virtual terminal mode - and thus bracketed paste - is disabled):

    cpython/Lib/_pyrepl/reader.py

    Lines 702 to 706 in 9f5994b

    while True:
    # We use the same timeout as in readline.c: 100ms
    self.run_hooks()
    self.console.wait(100)
    event = self.console.get_event(block=False)

    and

    cpython/Lib/_pyrepl/windows_console.py

    Lines 523 to 532 in 9f5994b

    def wait(self, timeout: float | None) -> bool:
    """Wait for an event."""
    # Poor man's Windows select loop
    start_time = time.time()
    while True:
    if msvcrt.kbhit(): # type: ignore[attr-defined]
    return True
    if timeout and time.time() - start_time > timeout / 1000:
    return False
    time.sleep(0.01)

    It is interesting, that msvcrt.kbhit() returns True in case of pasting, but if that weren't the case, we'd hit the 100ms timeout and would be even way slower. However, msvcrt.kbhit() is very slow in case of the legacy console, and it is called at least twice as often, because we get a key up and a key down event - but only a key down event in the virtual terminal case. If the pasted input contains upper case letters, we additionally get a "shift key pressed" event - so in the worst case, msvcrt.kbhit() gets called 3 times more often (and each call is slower).

    Output of python.bat -m cProfile -m _pyrepl when pasting the "test value" given in the OP for a legacy console:

       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
         50/1    0.010    0.000   17.202   17.202 {built-in method builtins.exec}
            1    0.000    0.000   17.202   17.202 <frozen runpy>:201(run_module)
            1    0.000    0.000   17.199   17.199 <frozen runpy>:65(_run_code)
            1    0.000    0.000   17.199   17.199 __main__.py:1(<module>)
            1    0.000    0.000   17.112   17.112 main.py:24(interactive_console)
            1    0.000    0.000   17.112   17.112 simple_interact.py:99(run_multiline_interactive_console)
            5    0.000    0.000   17.111    3.422 readline.py:375(multiline_input)
            5    0.004    0.001   17.111    3.422 reader.py:741(readline)
         3090    0.036    0.000   17.103    0.006 reader.py:694(handle1)
         6210    0.013    0.000   13.714    0.002 windows_console.py:523(wait)
         6236   13.433    0.002   13.433    0.002 {built-in method msvcrt.kbhit}
    

    Here the relevant line in case of virtual terminal:

      3270    0.554    0.000    0.554    0.000 {built-in method msvcrt.kbhit}
    

    The fix is to use WaitForSingleObject

        def wait(self, timeout: float | None) -> bool:
            """Wait for an event."""
            ret = WaitForSingleObject(InHandle, int(timeout))
            if ret == WAIT_FAILED:
                raise WinError(ctypes.get_last_error())

    which speeds up especially the legacy console (times in seconds):

    legacy terminal virtual terminal
    before 15.6 0.89
    after 1.8 0.26

    Note, see also #132440 (comment):

    • legacy terminal: manually start cmd.exe. Timings gotten by pasting
    import time
    t1 = time.time()
    <"test value" given in the OP>
    print(time.time() - t1)
    
    • virtual terminal: power shell via Windows terminal. Timings gotton by temporarily patching commands.py:
    import time
    class enable_bracketed_paste(Command):
        def do(self) -> None:
            self.reader.bp_begin = time.perf_counter()
            self.reader.paste_mode = True
            self.reader.in_bracketed_paste = True
    
    class disable_bracketed_paste(Command):
        def do(self) -> None:
            print("bracketed_paste took %5.2f s" % (time.perf_counter() - self.reader.bp_begin, ))
            self.reader.paste_mode = False
            self.reader.in_bracketed_paste = False
            self.reader.dirty = True
  14. chris-eibl commented on Apr 24, 2025

    @chris-eibl
    chris-eibl
    on Apr 24, 2025
    Member
    More actions

    Because pasting is so slow (especially in case of a legacy console), I've marked this as a release blocker.

  15. 18 remaining items

  16. chris-eibl commented on May 9, 2025

    @chris-eibl
    chris-eibl
    on May 9, 2025
    Member
    More actions

    @ambv I gave it a try and came up with #133728. Works for me in Windows and WSL in legacy and vt terminals and is as fast as bracketed pasting in paste mode (F3).

  17. ambv
    added a commit that references this issue on May 25, 2025

    GH-130328: Speedup pasting in legacy console on Windows (gh-133728)

    91b4886
  18. miss-islington
    added a commit that references this issue on May 25, 2025

    pythonGH-130328: Speedup pasting in legacy console on Windows (python…

    15a414d
  19. ambv
    added 2 commits that reference this issue on May 25, 2025

    [3.14] GH-130328: Speedup pasting in legacy console on Windows (gh-13…

    93aee56

    GH-130328: Fix WindowsConsoleGetEventTests after gh-133728 (gh-134660)

    1000283
  20. miss-islington
    added a commit that references this issue on May 25, 2025

    pythonGH-130328: Fix WindowsConsoleGetEventTests after pythongh-133728 (

    0422edf
  21. ambv
    added a commit that references this issue on May 25, 2025

    [3.14] GH-130328: Fix WindowsConsoleGetEventTests after gh-133728 (gh…

    6917fbf
  22. stonebig commented on May 26, 2025

    @stonebig
    stonebig
    on May 26, 2025
    More actions

    will it be backported to 3.13 too ?

  23. ambv commented on May 26, 2025

    @ambv
    ambv
    on May 26, 2025
    Contributor
    More actions

    No, this is a performance optimization with pretty large internal changes required.

  24. Pranjal095
    added 2 commits that reference this issue on Jul 12, 2025

    pythonGH-130328: Speedup pasting in legacy console on Windows (python…

    a295503

    pythonGH-130328: Fix WindowsConsoleGetEventTests after pythongh-133728 (

    c248bcb
  25. taegyunkim
    added 2 commits that reference this issue on Aug 4, 2025

    pythonGH-130328: Speedup pasting in legacy console on Windows (python…

    7d95b30

    pythonGH-130328: Fix WindowsConsoleGetEventTests after pythongh-133728 (

    3a120b1
  26. gostak-dd
    added 2 commits that reference this issue on Jun 2, 2026

    pythonGH-130328: Speedup pasting in legacy console on Windows (python…

    42b1d99

    pythonGH-130328: Fix WindowsConsoleGetEventTests after pythongh-133728 (

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS-windowsperformancePerformance or resource usagePerformance or resource usagerelease-blockerstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-replRelated to the interactive shellRelated to the interactive shelltype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    • Release and Deferred blockers 🚫
      Status
      Done
      Show more project fields

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.