Insert and execute code in console by script

Hi
I’m trying to insert some lines of code in console and execute that with script just like interactive typing and pressing enter to execute.
everything works OK but the bpy.ops.console.execute() function cause error.

My goal is to create connection to interactive console so that i can run one-liner snippets and selected code from text editor or from external editor.

here is my sample code:

import bpy

C = bpy.context

for area in C.screen.areas:
    if area.type == 'CONSOLE':
        c = {}
        c['area'] = area
        c['region'] = area.regions[-1]
        c['space_data'] = area.spaces.active
        c['screen'] = C.screen
        c['window'] = C.window
        bpy.ops.console.clear_line(c)
        bpy.ops.console.insert(c,text = 'print("Hello World!")')
        bpy.ops.console.execute(c)

Thanks.

bpy.ops.console.execute is a two-fold operation - it pushes a single line of input to a console class, then sends the output to blender’s interactive console using bpy.ops.console.scrollback_append.

Because execute is calling scrollback_append from the operator itself, it’s not being overridden.

Sending text to the console and adding output to the scrollback buffer requires a little more effort than an override.
This example only redirects a single line print('hello world') and catches the output.

from console_python import get_console
from contextlib import redirect_stdout
import bpy

def add_scrollback(override, text, text_type):
    append = bpy.ops.console.scrollback_append
    
    for l in text.split("\n"):
        txt = l.replace("\t", "    ")
        append(override, text=txt, type=text_type)

con = stdout = stderr = None
for area in bpy.context.screen.areas:    
    if area.type == 'CONSOLE':
        hsh = hash(area.regions[-1])
        con, stdout, stderr = get_console(hsh)
        break

stdout.seek(0)
stdout.truncate(0)

with redirect_stdout(stdout):
    con.push("print('hello world')")

out = stdout.getvalue()
if out:
    override = {'area': area, 'region': area.regions[-1], 'space_data': area.spaces.active}
    add_scrollback(override, out, 'OUTPUT')
1 Like

Oh how complicated
I was giving up and decided to put text in console by script then press enter manually to execute !
Your code works really great it also works good with variable assignment and shared script space.
With some formating and printing “>>>” it would be just like interactive console.
Thank you very much.
How did you know that this functions works different than others?

No problem. Blender’s interactive console is really just a blank shell that sends code to an InteractiveConsole object generated from the hash from the console’s region, and sends the output and errors to StringIO objects and outputs it using the scrollback operator.

You see how they did it under scripts/modules/console_python.py.

Because I’ve written a “Run in console” addon, myself :stuck_out_tongue:

https://github.com/K-410/blender-scripts/blob/master/run_in_console.py

1 Like

Ooo man that’s great ! :laughing::+1::+1::+1:
Thank You :pray:

Do you still think that capturing the outputs of other scripts unstable (which is how you stated in the addon panel)?