469,317 Members | 1,697 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,317 developers. It's quick & easy.

Resume after exception

Hi there,

Is it possible to have an 'except' case which passes control back to the
point after the exception occurred?

e.g.

# a function to open the file
# raises FileLockedException is file contains 'locked' information
def open_file(file_name):
f = file(file_name, 'r')
{read first line for file lock info}
if first_line == "FILE LOCKED":
raise FileLockedException(lock_user, lock_timestamp)
{read remainder of file}
return True

# elsewhere in a user interface module
def open_command():
try:
open_file("foo.bar")
except FileLockException, X:
ans = tkMessageBox.askyesno(title="File Locked", message="File
locked by '" + X.user + "' on " + X.time_stamp + "\nContinue
anyway?")
if ans == tkMessageBox.YES:
# return control to the remainder of the open_file function.
How?
else:
return False

Any ideas?

Cheers,
Richard
Jul 19 '05 #1
4 9860
On Tue, 14 Jun 2005 10:09:30 +0100,
"Richard Lewis" <ri**********@fastmail.co.uk> wrote:
Hi there,
Is it possible to have an 'except' case which passes control back to the
point after the exception occurred?


Not that I can think of.

[ example of "interrupting" a file-reading function in order to ask the
user if they really want to read a locked file ]

I would rewrite that this way (untested, and without error checking):

def open_file(file_name, read_if_locked=False):
f = file(file_name)
[read first line]
if first_line == "FILE LOCKED" and read_if_locked == FALSE:
return False
[read the rest]
return True

def open_command():
if open_file("foo.bar") == False:
[ask the user what to do]
if ans == tkMessageBox.YES:
open_file("foo.bar", True )

Regards,
Dan

--
Dan Sommers
<http://www.tombstonezero.net/dan/>
Jul 19 '05 #2
Why does the first function return True? Shouldn't it return the file
content? That's at least what the function name implies.
You call the second function open_command() which returns a boolean.
Feels wrong.

Where you have written "How?" I suggest that you replace that by:
return open_file("foo.bar", 1)

and change open_file() to look something like this:
def open_file(file_name, ignore_lock=False):
f = file(file_name, 'r')
{read first line for file lock info}
if first_line == "FILE LOCKED" and not ignore_lock:
raise FileLockedException(lock_user, lock_timestamp)
{read remainder of file}
return True

Jul 19 '05 #3
Richard Lewis wrote:
Is it possible to have an 'except' case which passes control back to the
point after the exception occurred?


Basically no, although I could imagine some gross hack with the frame
info and some bytecode hacks that effect a "goto". Basically the stack
frame gets unwound to the point where the exception is caught. If you
need recoverability, write your open_file function to be resumable in
some way.

Note that you could easily (perhaps) implement this as a callable
object, with the required state stored internally, and make the result
almost indistinguishable from what you are asking for:

I could imagine an API allowing something like this:

open_file = RecoverableOpenFileThingy()

while not open_file.completed:
try:
open_file("foo.bar")
except FileLockException, ex:
# blah blah
if ans != tkMessageBox.YES:
open_file.completed = True

But since your open_file() doesn't seem likely to be doing anything
particularly complicated, I really doubt you need the complexity of a
special class here. Just stick the relevant code inside a loop, much
like that above, and break out of the loop when things succeed.

(What internal state do you think the open_file procedure would have to
maintain, which you would be trying to resume? If you are just going to
go back to the beginning of it and try again, you don't need anything
like what you asked for, just a regular loop.)
Jul 19 '05 #4
Richard Lewis schreef:
Is it possible to have an 'except' case which passes control back to the
point after the exception occurred?


No, not in Python. The concept has however been discussed, under the
name "resumable exceptions".

http://www.google.com/search?num=100...e%3Apython.org

An excellent article about the concept was written by Kent Pitman:

"Condition Handling in the Lisp Language Family"
http://www.nhplace.com/kent/Papers/C...ling-2001.html

Common Lisp is a language that does have the feature. Your code would
be written in Lisp like below. When the function notices the file is
locked, it will raise an exception. Now imagine there are two ways to
solve the problem: 1) read the file anyway, despite the lock; 2) clear
the lock and read the file. Or reading the file could be cancelled.
These three possible ways to continue the execution are set up by
"restart-case". (So this is actually a generalization of your request,
in that instead of "just continueing", you can direct the way of
continuing)

(defun read-unlocked-file (file-name)
(with-open-file (f file-name)

(when (string= (read-line f) "FILE LOCKED")
(let ((user "lock-user")
(timestamp 123))
(restart-case (error 'file-locked :name file-name
:user user :timestamp timestamp)
(continue () :report "Continue reading the locked file.")
(clear-lock () :report "Clear the lock and continue reading"
(warn "clearing lock..."))
(abort () :report "Abort reading the file."
(return-from read-unlocked-file)))))

(warn "reading remainder of file...")
t))

When reading a locked file, you end up with this message:

CL-USER(31): (read-unlocked-file "file.txt")
Error: File file.txt was locked by lock-user at time 123.
[condition type: FILE-LOCKED]

Restart actions (select using :continue):
0: Continue reading the locked file.
1: Clear the lock and continue reading
2: Abort reading the file.
3: Return to Top Level (an "abort" restart).
4: Abort entirely from this process.

Note the three first "restart actions" are the ones we just defined
inside "read-unlocked-file". Let's continue execution by clearing the
lock (restart number 1):

[1] CL-USER(32): :continue 1
Warning: clearing lock...
Warning: reading remainder of file...
T

If Python had restarts, in your example you would set up code that,
depending on whether the user clicked "abort" or "continue" in the
dialog, automatically invokes the corresponding restart to either
continue or abort the calculation.

Restarts are pretty cool. Maybe Stackless Python could support it
fairly easily, restarts basically being named continuations?
- Willem

Jul 19 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Rob R. Ainscough | last post: by
5 posts views Thread by itsupport1 | last post: by
15 posts views Thread by Neo | last post: by
7 posts views Thread by fniles | last post: by
7 posts views Thread by Rob R. Ainscough | last post: by
11 posts views Thread by Maxwell2006 | last post: by
8 posts views Thread by Adil Akram | last post: by
19 posts views Thread by kimiraikkonen | last post: by
3 posts views Thread by sriharikabattula | last post: by
reply views Thread by suresh191 | last post: by
reply views Thread by harlem98 | last post: by
1 post views Thread by Geralt96 | last post: by
reply views Thread by harlem98 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.