a convenient way to deeply nest try/finally statements

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

a convenient way to deeply nest try/finally statements

Shannon -jj Behrens
I'm posting this in the hope someone else will find it useful.  If you
want it, consider it in the public domain.


"""This is a convenient way to deeply nest try/finally statements."""

__docformat__ = "restructuredtext"

# Created: Tue Oct 11 08:42:23 PDT 2005
# Author: Shannon -jj Behrens
# Email: [hidden email]
#
# Copyright (c) Shannon -jj Behrens.  All rights reserved.


def tryFinally(lst):

    """This is a convenient way to deeply nest try/finally statements.

    It is appropriate for complicated resource initialization and destruction.
    For instance, if you have a list of 50 things that need to get intialized
    and later destructed via using try/finally (especially if you need to
    create the list dynamically) this function is appropriate.

    Given::

        lst = [
            ((f_enter_0, f_enter_0_args, f_enter_0_kargs),
             (f_exit_0, f_exit_0_args, f_exit_0_kargs)),

            ((f_enter_1, f_enter_1_args, f_enter_1_kargs),
             (f_exit_1, f_exit_1_args, f_exit_1_kargs)),

            ((f_enter_2, f_enter_2_args, f_enter_2_kargs),
             (f_exit_2, f_exit_2_args, f_exit_2_kargs))
        ]

    Execute::

        f_enter_0(*f_enter_0_args, **f_enter_0_kargs)
        try:

            f_enter_1(*f_enter_1_args, **f_enter_1_kargs)
            try:

                f_enter_2(*f_enter_2_args, **f_enter_2_kargs)
                try:
                    pass
                finally:
                     f_exit_2(*f_exit_2_args, **f_exit_2_kargs)

            finally:
                 f_exit_1(*f_exit_1_args, **f_exit_1_kargs)

        finally:
             f_exit_0(*f_exit_0_args, **f_exit_0_kargs)

    lst
        See the example above.  Note that you can leave out parts of the tuples
        by passing shorter tuples.  For instance, here are two examples::

            # Second tuple missing.
            ((f_enter_2, f_enter_2_args, f_enter_2_kargs),)

            # Leave out args or args and kargs.
            ((f_enter_2,),
             (f_exit_2, f_exit_2_args))

    """

    def castTwoParts(first):
        lenFirst = len(first)
        default = ((), ())
        max = len(default)
        if lenFirst > max:
            raise ValueError("""\
The lst must be a list of tuples of the form (enterTuple, exitTuple).""", first)
        return first + default[lenFirst:]

    def doNothing(*args, **kargs):
        pass

    def castFunctionArgsKargs(fTuple):
        lenFTuple = len(fTuple)
        default = (doNothing, (), {})
        max = len(default)
        if lenFTuple > max:
            raise ValueError("""\
Each tuple in the lst is a pair of tuples that look like (f, args, kargs).""",
                             fTuple)
        return fTuple + default[lenFTuple:]

    if not len(lst):
        return
    first, others = lst[0], lst[1:]
    first = castTwoParts(first)
    first = (castFunctionArgsKargs(first[0]),
             castFunctionArgsKargs(first[1]))
    ((fEnter, fEnterArgs, fEnterKargs),
     (fExit, fExitArgs, fExitKargs)) = first

    fEnter(*fEnterArgs, **fEnterKargs)
    try:
        tryFinally(others)
    finally:
        fExit(*fExitArgs, **fExitKargs)


if __name__ == '__main__':

    from cStringIO import StringIO

    def printEverything(*args, **kargs): print >>buf, `args`, `kargs`
    def refuseArgs(): print >>buf, "refused args"

    lst = [
        ((printEverything, ("f_enter_0_args",), {"in": "in"}),
         (printEverything, ("f_exit_0_args",))),

        ((printEverything,),
         ()),

        ((refuseArgs,),)
    ]

    result = """\
('f_enter_0_args',) {'in': 'in'}
() {}
refused args
('f_exit_0_args',) {}
"""

    buf = StringIO()
    tryFinally(lst)
    assert buf.getvalue() == result

_______________________________________________
Baypiggies mailing list
[hidden email]
http://www.baypiggies.net/cgi-bin/mailman/listinfo/baypiggies
Reply | Threaded
Open this post in threaded view
|

Re: a convenient way to deeply nest try/finally statements

Aahz
On Tue, Oct 11, 2005, Shannon -jj Behrens wrote:
>
> """This is a convenient way to deeply nest try/finally statements."""

While this probably still will be useful, Python 2.5 will have a
``with`` statement that makes it less useful.
--
Aahz ([hidden email])           <*>         http://www.pythoncraft.com/

"If you think it's expensive to hire a professional to do the job, wait
until you hire an amateur."  --Red Adair
_______________________________________________
Baypiggies mailing list
[hidden email]
http://www.baypiggies.net/cgi-bin/mailman/listinfo/baypiggies
Reply | Threaded
Open this post in threaded view
|

