[Python-Dev] Terminology for PEP 343

Nick Coghlan ncoghlan at gmail.com
Mon Jul 4 13:14:15 CEST 2005


Take II on some draft docs (accuracy of specific examples obviously 
depends on other PEP 343 and PEP 342 related updates).

Based on the various discussions, the following suggests the term 
"suite managers". That focuses on the fact that we're doing something 
before and after the contained suite.

The fact that they bracket a single suite seems to be the only thing 
the assorted uses really have in common, and emphasising that seems to 
work well. It's certainly the first case where I've been able to 
easily explain what decimal.Context does (or will do) when used in a 
'with' statement.

Cheers,
Nick.

"""
With Statements and Suite Management

A frequent need in programming is to ensure a particular action is
taken after a specific section of code has been executed (e.g. closing 
a file, or releasing a lock). The tool to achieve this in Python is 
the 'with' statement. 'with' statements are used to ensure a 
particular action is taken before the contained suite is entered, and 
a second action when the suite is exited.

The precise behaviour of the 'with' statement is governed by the 
supplied suite manager - an object which supports the suite management
protocol. This protocol consists of two methods:

    __enter__(self):
      This method is called without arguments before the contained 
suite is entered. If the 'as' clause of the 'with' statement is used, 
the value returned from this method is assigned to the identified target.
      Many suite managers will return self from the __enter__ method, 
but returning a different object may make sense for some managers 
(e.g. see the 'closing' suite manager example below).

    __exit__(self, exc_type, exc_value, exc_traceback):
      This method is called after the contained suite has exited. If 
the suite was left due to an exception, the details of that exception 
are passed as arguments. Otherwise, all three arguments are set to None.
      If exception details are passed in, and this method returns 
without incident, then the original exception continues to propagate. 
Otherwise, the exception raised by this method will replace the 
original exception.

Using Suite Managers to Manage Resources

The simplest use of suite management is to strictly control the 
handling of key resources (e.g. files, generators, database 
connections, synchronisation locks).

These resource managers will generally acquire the resource in their 
__enter__ method, although some resource managers may accept the 
resource to be managed as an argument to the constructor or acquire it 
during construction. Resource managers will then release the resource 
in their __exit__ method.

Some resources (e.g. threading.Lock) support the suite management 
protocol natively, allowing them to be used directly in 'with' statements.

While resource management is the most obvious use of the suite 
management protocol, more complex uses are also possible. For example, 
when used as suite managers, decimal.Context objects set themselves as 
the current context before the suite is entered, and then 
automatically revert back to the previous context as the suite is 
exited. This allows the code in the contained suite to manipulate the 
context freely, without needing to worry about manually undoing any 
changes. Other possibilities for suite management include automatic 
exception logging or database transaction handling.

Using Generators to Define Suite Managers

In conjunction with the 'suite_manager' decorator, Python's
generators provide a convenient way to implement the suite
management protocol, and share state between the __enter__ and
__exit__ methods.

The generator must yield exactly once during normal execution. The 
suite manager's __enter__ method executes the generator up to that 
point, and the value yielded is returned. The remainder of the 
generator is executed by the suite manager's __exit__ method. Any 
exceptions that occur in the managed suite will be injected into the 
generator at the location of the yield statement.

For example, the following suite manager allows prompt closure of
any resource with a 'close' method (e.g. a generator or file):

    @suite_manager
    def closing(resource):
        try:
            yield resource
        finally:
            resource.close()
"""
-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://boredomandlaziness.blogspot.com


More information about the Python-Dev mailing list