Jason Orendorff wrote: > Phillip J. Eby writes: > >>You didn't offer any reasons why this would be useful and/or good. > > > It makes it dramatically easier to write Python classes that correctly > support 'with'. I don't see any simple way to do this under PEP 343; > the only sane thing to do is write a separate @contextmanager > generator, as all of the examples do.
Hmm, it's kind of like the iterable/iterator distinction. Being able to do: class Whatever(object): def __iter__(self): for item in self.stuff: yield item is a very handy way of defining "this is how you iterate over this class". The only cost is that actual iterators then need to define an __iter__ method that returns 'self' (which isn't much of a cost, and is trivial to do even for iterators written in C). If there was a __with__ slot, then we could consider that as identifying a "manageable context", with three methods to identify an actual context manager: __with__ that returns self __enter__ __exit__ Then the explanation of what a with statement does would simply look like: abc = EXPR.__with__() # This is the only change exc = (None, None, None) VAR = abc.__enter__() try: try: BLOCK except: exc = sys.exc_info() raise finally: abc.__exit__(*exc) And the context management for decimal.Context would look like: class Context: ... @contextmanager def __with__(self): old = decimal.getcontext() new = self.copy() # Make this nesting and thread safe decimal.setcontext(new) try: yield new finally: decimal.setcontext(old) And for threading.Lock would look like: class Lock: ... def __with__(self): return self def __enter__(self): self.acquire() return self def __exit__(self): self.release() Also, any class could make an existing independent context manager (such as 'closing') its native context manager as follows: class SomethingCloseable: ... def __with__(self): return closing(self) > As for the second proposal, I was thinking we'd have one mental model > for context managers (block template generators), rather than two > (generators vs. enter/exit methods). Enter/exit seemed superfluous, > given the examples in the PEP. Try to explain the semantics of the with statement without referring to the __enter__ and __exit__ methods, and then see if you still think they're superfluous ;) The @contextmanager generator decorator is just syntactic sugar for writing duck-typed context managers - the semantics of the with statement itself can only be explained in terms of the __enter__ and __exit__ methods. Indeed, explaining how the @contextmanager decorator itself works requires recourse to the __enter__ and __exit__ methods of the actual context manager object the decorator produces. However, I think the idea of have a distinction between manageable contexts and context managers similar to the distinction between iterables and iterators is one well worth considering. Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --------------------------------------------------------------- http://boredomandlaziness.blogspot.com _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com