Re: a convenient way to deeply nest try/finally statements

Shannon -jj Behrens
I was following the "with" statement thing for a while, but eventually
gave up on keeping up with the dev mailing list.  Please correct me if
I'm wrong, but the benefit of my library is also that you don't have
to nest things inside each other.  I.e. it's a flat list of (init,
destruct) that is implemented as nested try/finallys but doesn't look
like that.  Hence, it's easy to construct such lists and rearrange
them dynamically.

Am I mistaken?

Thanks,
-jj

On 10/11/05, Aahz <[hidden email]> wrote:

> On Tue, Oct 11, 2005, Shannon -jj Behrens wrote:
> >
> > """This is a convenient way to deeply nest try/finally statements."""
>
> While this probably still will be useful, Python 2.5 will have a
> ``with`` statement that makes it less useful.
> --
> Aahz ([hidden email])           <*>         http://www.pythoncraft.com/
>
> "If you think it's expensive to hire a professional to do the job, wait
> until you hire an amateur."  --Red Adair

--
Hacking is to climbing Mt. Everest as
software engineering is to building a Denny's there.

_______________________________________________
Baypiggies mailing list
[hidden email]
http://www.baypiggies.net/cgi-bin/mailman/listinfo/baypiggies
Reply | Threaded
Open this post in threaded view
|

Re: a convenient way to deeply nest try/finally statements

Mike Rovner
Shannon -jj Behrens wrote:
> I was following the "with" statement thing for a while, but eventually
> gave up on keeping up with the dev mailing list.  Please correct me if
> I'm wrong, but the benefit of my library is also that you don't have
> to nest things inside each other.  I.e. it's a flat list of (init,
> destruct) that is implemented as nested try/finallys but doesn't look
> like that.  Hence, it's easy to construct such lists and rearrange
> them dynamically.
>
> Am I mistaken?

That's of cause true, but how often one needs to rearrange program code
dynamically?

Not diminishing the value of your lib, don't take me wrong. In complex
cases even for static use it can be more expressive/maintainable.

Regards,
Mike
_______________________________________________
Baypiggies mailing list
[hidden email]
http://www.baypiggies.net/cgi-bin/mailman/listinfo/baypiggies
Reply | Threaded
Open this post in threaded view
|

Re: a convenient way to deeply nest try/finally statements

Shannon -jj Behrens
On 10/13/05, Mike Rovner <[hidden email]> wrote:

> Shannon -jj Behrens wrote:
> > I was following the "with" statement thing for a while, but eventually
> > gave up on keeping up with the dev mailing list.  Please correct me if
> > I'm wrong, but the benefit of my library is also that you don't have
> > to nest things inside each other.  I.e. it's a flat list of (init,
> > destruct) that is implemented as nested try/finallys but doesn't look
> > like that.  Hence, it's easy to construct such lists and rearrange
> > them dynamically.
> >
> > Am I mistaken?
>
> That's of cause true, but how often one needs to rearrange program code
> dynamically?
>
> Not diminishing the value of your lib, don't take me wrong. In complex
> cases even for static use it can be more expressive/maintainable.

In my situation, since Aquarium is a framework, I needed subclasses to
be able to inject initialization tasks anywhere within an existing
list of initialization tasks and have them all work in the same way:

do stuff
try:
    recursively do all the other stuff
finally:
    try:
        cleanup
    except:
        catch finally exceptions in a consistent manner

This was something that I had needed for years, but had never known
how to deal with elegantly.  By elegantly, I mean "not using
try/finally and marching off the right side of the screen" ;)

Happy Hacking!
-jj

--
Hacking is to climbing Mt. Everest as
software engineering is to building a Denny's there.

_______________________________________________
Baypiggies mailing list
[hidden email]
http://www.baypiggies.net/cgi-bin/mailman/listinfo/baypiggies
Reply | Threaded
Open this post in threaded view
|

Re: a convenient way to deeply nest try/finally statements

Aahz
In reply to this post by Shannon -jj Behrens
On Thu, Oct 13, 2005, Shannon -jj Behrens wrote:

>
> I was following the "with" statement thing for a while, but eventually
> gave up on keeping up with the dev mailing list.  Please correct me if
> I'm wrong, but the benefit of my library is also that you don't have
> to nest things inside each other.  I.e. it's a flat list of (init,
> destruct) that is implemented as nested try/finallys but doesn't look
> like that.  Hence, it's easy to construct such lists and rearrange
> them dynamically.
>
> Am I mistaken?
>
> Thanks,
> -jj
>
> On 10/11/05, Aahz <[hidden email]> wrote:
>> On Tue, Oct 11, 2005, Shannon -jj Behrens wrote:
>>>
>>> """This is a convenient way to deeply nest try/finally statements."""
>>
>> While this probably still will be useful, Python 2.5 will have a
>> ``with`` statement that makes it less useful.
>> --
>> Aahz ([hidden email])           <*>         http://www.pythoncraft.com/
>>
>> "If you think it's expensive to hire a professional to do the job, wait
>> until you hire an amateur."  --Red Adair
>
> --
> Hacking is to climbing Mt. Everest as
> software engineering is to building a Denny's there.

