Staging
v0.8.1
https://github.com/python/cpython
Revision de4f05b741aacf545d2fb844329d930877117ee2 authored by Éric Araujo on 05 August 2011, 23:51:07 UTC, committed by Éric Araujo on 05 August 2011, 23:51:07 UTC
site.USER_BASE and site.USER_SITE are now fully documented.  PEP 370 is
outdated with respects to the Mac framework situation, but the code in
sysconfig and the example in the 3.2 What’s New document helped me find
the right values to document for Mac OS X.

The command-line interface of the site module, partly documented in the
3.2 What’s New, is fully described in the module docs.

The purpose of the usercustomize module is explained in the site docs,
with a gentle introduction in the tutorial (right after the section that
talks about PYTHONSTARTUP; a comment mentions it should be moved from
the tutorial to another file, but that will be another bug).

Various markup and wording improvements were made along the way in the
site module docs.  Duplicate and incomplete declarations of environment
variables have also been removed (the original bug report was actually
about these entries :).  The site module docs are still a bit messy;
I’ll see about improving them for #11553.

All these sections are copiously interlinked and findable from the doc
indexes.
1 parent e5cad23
Raw File
Tip revision: de4f05b741aacf545d2fb844329d930877117ee2 authored by Éric Araujo on 05 August 2011, 23:51:07 UTC
Improve documentation for PEP 370 support in site module (#8617).
Tip revision: de4f05b
contextlib.py
"""Utilities for with-statement contexts.  See PEP 343."""

import sys
from functools import wraps
from warnings import warn

__all__ = ["contextmanager", "closing", "ContextDecorator"]


class ContextDecorator(object):
    "A base class or mixin that enables context managers to work as decorators."

    def _recreate_cm(self):
        """Return a recreated instance of self.

        Allows otherwise one-shot context managers like
        _GeneratorContextManager to support use as
        decorators via implicit recreation.

        Note: this is a private interface just for _GCM in 3.2 but will be
        renamed and documented for third party use in 3.3
        """
        return self

    def __call__(self, func):
        @wraps(func)
        def inner(*args, **kwds):
            with self._recreate_cm():
                return func(*args, **kwds)
        return inner


class _GeneratorContextManager(ContextDecorator):
    """Helper for @contextmanager decorator."""

    def __init__(self, func, *args, **kwds):
        self.gen = func(*args, **kwds)
        self.func, self.args, self.kwds = func, args, kwds

    def _recreate_cm(self):
        # _GCM instances are one-shot context managers, so the
        # CM must be recreated each time a decorated function is
        # called
        return self.__class__(self.func, *self.args, **self.kwds)

    def __enter__(self):
        try:
            return next(self.gen)
        except StopIteration:
            raise RuntimeError("generator didn't yield")

    def __exit__(self, type, value, traceback):
        if type is None:
            try:
                next(self.gen)
            except StopIteration:
                return
            else:
                raise RuntimeError("generator didn't stop")
        else:
            if value is None:
                # Need to force instantiation so we can reliably
                # tell if we get the same exception back
                value = type()
            try:
                self.gen.throw(type, value, traceback)
                raise RuntimeError("generator didn't stop after throw()")
            except StopIteration as exc:
                # Suppress the exception *unless* it's the same exception that
                # was passed to throw().  This prevents a StopIteration
                # raised inside the "with" statement from being suppressed
                return exc is not value
            except:
                # only re-raise if it's *not* the exception that was
                # passed to throw(), because __exit__() must not raise
                # an exception unless __exit__() itself failed.  But throw()
                # has to raise the exception to signal propagation, so this
                # fixes the impedance mismatch between the throw() protocol
                # and the __exit__() protocol.
                #
                if sys.exc_info()[1] is not value:
                    raise


def contextmanager(func):
    """@contextmanager decorator.

    Typical usage:

        @contextmanager
        def some_generator(<arguments>):
            <setup>
            try:
                yield <value>
            finally:
                <cleanup>

    This makes this:

        with some_generator(<arguments>) as <variable>:
            <body>

    equivalent to this:

        <setup>
        try:
            <variable> = <value>
            <body>
        finally:
            <cleanup>

    """
    @wraps(func)
    def helper(*args, **kwds):
        return _GeneratorContextManager(func, *args, **kwds)
    return helper


class closing(object):
    """Context to automatically close something at the end of a block.

    Code like this:

        with closing(<module>.open(<arguments>)) as f:
            <block>

    is equivalent to this:

        f = <module>.open(<arguments>)
        try:
            <block>
        finally:
            f.close()

    """
    def __init__(self, thing):
        self.thing = thing
    def __enter__(self):
        return self.thing
    def __exit__(self, *exc_info):
        self.thing.close()
back to top