[sorry that this posting may double but i failed to post this on a new thread and even 'mutt' with 120 columns doesn't show the subject anymore] 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 _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev ----- End forwarded message ----- -- "Why are people killing each other when there is so much fun stuff to be had through friendly cooperation?" (Bengt Richter on c.l.py) "Why are people killing each other when there is so much fun stuff to be had through friendly cooperation?" (Bengt Richter on c.l.py)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4