This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author asmeurer
Recipients Marco Sulla, asmeurer, eric.smith, eryksun, steven.daprano, terry.reedy, vstinner
Date 2021-02-17.21:16:39
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1613596600.14.0.359318562204.issue39820@roundup.psfhosted.org>
In-reply-to
Content
To reiterate some points I made in the closed issues https://bugs.python.org/issue42819 and https://bugs.python.org/issue32019.

A simple "fix" would be to emulate the non-bracketed paste buffering. That is, accept the input using bracketed paste, but split it line by line and send that to the REPL. That would achieve some of the benefits of bracketed paste (faster pasting), without having to change how the REPL works.

For actually allowing multiline input in the REPL, one issue I see is that the so-called "single" compile mode is fundamentally designed around single line evaluation. To support proper multiline evaluation, it would need to break from this model (which in my opinion is over engineered).

In one of my personal projects, I use a function along the lines of 

import ast

def eval_exec(code, g=None, l=None, *, filename="<stdin>", noresult=None):
    if g is None:
        g = globals()
    if l is None:
        l = g
    p = ast.parse(code)
    expr = None
    res = noresult
    if p.body and isinstance(p.body[-1], ast.Expr):
        expr = p.body.pop()
    code = compile(p, filename, 'exec')
    exec(code, g, l)
    if expr:
        code = compile(ast.Expression(expr.value), filename, 'eval')
        res = eval(code, g, l)

    return res

This function automatically execs the code, but if the last part of it is an expression, it returns it (note that this is much more useful than simply printing it). Otherwise it returns a noresult marker (None by default).

I think this sort of functionality in general would be useful in the standard library (much more useful than compile('single')), but even ignoring whether it should be a public function, this is the sort of thing that is needed for "proper" multiline execution in a REPL. Terry mentioned that idle supports multiline already. But I tried pasting

a = 1
a

into idle (Python 3.9), and I get the same "SyntaxError: multiple statements found while compiling a single statement" error, suggesting it still has the same fundamental limitation. 

Also, if it wasn't clear, I should note that this is independent of pasting. You can already write

def func():
    return 1
func()

manually in the interpreter or IDLE and it will give a syntax error.
History
Date User Action Args
2021-02-17 21:16:40asmeurersetrecipients: + asmeurer, terry.reedy, vstinner, eric.smith, steven.daprano, eryksun, Marco Sulla
2021-02-17 21:16:40asmeurersetmessageid: <1613596600.14.0.359318562204.issue39820@roundup.psfhosted.org>
2021-02-17 21:16:40asmeurerlinkissue39820 messages
2021-02-17 21:16:39asmeurercreate