Move the PEP 343 documentation and implementation closer to the

terminology in the alpha 1 documentation.

 - "context manager" reverts to its alpha 1 definition
 - the term "context specifier" goes away entirely
 - contextlib.GeneratorContextManager is renamed GeneratorContext

There are still a number of changes relative to alpha 1:

  - the expression in the with statement is explicitly called the
    "context expression" in the language reference
  - the terms 'with statement context', 'context object' or 'with
    statement context' are used in several places instead of a bare
    'context'. The aim of this is to avoid ambiguity in relation to the
    runtime context set up when the block is executed, and the context
    objects that already exist in various application domains (such as
    decimal.Context)
  - contextlib.contextmanager is renamed to contextfactory
    This best reflects the nature of the function resulting from the
    use of that decorator
  - decimal.ContextManager is renamed to WithStatementContext
    Simple dropping the 'Manager' part wasn't possible due to the
    fact that decimal.Context already exists and means something
    different. WithStatementContext is ugly but workable.

A technically unrelated change snuck into this commit:
contextlib.closing now avoids the overhead of creating a
generator, since it's trivial to implement that particular
context manager directly.
This commit is contained in:
Nick Coghlan 2006-04-25 10:56:51 +00:00
parent 327ea38cc4
commit a7e820a408
7 changed files with 165 additions and 141 deletions

View file

@ -2,10 +2,10 @@
import sys
__all__ = ["contextmanager", "nested", "closing"]
__all__ = ["contextfactory", "nested", "closing"]
class GeneratorContextManager(object):
"""Helper for @contextmanager decorator."""
class GeneratorContext(object):
"""Helper for @contextfactory decorator."""
def __init__(self, gen):
self.gen = gen
@ -48,8 +48,8 @@ class GeneratorContextManager(object):
raise
def contextmanager(func):
"""@contextmanager decorator.
def contextfactory(func):
"""@contextfactory decorator.
Typical usage:
@ -77,7 +77,7 @@ def contextmanager(func):
"""
def helper(*args, **kwds):
return GeneratorContextManager(func(*args, **kwds))
return GeneratorContext(func(*args, **kwds))
try:
helper.__name__ = func.__name__
helper.__doc__ = func.__doc__
@ -87,7 +87,7 @@ def contextmanager(func):
return helper
@contextmanager
@contextfactory
def nested(*contexts):
"""Support multiple context managers in a single with-statement.
@ -133,9 +133,8 @@ def nested(*contexts):
raise exc[0], exc[1], exc[2]
@contextmanager
def closing(thing):
"""Context manager to automatically close something at the end of a block.
class closing(object):
"""Context to automatically close something at the end of a block.
Code like this:
@ -151,7 +150,11 @@ def closing(thing):
f.close()
"""
try:
yield thing
finally:
thing.close()
def __init__(self, thing):
self.thing = thing
def __context__(self):
return self
def __enter__(self):
return self.thing
def __exit__(self, *exc_info):
self.thing.close()