Hello, I'll try to take the discussion about a "unified approach" towards 'code block' or thunk handling into a fresh thread and present what Michael Hudson truthfully calls "a friendly competing approach". Preliminaries ------------- We have some use cases for a construct that allows encapsulating try/except/finally hooks into an object. Especially for timely finalization (of files, locks or other resources) we don't want to scatter try-finally constructs all over the place. Please understand that the following proposal has nothing to do with "function-level" thunk-manipulation ala classmethod but only with "inline" thunks (which don't and shouldn't have their own scope). Syntax and semantic proposal ---------------------------- I think we can may get away with only a "weak" keyword and allow the aforementioned encapsulation of execution events into an object like this: exec expr [with params]: suite where the expression is evaluated to return a "thunk" handler with these optional "execution" hooks: def __enter__(self): "before suite start" def __except__(self, type, value, tb): "swallow given exception, reraise if neccessary" def __leave__(self): """upon suite finish (not called if __except__ exists and an exception happened) """ The above "with" parameters (of the form name=expr, comma-separated) are bound in local (or global/nested) *and* handler instance namespace. The 'suite' is what we call "thunk". The above logic allows clean timely finalization for *multiple* ressources: exec autoclose() with f1=open(name1), f2=open(name2, 'w'): for line in f1: ... f2.write(...) which would execute as follows a) autoclose() instance is created and stored as the "thunk"-handler b) f1/f2 are stored as attributes on the autoclose instance c) f1/f2 are put into the local/global namespace (and nested ones if rebinding is allowed) d) thunk executes (for line ...) e) autoclose 'leave' hook is called (with or without exception) and is implemented like this: def __leave__(self): for obj in self.__dict__.values(): obj.close() f) thunk handler is removed Because computing 'f1' may succeed but 'f2' can subsequently fail the assignments *have to* execute within "autoclose" control. Now on to the usage of the except hook. Nice use cases might be exec retry(maxretry=3, on=IOError): # do network io-stuff or exec skip_on(AttributeError, TypeError): some_object.notify_hook() but i am sure there are more. Exception handling is often ugly when inlined with the code. I think that stating 'exception behaviour' up-front allows to write nice readable constructs. __exit__ versus __leave__ --------------------------- One remark (mainly to Michael as he does that other patch) about the hook-name __leave__ versus __exit__. we may want to eventually allow 'yield' within the thunk and then '__exit__' would be misleading. Here is the use case: exec self.mylock: # would lock/unlock on entering/leaving # the generator ... for whatever in something: yield whatever ... Or do you think that this (future) use case warrants yet another hook? If there is interest i can probably modify my patch to allow all of the proposed syntax so that you could play around with it. the next additional idea is not essential for my so-far proposal (but hopefully interesting, nonetheless). regards and interested in comments, holger ------------- Catching values ala Quixote ------------------- With my former patch there was another "execution" event: the catching of "dropped" values ala Quixote. For values that are not assigned to a name and would be discarded otherwise the execution handler can implement another hook: def __catch__(self, value): "catch dropped value from thunk" this allows anonymous (un-named) objects to be passed *within the thunk* to the execution handler. some example use-cases: exec debug: if condition: "something questionable happenend" so you can quite completly encapsulate debug-handling into one object. Note that this exec could be special-cased to do nothing if "debug" is None. Another one (ala the Quixote-framework): exec html_stream: "<h1>title</h1>" "<p>%s</p>" % html_quote(para) or even: exec html.tr(): exec html.td(): "column" which comes close to what Walter wants. And maybe you understand now why I choose this strange xml-syntax with my former patch :-) Actually i didn't have the idea of reusing 'exec' which makes a lot more sense to me, now. again with regards and intersted in any remarks, holger