[Python-Dev] With context, please

Nick Coghlan ncoghlan at gmail.com
Sun Apr 23 09:36:50 CEST 2006


Phillip J. Eby wrote:
> Read the first sentence again:
> 
> "EXPRESSION returns a value that the with statement uses to *create* a 
> context" (emphasis added).
> 
> It doesn't say that the value *is* the context, and if anything, the 
> second excerpt supports that by implying that the context manager is the 
> thing passed to the "with" statement.

Things become confused because "context" gets used two different ways: to 
refer to the context object itself, and the runtime state that the context 
manager creates.

Every case I've seen it used in user-oriented documentation it has referred to 
the latter.

There may be only 2 concrete objects involved, but there's actually three 
entities of interest - the context object, the context manager, and the 
nebulous runtime state that makes up the actual "execution context" (i.e. the 
things the context manager *does* based on the current state of the context 
object).

> Also, there haven't been any complaints of the a1 documentation being 
> unclear on this; rather, it was the *PEP* that was considered 
> confusing.  So in effect, we already tested this in a1, with one 
> interpretation in the docs and another in the PEP, and the documenation 
> won.

Except that it breaks down when you actually try to line it up with the code 
(which is where Paul got stuck when reviewing the documentation yesterday):

  - decimal.Context:
     - is not a context according to the current docs
     - decimal.Context.__context__() returns a decimal.ContextManager object
  - contextlib.contextmanager()
      - is actually used to define contexts according to the current docs
      - but returns a GeneratorContextManager object
  - contextlib.nested()
      - uses "contexts" as the name for its arguments
      - uses "context" as the iteration variable
      - uses "mgr" as the name for the result of context.__context__()
  - Compilation/evaluation chain
      - First clause in With statement is named "context_expr"
      - parser takes its cue from the AST definition
      - AST compiler refers to context.__exit__/__enter__ in a comment
      - ceval refers to context.__exit__ in a comment


So the problem is not that the documentation disagrees with the PEP, it's that 
it disagrees with the *implementation*. contextlib.py, decimal.py, Python.asdl 
and ast.c consistently use "context" to refer to the original objects 
provided to the with statement and "context manager" to refer to the return 
value of the __context__ method.

compile.c is confused either way, since it uses "context" for both objects, 
and ceval.c appears to be taking its cue from compile.c :)

(threading.py and fileobject.c just provide the methods directly, so they 
don't mention the terminology at all)

What I'm trying for alpha 2 is to bring the documentation in line with the 
implementation, because I think that's the root of all of the current 
confusion. If things still break down, then we can look at changing both the 
documentation and the implementation to use the alpha 1 terminology post-alpha 2.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://www.boredomandlaziness.org


More information about the Python-Dev mailing list