MaxLunar
MaxLunar

Reputation: 663

Simulate Python interactive mode

Im writing a private online Python interpreter for VK, which would closely simulate IDLE console. Only me and some people in whitelist would be able to use this feature, no unsafe code which can harm my server. But I have a little problem. For example, I send the string with code def foo():, and I dont want to get SyntaxError but continue defining function line by line without writing long strings with use of \n. exec() and eval() doesn't suit me in that case. What should I use to get desired effect? Sorry if duplicate, still dont get it from similar questions.

Upvotes: 1

Views: 414

Answers (2)

user2357112
user2357112

Reputation: 280456

The Python standard library provides the code and codeop modules to help you with this. The code module just straight-up simulates the standard interactive interpreter:

import code
code.interact()

It also provides a few facilities for more detailed control and customization of how it works.

If you want to build things up from more basic components, the codeop module provides a command compiler that remembers __future__ statements and recognizes incomplete commands:

import codeop
compiler = codeop.CommandCompiler()

try:
    codeobject = compiler(some_source_string)
    # codeobject is an exec-utable code object if some_source_string was a
    # complete command, or None if the command is incomplete.
except (SyntaxError, OverflowError, ValueError):
    # If some_source_string is invalid, we end up here.
    # OverflowError and ValueError can occur in some cases involving invalid literals.

Upvotes: 2

ivan_pozdeev
ivan_pozdeev

Reputation: 35998

It boils down to reading input, then

exec <code> in globals,locals

in an infinite loop.

See e.g. IPython.frontend.terminal.console.interactiveshell.TerminalInteractiveSh ell.mainloop().

Continuation detection is done in inputsplitter.push_accepts_more() by trying ast.parse().

Actually, IPython already has an interactive web console called Jupyter Notebook, so your best bet should be to reuse it.

Upvotes: 2

Related Questions