[Python-Dev] PEP 343: confusing context terminology (original) (raw)

A.M. Kuchling amk at amk.ca
Tue Apr 18 16:04:19 CEST 2006


PEP 343 says:

This PEP proposes that the protocol used by the with statement be
known as the "context management protocol", and that objects that
implement that protocol be known as "context managers". The term
"context" then encompasses all objects with a __context__() method
that returns a context manager (this means that all context managers
are contexts, but not all contexts are context managers).

I read this paragraph as meaning:

context = 'thing with __context__()'
context manager = 'thing returned by __context__()'

So in a 'with' statement:

with A as B: ...

A is a context; the context manager is internal and unavailable.

The PEP uses this terminology, but the documentation for contextlib seems to reverse things. The decorator is called '@contextmanager', not '@context', and the text says things like:

Note that you can use \code{@contextmanager} to define a context
manager's \method{__context__} method.  This is usually more convenient
than creating another class just to serve as a context.  For example:

or:

\begin{funcdesc}{nested}{ctx1\optional{, ctx2\optional{, ...}}}
Combine multiple context managers into a single nested context manager.

ref/ref3.tex uses the terms one way, then reverses them:

A \dfn{context manager} is an object that manages the entry
to, and exit from, a \dfn{context} surrounding a block of
code.  Context managers are normally invoked using the
\keyword{with} statement (described in section~\ref{with}),
but can also be used by directly invoking their methods.

\begin{methoddesc}[context manager]{__context__}{self} 

Invoked when the object is used as the context expression of a
\keyword{with} statement.  The return value must implement
\method{__enter__()} and \method{__exit__()} methods.  Simple
context managers that wish to directly implement
\method{__enter__()} and \method{__exit__()} should just
return \var{self}.

Context managers written in Python can also implement this
method using a generator function decorated with the
\function{contextlib.contextmanager} decorator, as this can be
simpler than writing individual \method{__enter__()} and
\method{__exit__()} methods when the state to be managed is
complex.

Personally, I find this terminology counterintuitive. The "What's New" uses 'context manager = thing with __context()' because I read the first paragraph quoted from PEP 343, got confused, decided it couldn't possibly mean what it said, and fell back on the intuition that a 'manager' is usually a big long-lived thing while a 'context' is more likely to be a transient thing that exists for the duration of a statement and is then discarded.

So, my questions:

1) Am I misunderstanding the PEP?  Is 
   'context = 'thing with __context__()' really the PEP's
   meaning?

2) If the answer to 1) is 'yes', can we change the PEP?  

   My intuition is that a 'manager' keeps track of multiple
   entities being managed; to have a single 'context' produce
   multiple 'context managers' over time seems exactly
   backwards.

   I think I understand the logic behind the name -- that the
   context manager *manages* the entry to and exit from the
   block -- but think 'Manager' is the wrong term for this
   because the object is really encapsulating a
   procedure/algorithm, not managing a set of objects.  The
   closest GoF pattern name might be 'Strategy', which is
   still a bit of a stretch.

    3) If the answer to 2) is "buzz off" :), the documentation
     (lib/contextlib, RefGuide, and What's New) needs to be fixed 
   to use the terminology consistent with PEP 343.  I'll do
   the "What's New", but someone else would have to update the
   other two.

--amk



More information about the Python-Dev mailing list