On Wed, Feb 29, 2012 at 09:02, Craig Yoshioka <
craigyk@me.com> wrote:
> So I've recently been trying to implement something for which I had hoped the 'with' statement would be perfect, but it turns out, won't work because Python provides no mechanism by which to skip the block of code in a with statement.
>
> I want to create some functionality to make it easy too wrap command line programs in a caching architecture. To do this there are some things that need to happen before and after the wrapped CLI program is called, a try,except,finally version might look like this:
>
> def cachedcli(*args):
> try:
> hashedoutput = hashon(args)
> if iscached():
> return hashedoutput
> acquirelock()
> cli(*args,hashedoutput)
> iscached(True)
> return hashedoutput
> except AlreadyLocked:
> while locked:
> wait()
> return example(*args)
> finally:
> releaselock()
>
> the 'with' version would look like
>
> def cachedcli(*args)
> hashedpath = hashon(args)
> with cacheon(hashedpath):
> cli(hashedpath,*args)
> return hashedpath
>
>
> So obviously the 'with' statement would be a good fit, especially since non-python programmers might be wrapping their CLI programs... unfortunately I can't use 'with' because I can't find a clean way to make the with block code conditional.
>
> PEP377 suggested some mechanics that seemed a bit complicated for getting the desired effect, but I think, and correct me if I'm wrong, that the same effect could be achieved by having the __enter__ function raise a StopIteration that would be caught by the context and skip directly to the __exit__ function. The semantics of this even make some sense too me, since the closest I've been able to get to what I had hoped for was using an iterator to execute the appropriate code before and after the loop block:
>
> def cachedcli(*args)
> hashedpath = hashon(args)
> for _ in cacheon(hashedpath):
> cli(hashedpath,*args)
> return hashedpath
>
> this still seems non-ideal to me...
Specifically with regard to caching, I recommend writing a CLI
execution class which implements the caching logic internally.
If you really want to do this with some special syntax sugar, use
decorators, which are good for wrapping functions/methods with
caching.
The "with" statement is IMO not suitable here (and rightfully so).
- Tal Einat