[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