[Python-Dev] PEP 343: confusing context terminology

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