Esempio n. 1
0
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