Not really mistaken, no.  My point was that there will overall be fewer
use cases for your code.

BTW, I'm sticking this down here as a reminder that proper quoting
protocol is to trim excess bits like signatures and put new text below
quotes.
--
Aahz ([hidden email])           <*>         http://www.pythoncraft.com/

"If you think it's expensive to hire a professional to do the job, wait
until you hire an amateur."  --Red Adair
_______________________________________________
Baypiggies mailing list
[hidden email]
http://www.baypiggies.net/cgi-bin/mailman/listinfo/baypiggies
Reply | Threaded
Open this post in threaded view
|

Re: a convenient way to deeply nest try/finally statements

tpc247

On 10/13/05, Aahz <[hidden email]> wrote:
On Thu, Oct 13, 2005, Shannon -jj Behrens wrote:

>
> I was following the "with" statement thing for a while, but eventually
> gave up on keeping up with the dev mailing list.  Please correct me if
> I'm wrong, but the benefit of my library is also that you don't have
> to nest things inside each other.  I.e. it's a flat list of (init,
> destruct) that is implemented as nested try/finallys but doesn't look
> like that.  Hence, it's easy to construct such lists and rearrange
> them dynamically.
>
> Am I mistaken?
>
> On 10/11/05, Aahz <[hidden email]> wrote:
>> On Tue, Oct 11, 2005, Shannon -jj Behrens wrote:
>>>
>>> """This is a convenient way to deeply nest try/finally statements."""
>>
>> While this probably still will be useful, Python 2.5 will have a
>> ``with`` statement that makes it less useful.

Not really mistaken, no.  My point was that there will overall be fewer
use cases for your code.

BTW, I'm sticking this down here as a reminder that proper quoting
protocol is to trim excess bits like signatures and put new text below
quotes.

on an unrelated note, proper quoting protocol according to who ?  I was not aware there was a commonly accepted standard for quoting in email...
 

_______________________________________________
Baypiggies mailing list
[hidden email]
http://www.baypiggies.net/cgi-bin/mailman/listinfo/baypiggies
Reply | Threaded
Open this post in threaded view
|

Re: a convenient way to deeply nest try/finally statements

Tony Cappellini-2

>on an unrelated note, proper quoting protocol according to who ?  I was not aware there was a commonly accepted standard for quoting in >>email...
 
Not copying the entire digest (or the entire previous mail on lengthy mail) back to the list is the generally accepted standard.
This holds true on many mailing lists. Typically, a few lines or short paragraph of the mail being replied to is sufficient to show the context.

 

_______________________________________________
Baypiggies mailing list
[hidden email]
http://www.baypiggies.net/cgi-bin/mailman/listinfo/baypiggies
Reply | Threaded
Open this post in threaded view
|

Re: a convenient way to deeply nest try/finally statements

wesley chun
On 10/17/05, Tony C <[hidden email]> wrote:

>on an unrelated note, proper quoting protocol according to who ?  I was not aware there was a commonly accepted standard for quoting in >>email...
 
Not copying the entire digest (or the entire previous mail on lengthy mail) back to the list is the generally accepted standard.
This holds true on many mailing lists. Typically, a few lines or short paragraph of the mail being replied to is sufficient to show the context.

this goes without saying (maybe it's me), but i dislike excess clutter.

i believe Aahz's issue is b/w replying at the top/quoting at the bottom (the more Win32/outlook way), or vice versa: quoting at the top, replying at the bottom, the more "Unix-y" way of e-mail replies.  i've been guilty of both, depending on the context and relevance of the threads.

-- wesley
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"Core Python Programming", Prentice Hall, (c)2006,2001
    http://corepython.com

wesley.j.chun :: wescpy-at-gmail.com
cyberweb.consulting : silicon valley, ca
http://cyberwebconsulting.com
_______________________________________________
Baypiggies mailing list
[hidden email]
http://www.baypiggies.net/cgi-bin/mailman/listinfo/baypiggies
Reply | Threaded
Open this post in threaded view
|

Re: a convenient way to deeply nest try/finally statements

Guido van Rossum
>  this goes without saying (maybe it's me), but i dislike excess clutter.

So let this be the last message about quoting styles.

--
--Guido van Rossum (home page: http://www.python.org/~guido/)

_______________________________________________
Baypiggies mailing list
[hidden email]
http://www.baypiggies.net/cgi-bin/mailman/listinfo/baypiggies