[Python-Dev] On suppress()'s trail blazing (was Re: cpython: Rename contextlib.ignored() to contextlib.ignore()) (original) (raw)

Gregory P. Smith greg at krypto.org
Thu Oct 17 22:16:50 CEST 2013


On Thu, Oct 17, 2013 at 9:06 AM, Barry Warsaw <barry at python.org> wrote:

On Oct 18, 2013, at 01:26 AM, Nick Coghlan wrote:

>By contrast, suppress() and redirectstdout() 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 = getsomeresource() try: yield # execute the operation finally: # No matter what happened above... resource.free() redirectstdout() 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20131017/ef7c82f5/attachment.html>



More information about the Python-Dev mailing list