On Thu, Oct 17, 2013 at 9:06 AM, Barry Warsaw <ba...@python.org> wrote:
> On Oct 18, 2013, at 01:26 AM, Nick Coghlan wrote: > > >By contrast, suppress() and redirect_stdout() are the *first* general > >purpose context managers added to contextlib since its incarnation in > >Python 2.5 (although there have been many various domain specific > >context manager additions elsewhere in the standard library). > > There's a fundamental conceptual shift here that's worth exploring more, > and > which I think was first identified by RDM. > > Until now, context managers were at their heart (at least IMHO) about > managing > "resources". A general resource might be an open file, or it might be a > database transaction, or even the current working directory. Context > managers > (as expressed elegantly by the `with` statement) are used to ensure that a > resource acquired for some limited operation is - to Python's best ability > - > "released" at the end of that operation, no matter what happens. E.g. the > file is closed even if there's a write error, or the current working > directory > is restored to its original location. > > We need only look at the typical @contextmanager use to see the idiom they > embody. As shown in the docstring: > > @contextmanager > def acquire(): > resource = get_some_resource() > try: > yield # execute the operation > finally: > # No matter what happened above... > resource.free() > > redirect_stdout() conforms to this fine tradition, with the resource being > sys.stdout. > > suppress() breaks the mold, which I think is what is breaking people's > brains. It isn't about guaranteeing that a resource is restored to its > original value after some operation. It's about short circuiting that > operation. > > Just look at the implementation to see this shift in perspective. It > doesn't > use try/finally, it uses try/except. > > So it's important to acknowledge that suppress() is charting new territory > and > it will take some exploration and experimentation to get used to, or maybe > even to decide whether it's a good idea. It'll be interesting to see > whether > this fundamental difference is easily explained, understood, and > internalized > and that will go a long way to figuring out whether this is a good idea to > be > expanded on in the future. > Is this shift to do non-resourcey-things really new? In 2009 when doing *great things* to the unittest module for the upcoming Python 2.7 we (michael foord I believe) turned the previous None return value of assertRaises into a context manager so that it could be used in a non-resource-management manner similar to: with self.assertRaises(SomeError) as context: state = set_something_up() call_offending_thing_on_it(state) self.assertIn('Bloody Murder!', context.exception.msg) I thought this was great. As did a bunch of other people in the room. Thus we have it and happily use it. It certainly is _not at all_ how I had ever been thinking of context managers before this feature was added. I had pigeon holed them into resource management tasks in my mind rather than thinking of them as a replacement for try..except syntax in common cases. -gps
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com