I lost the original thread, but my first thought was to use the readline
module's history capability to save and reload a "session". This hack
partially works for what little testing I've done (place it in
sitecustomize.py):
import readline
import os
import sys
_start_len = len(open(os.path.expanduser("~/.pyhist")).readlines())
_session_file = os.path.expanduser("~/.pysession")
def save(f=_session_file, start=_start_len):
sf = open(f, 'w')
while True:
line = readline.get_history_item(start)
start += 1
if line is None:
break
if line.startswith('save(') or line.startswith('load('):
continue
sf.write(line+"\n")
def load(f=_session_file):
execfile(f, sys._getframe(-1).f_globals)
import __builtin__
__builtin__.save = save
__builtin__.load = load
My readline history is stored in ~/.pyhist. I can't use
readline.get_history_length() to mark the start of a session for reasons
which are not obvious to me. When I first started futzing around with it,
readline.get_history_length() returned 9934. Now, even though my ~/.pyhist
file has more than 9960 lines, get_history_length() seems to always return
-1, thus making it useless in this context.
Here's a simple session showing save() and load() within the same session:
>>> import math
>>> print math.sin(47)
0.123573122745
>>> def f():
... return math.sin(48)
...
>>> save()
>>> load()
0.123573122745
>>> f
At 02:35 PM 12/1/03 -0600, Skip Montanaro wrote:
My readline history is stored in ~/.pyhist. I can't use readline.get_history_length() to mark the start of a session for reasons which are not obvious to me.
get_history_length() is the length you've set for truncation, not the actual length. You want get_current_history_length(), IIRC.
>> My readline history is stored in ~/.pyhist. I can't use >> readline.get_history_length() to mark the start of a session for >> reasons which are not obvious to me. Phillip> get_history_length() is the length you've set for truncation, Phillip> not the actual length. You want get_current_history_length(), Phillip> IIRC. Yes, thanks. I decided to dispense with accessing the "start" of the session and force the user to simply mark() where a session is to start. That's one extra function to remember, but seems a lot more flexible. Appended is my current incarnation. Still doesn't load() right, though save() seems to work. Usage is: mark() ... bunch of commands at the interpreter prompt ... save() Any clues about what I'm doing wrong in load()? I want to stuff the evaluated objects into the globals() of the caller (that is, the globals for the interactive session in most situations). Skip import readline import os import sys # needs to match the filename the user uses! _histfile = os.path.expanduser("~/.pyhist") # where we save sessions _session_file = os.path.expanduser("~/.pysession") # mark with something valid at the interpreter but unlikely to be executed # by the user _marker = '((1.0+999.0j, "mark", 999.0-1.0j))' def save(): end = readline.get_current_history_length() - 1 session = [] item = readline.get_history_item(end) while item != _marker: session.insert(0, item+"\n") end -= 1 item = readline.get_history_item(end) file(_session_file, 'w').writelines(session) print >> sys.stderr, "saved session to", _session_file def load(): execfile(_session_file, sys._getframe(-1).f_globals) print >> sys.stderr, "loaded session from", _session_file def mark(): readline.add_history(_marker) import __builtin__ __builtin__.save = save __builtin__.load = load __builtin__.mark = mark
At 04:10 PM 12/1/03 -0600, Skip Montanaro wrote:
def load(): execfile(_session_file, sys._getframe(-1).f_globals) print >> sys.stderr, "loaded session from", _session_file
What does getframe with a negative number do? I've only ever used positive numbers when calling getframe. I think maybe you want 1 here, not -1.
"Phillip J. Eby"
What does getframe with a negative number do?
Obviously it uses the time machine to look into the future a little and return a frame that is *going* to be called from the current function... Greg Ewing, Computer Science Dept, +--------------------------------------+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | greg@cosc.canterbury.ac.nz +--------------------------------------+
At 02:27 PM 12/2/03 +1300, Greg Ewing wrote:
"Phillip J. Eby"
What does getframe with a negative number do?
Obviously it uses the time machine to look into the future a little and return a frame that is *going* to be called from the current function...
Actually, it appears to return the same result as sys._getframe(0). Maybe it should raise an exception for a negative value. (OTOH, maybe leaving it so that it silently does something meaningless will help discourage people from using it so often... ;) )
>> > What does getframe with a negative number do? >> Obviously it uses the time machine to look into the future... Phillip> Maybe it should raise an exception for a negative value. Phillip> (OTOH, maybe leaving it so that it silently does something Phillip> meaningless will help discourage people from using it so Phillip> often... ;) ) Yeah, whatever. ;-) At any rate, now that Phillip and Tim straightened me out on my number line basics, there's a simple session save/restore available at http://www.musi-cal.com/~skip/python/save_session.py Making it work on Windows (where it's probably needed more) is left as an exercise for the reader. Skip
participants (3)
-
Greg Ewing
-
Phillip J. Eby
-
Skip Montanaro