Would it not be nice if
IPython could run inside the
Blender terminal in such way that it will remember the namespace history in between sessions? Why IPython? It gives you auto completion, deep reloads, object introspection, input history, access to your operating system commands with python variables, auto indent, ... In case you are not convinced, read this
tutorial,
reference or watch these
screencasts on
showmedo.
Most Linux distributions ship IPython in their repositories. For example installing on
Ubuntu is as easy as:
$ sudo apt-get install ipython
Getting IPython on Windows or Mac is simple if you have
setuptools installed:
$ easy_install IPython
Windows users should install
pyreadline as well for autocompletion. Check first in a terminal if IPython is correctly installed:
$ ipython
Python 2.5.2 (r252:60911, Oct 5 2008, 19:24:49)
Type "copyright", "credits" or "license" for more information.
IPython 0.8.4 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.
In [1]:
Save the following code as 'ipython_terminal.py' in your blender home script folder (~/.blender/scripts).
#!BPY
"""
Name: 'IPython (Terminal) - Enhanced Interactive Python Shell in Terminal'
Blender: 248
Group: 'System'
Tooltip: 'Interactive Python Console in terminal'
"""
__author__ = "Stani (SPE Python IDE)"
__url__ = ["pythonide.stani.be", "www.blender.org", "www.python.org"]
__bpydoc__ = """\
This only works if you started Blender from a terminal.
Otherwise Blender will freeze. The IPython console will
appear in the terminal. The namespace will be persistent
between console sessions within one Blender session.
Press Ctrl-D to pause the IPython session and return to Blender.
"""
# -*- coding: UTF-8 -*-
# ar - ARchitecture library
# Copyright (C) 2009 www.stani.be
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/
import sys
from IPython.Shell import IPShell
import bpy
import Blender
try:
shell = Blender.Registry.GetKey('ipython.terminal')['shell']
shell.IP.exit_now = False # resume
except TypeError:
sys_argv = sys.argv
sys.argv = ['/usr/bin/ipython']
shell = IPShell(user_ns={'Blender':Blender, 'bpy':bpy})
sys.argv = sys_argv
def pre_prompt_hook(ip, Blender=Blender, shell=shell):
Blender.Redraw()
Blender.Registry.SetKey('ipython.terminal', {'shell':shell})
shell.IP.set_hook('pre_prompt_hook',pre_prompt_hook)
shell.mainloop(banner=shell.IP.BANNER + shell.IP.banner2 +\
'\nPress Ctrl-D to pause the IPython session and ' +\
'return to Blender.\n')
Make sure you start Blender from a terminal and not from the start menu, as IPython will run in the terminal. You can start the IPython terminal from the Script window in Blender. (Scripts > System > Ipython (Terminal) ) Just like in my previous blog post, each time a Python statement is entered, the Blender window is updated. So you can move a cube and see the result, if you type:
In [1]: cube = bpy.data.objects['Cube']
In [2]: cube.LocX = -1
When you want to return to Blender, press Ctrl-D. If you restart later the IPython terminal, it will remember any commands you have typed or any variables you have declared (like cube in the example).
IPython has a different prompt which makes it easy to go back to previous input statements or output values:
In [1]: a=1
In [2]: print a
1
In [3]: a
Out[3]: 1
In [4]: exec _i2 # execute second command
1
In [5]: exec In[2:4] # execute multiple previous commands
1
In [6]: b=_3 # third ouput value
In [7]: a==b
Out[7]: True
If you prefer a standard python prompt (>>>), just enter '%doctest_mode':
In [1]: %doctest_mode
*** Pasting of code with ">>>" or "..." has been enabled.
Exception reporting mode: Plain
Doctest mode is: ON
>>>
For auto completion, press the TAB key:
In [1]: bpy.data.
bpy.data.__class__ bpy.data.curves
bpy.data.__delattr__ bpy.data.fonts
bpy.data.__dict__ bpy.data.groups
bpy.data.__doc__ bpy.data.images
bpy.data.__getattribute__ bpy.data.ipos
bpy.data.__hash__ bpy.data.lamps
bpy.data.__init__ bpy.data.lattices
bpy.data.__name__ bpy.data.materials
bpy.data.__new__ bpy.data.meshes
bpy.data.__reduce__ bpy.data.metaballs
bpy.data.__reduce_ex__ bpy.data.objects
bpy.data.__repr__ bpy.data.scenes
bpy.data.__setattr__ bpy.data.sounds
bpy.data.__str__ bpy.data.texts
bpy.data.actions bpy.data.textures
bpy.data.armatures bpy.data.worlds
bpy.data.cameras
In [1]: bpy.data.m
bpy.data.materials bpy.data.meshes bpy.data.metaballs
In [1]: from Blender import M
Material Mathutils Mesh Metaball Modifier
As shown in the last example auto completion works even for import statements.
Altough the Blender window updates itself, the Blender user interface is still irresponsive when running an IPython session. In a future blog post I'll show how to run IPython inside the Blender window in such way that the user interface stays fully responsive.