FAQ
I'm writing some code that writes to a mbox file and want to retry
locking the mbox file a few times before giving up. I can't see a
really tidy way to implement this.

Currently I have something like:-

dest = mailbox.mbox(mbName, factory=None)

for tries in xrange(3):
try:
dest.lock()
#
#
# Do some stuff to the mbox file
#
dest.unlock()
break # done what we need, carry on

except mailbox.ExternalClashError:
log("Destination locked, try " + str(tries))
time.sleep(1)
# and try again

... but this doesn't really work 'nicely' because the break after
dest.unlock() takes me to the same place as running out of the number
of tries in the for loop. I need a way to handle the case where we
run out of tries (and *haven't* done what we needed to do) separately
from the case where it worked OK.

I can see all sorts of messy ways to handle this with a flag of some
sort but is there a proper elegant way of doing it?


--
Chris Green

Search Discussions

  • Matteo Landi at Oct 17, 2010 at 5:15 pm
    You can use the 'else' keyword outside the for loop:

    for <condition>:
    if <condition>:
    break
    else
    <some operations>

    The execution will step inside the else branch if the for loop ends
    normally, i.e. without encountering a break keyword.
    Hope it helps.

    Regards,
    Matteo
    On Sun, Oct 17, 2010 at 6:58 PM, wrote:
    I'm writing some code that writes to a mbox file and want to retry
    locking the mbox file a few times before giving up. ?I can't see a
    really tidy way to implement this.

    Currently I have something like:-

    ? ?dest = mailbox.mbox(mbName, factory=None)

    ? ?for tries in xrange(3):
    ? ? ? ?try:
    ? ? ? ? ? ?dest.lock()
    ? ? ? ? ? ?#
    ? ? ? ? ? ?#
    ? ? ? ? ? ?# Do some stuff to the mbox file
    ? ? ? ? ? ?#
    ? ? ? ? ? ?dest.unlock()
    ? ? ? ? ? ?break ? ? ? # done what we need, carry on

    ? ? ? ?except mailbox.ExternalClashError:
    ? ? ? ? ? ?log("Destination locked, try " + str(tries))
    ? ? ? ? ? ?time.sleep(1)
    ? ? ? ? ? ?# and try again

    ... but this doesn't really work 'nicely' because the break after
    dest.unlock() takes me to the same place as running out of the number
    of tries in the for loop. ?I need a way to handle the case where we
    run out of tries (and *haven't* done what we needed to do) separately
    from the case where it worked OK.

    I can see all sorts of messy ways to handle this with a flag of some
    sort but is there a proper elegant way of doing it?


    --
    Chris Green
    --
    http://mail.python.org/mailman/listinfo/python-list


    --
    Matteo Landi
    http://www.matteolandi.net/
  • Chris Torek at Oct 17, 2010 at 5:52 pm

    In article <4imro7-ds6.ln1 at chris.zbmc.eu>, wrote:
    I'm writing some code that writes to a mbox file and want to retry
    locking the mbox file a few times before giving up. ...
    dest = mailbox.mbox(mbName, factory=None)
    for tries in xrange(3):
    try:
    dest.lock()
    #
    #
    # Do some stuff to the mbox file
    #
    dest.unlock()
    break # done what we need, carry on

    except mailbox.ExternalClashError:
    log("Destination locked, try " + str(tries))
    time.sleep(1)
    # and try again

    ... but this doesn't really work 'nicely' because the break after
    dest.unlock() takes me to the same place as running out of the number
    of tries in the for loop.
    Seems to me the "right place" for this is a little wrapper lock as
    it were:

    def retried_lock(max_attempts=3):
    for tries in xrange(max_attempts):
    try:
    self.lock()
    return # got the lock
    except mailbox.ExternalClashError:
    log and sleep here
    raise mailbox.ExternalClashError # or whatever

    and now instead of dest.lock() you just do a dest.retried_lock().

    Plumbing (including fitting this in as a context manager so
    that you can just do "with dest" or some such) is left as an
    exercise, :-)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40?39.22'N, 111?50.29'W) +1 801 277 2603
    email: gmail (figure it out) http://web.torek.net/torek/index.html
  • Tinnews at Oct 17, 2010 at 7:02 pm

    Matteo Landi wrote:
    On Sun, Oct 17, 2010 at 6:58 PM, wrote:
    I'm writing some code that writes to a mbox file and want to retry
    locking the mbox file a few times before giving up. ?I can't see a
    really tidy way to implement this.

    Currently I have something like:-

    ? ?dest = mailbox.mbox(mbName, factory=None)

    ? ?for tries in xrange(3):
    ? ? ? ?try:
    ? ? ? ? ? ?dest.lock()
    ? ? ? ? ? ?#
    ? ? ? ? ? ?#
    ? ? ? ? ? ?# Do some stuff to the mbox file
    ? ? ? ? ? ?#
    ? ? ? ? ? ?dest.unlock()
    ? ? ? ? ? ?break ? ? ? # done what we need, carry on

    ? ? ? ?except mailbox.ExternalClashError:
    ? ? ? ? ? ?log("Destination locked, try " + str(tries))
    ? ? ? ? ? ?time.sleep(1)
    ? ? ? ? ? ?# and try again

    ... but this doesn't really work 'nicely' because the break after
    dest.unlock() takes me to the same place as running out of the number
    of tries in the for loop. ?I need a way to handle the case where we
    run out of tries (and *haven't* done what we needed to do) separately
    from the case where it worked OK.

    I can see all sorts of messy ways to handle this with a flag of some
    sort but is there a proper elegant way of doing it?
    You can use the 'else' keyword outside the for loop:

    for <condition>:
    if <condition>:
    break
    else
    <some operations>

    The execution will step inside the else branch if the for loop ends
    normally, i.e. without encountering a break keyword.
    Hope it helps.
    Thank you! I'd looked at 'else' inside the 'try' but hadn't thought
    of looking at the 'else' that goes with 'for'. That does just what I
    need.

    --
    Chris Green
  • Dave Angel at Oct 17, 2010 at 9:19 pm

    On 2:59 PM, tinnews at isbd.co.uk wrote:
    I'm writing some code that writes to a mbox file and want to retry
    locking the mbox file a few times before giving up. I can't see a
    really tidy way to implement this.

    Currently I have something like:-

    dest = mailbox.mbox(mbName, factory=None)

    for tries in xrange(3):
    try:
    dest.lock()
    #
    #
    # Do some stuff to the mbox file
    #
    dest.unlock()
    break # done what we need, carry on

    except mailbox.ExternalClashError:
    log("Destination locked, try " + str(tries))
    time.sleep(1)
    # and try again

    ... but this doesn't really work 'nicely' because the break after
    dest.unlock() takes me to the same place as running out of the number
    of tries in the for loop. I need a way to handle the case where we
    run out of tries (and *haven't* done what we needed to do) separately
    from the case where it worked OK.

    I can see all sorts of messy ways to handle this with a flag of some
    sort but is there a proper elegant way of doing it?
    The usual idiom for telling whether you ever finished a loop is to use
    the else: clause. Else is only executed if break was never executed.

    for ....
    if something
    do...success
    break
    else
    do ... one failure
    (continue)
    else:
    ...None of the loops succeeded

    In your case you're using try/except, rather than if/else, but the outer
    mechanism still holds.

    DaveA

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedOct 17, '10 at 4:58p
activeOct 17, '10 at 9:19p
posts5
users4
websitepython.org

People

Translate

site design / logo © 2022 Grokbase