def get_console(console_id): """ helper function for console operators currently each text data block gets its own console - code.InteractiveConsole() ...which is stored in this function. console_id can be any hashable type """ from code import InteractiveConsole consoles = getattr(get_console, "consoles", None) hash_next = hash(bpy.context.window_manager) if consoles is None: consoles = get_console.consoles = {} get_console.consoles_namespace_hash = hash_next else: # check if clearing the namespace is needed to avoid a memory leak. # the window manager is normally loaded with new blend files # so this is a reasonable way to deal with namespace clearing. # bpy.data hashing is reset by undo so cant be used. hash_prev = getattr(get_console, "consoles_namespace_hash", 0) if hash_prev != hash_next: get_console.consoles_namespace_hash = hash_next consoles.clear() console_data = consoles.get(console_id) if console_data: console, stdout, stderr = console_data # XXX, bug in python 3.1.2, 3.2 ? (worked in 3.1.1) # seems there is no way to clear StringIO objects for writing, have to # make new ones each time. import io stdout = io.StringIO() stderr = io.StringIO() else: if _BPY_MAIN_OWN: import types bpy_main_mod = types.ModuleType("__main__") namespace = bpy_main_mod.__dict__ else: namespace = {} namespace["__builtins__"] = sys.modules["builtins"] namespace["bpy"] = bpy # weak! - but highly convenient namespace["C"] = bpy.context namespace["D"] = bpy.data replace_help(namespace) console = InteractiveConsole(locals=namespace, filename="<blender_console>") console.push("from mathutils import *") console.push("from math import *") if _BPY_MAIN_OWN: console._bpy_main_mod = bpy_main_mod import io stdout = io.StringIO() stderr = io.StringIO() consoles[console_id] = console, stdout, stderr return console, stdout, stderr