[Python-Dev] Why are contexts also managers? (was r45544 - peps/trunk/pep-0343.txt)
Nick Coghlan
ncoghlan at gmail.com
Fri Apr 21 11:31:35 CEST 2006
Guido van Rossum wrote:
> Sorry Nick, but you've still got it backwards. The name of the
> decorator shouldn't indicate the type of the return value (of calling
> the decorated generator) -- it should indicate how we think about the
> function. Compare @staticmethod and @classmethod -- the return type
> doesn't enter into it. I think of the function/generator itself as the
> context manager; it returns a context.
Let me have another go. . .
One of the proposals when Raymond raised the issue of naming the PEP 343
protocol was to call objects with "__enter__"/"__exit__" methods "contexts".
This was rejected because there were too many things (like decimal.Context)
that already used that name but couldn't easily be made to fit the new
definition. So we settled on calling them "context managers" instead.
This wasn't changed by the later discussion that introduced the __context__
method. Instead, the new term "manageable context" (or simply "context") was
introduced to mean "anything with a __context__ method". This was OK, because
existing context objects like decimal.Context could easily add a context
method to return an appropriate context manager.
Notice that in *both* approved versions of PEP 343 (before and after the
inclusion of the __context__ method) the name of the decorator matched the
name of the kind of object returned by the decorated generator function.
*THIS ALL CHANGED AT PYCON* (at least, I assume that's where it happened - it
sure didn't happen on this list, and the timing is about right).
During implementation, the meanings of "context" and "context manager" were
swapped from the meanings in the approved PEP, leading to the current
situation where decimal.Context is actually not, in fact, a context. These
meanings were then the ones included in the checked in documentation for
contextlib, and in PJE's recent update to PEP 343 itself.
However, *despite* the meanings of the two terms being swapped, the decorator
kept the same name. This means that when using a generator to create a
"context manager" like decimal.Context under the revised terminology, you are
forced to claim that the __context__ method is itself a context manager:
class Context(object):
# Actually a context manager, despite the class name
@contextlib.contextmanager
def __context__(self):
# Actually a context, despite the decorator name
newctx = self.copy()
oldctx = decimal.getcontext()
decimal.setcontext(newctx)
try:
yield newctx
finally:
decimal.setcontext(oldctx)
I also note that the decimal module in 2.5a1 actually uses the originally
approved PEP 343 terminology, calling the object returned from __context__ a
ContextManager.
And all of this is why I believe we need to either fix the documentation to
use the terminology used in the PEP at the time of approval, or else finish
the job of swapping the two terms and change the name of the decorator. Having
remembered why we picked "context manager" over "context" in the first place,
my preference is strongly for reverting to the original terminology.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://www.boredomandlaziness.org
More information about the Python-Dev
mailing list