[IPython-user] Embedding IPython with py2exe
Michael Foord
mike at pcblokes.com
Fri Dec 31 08:36:26 CST 2004
Hello All,
I'm by no means an experienced IPython user. I'm currently working on a
project called 'Movable Python'. This uses py2exe to build a standalone,
portable distribution of Python. Basically a version of python that
doesn't need to be installed. (windoze only I'm afraid because it uses
py2exe).
I've added an interactive interpreter to it (effectively replicating the
'-' and '-i' command line options of python) and have provided the
option of using IPython as the console if the distribution was built
with IPython available.
I cam across the following issue when embedding IPython in a py2exe
program. I thought it might be useful to share the information here in
case any other users attempted to do a similar thing.
The function that calls interactive mode is :
def interactive(localvars):
"""A very simple function to embed an interactive interpreter into
movpy."""
IPShellEmbed = None
try:
from IPython.Shell import IPShellEmbed
except ImportError:
pass
if not IPShellEmbed or IPOFF:
from code import InteractiveConsole
con = InteractiveConsole(localvars)
con.interact()
else:
ipshell = IPShellEmbed()
ipshell()
sys.exit()
which is called with :
interactive(locals())
Nice and easy !! Except when called from a py2exe program, site.py isn't
imported. This means that 'copyright' and 'credits' aren't available as
builtins. This causes part of IPython to fail. To rectify this I used
the following code straight from site.py :
###########################################
# Functions from site.py
# Used by IPython
# These add objects would normally be available as builtins in the
python environment
# but aren't in a normal py2exe program !
def setquit():
"""Define new built-ins 'quit' and 'exit'.
These are simply strings that display a hint on how to exit.
"""
if os.sep == ':':
exit = 'Use Cmd-Q to quit.'
elif os.sep == '\\':
exit = 'Use Ctrl-Z plus Return to exit.'
else:
exit = 'Use Ctrl-D (i.e. EOF) to exit.'
__builtin__.quit = __builtin__.exit = exit
class _Printer(object):
"""interactive prompt objects for printing the license text, a list of
contributors and the copyright notice."""
MAXLINES = 23
def __init__(self, name, data, files=(), dirs=()):
self.__name = name
self.__data = data
self.__files = files
self.__dirs = dirs
self.__lines = None
def __setup(self):
if self.__lines:
return
data = None
for dir in self.__dirs:
for filename in self.__files:
filename = os.path.join(dir, filename)
try:
fp = file(filename, "rU")
data = fp.read()
fp.close()
break
except IOError:
pass
if data:
break
if not data:
data = self.__data
self.__lines = data.split('\n')
self.__linecnt = len(self.__lines)
def __repr__(self):
self.__setup()
if len(self.__lines) <= self.MAXLINES:
return "\n".join(self.__lines)
else:
return "Type %s() to see the full %s text" % ((self.__name,)*2)
def __call__(self):
self.__setup()
prompt = 'Hit Return for more, or q (and Return) to quit: '
lineno = 0
while 1:
try:
for i in range(lineno, lineno + self.MAXLINES):
print self.__lines[i]
except IndexError:
break
else:
lineno += self.MAXLINES
key = None
while key is None:
key = raw_input(prompt)
if key not in ('', 'q'):
key = None
if key == 'q':
break
def setcopyright():
"""Set 'copyright' and 'credits' in __builtin__"""
__builtin__.copyright = _Printer("copyright", sys.copyright)
__builtin__.credits = _Printer("credits", """\
Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
for supporting Python development. See www.python.org for more
information.""")
here = os.path.dirname(os.__file__)
__builtin__.license = _Printer(
"license", "See http://www.python.org/%.3s/license.html" % sys.version,
["LICENSE.txt", "LICENSE"],
[os.path.join(here, os.pardir), here, os.curdir])
class _Helper(object):
"""Define the built-in 'help'.
This is a wrapper around pydoc.help (with a twist).
"""
def __repr__(self):
return "Type help() for interactive help, " \
"or help(object) for help about object."
def __call__(self, *args, **kwds):
import pydoc
return pydoc.help(*args, **kwds)
def sethelper():
__builtin__.help = _Helper()
setquit()
setcopyright()
sethelper()
#########################################
This solves the problem neatly. I've also posted this message to the
py2exe mailing list as well. It could also be fixed by testing for
NameError when they are used in IPython... but that may not be a priority.
By the way 'Movable Python' is nearly ready for it's first release. I'm
just finishing enough docs to make it usable. The project home is at
sourceforge. http://sourceforge.net/projects/movpy
You can grab a copy of what is done so far (incomplete docs) from :
http://www.voidspace.org.uk/cgi-bin/voidspace/downman.py?file=testenv.zip
Regards,
Fuzzy
http://www.voidspace.org.uk/python/index.shtml
More information about the IPython-user
mailing list