Change proposed terminology from context object to context specifier
This commit is contained in:
parent
db32145d0e
commit
d36c583656
94
pep-0343.txt
94
pep-0343.txt
|
@ -29,6 +29,9 @@ Author's Note
|
|||
|
||||
Python's alpha release cycle revealed terminology problems in this
|
||||
PEP and in the associated documentation and implementation [14].
|
||||
So while the PEP is already accepted, this refers to the
|
||||
implementation rather than the exact terminology.
|
||||
|
||||
The current version of the PEP reflects the implementation and
|
||||
documentation as at Python 2.5a2. The PEP will be updated to
|
||||
reflect any changes made to the terminology prior to the final
|
||||
|
@ -269,12 +272,12 @@ Specification: The 'with' Statement
|
|||
|
||||
The call to the __context__() method serves a similar purpose to
|
||||
that of the __iter__() method of iterator and iterables. A context
|
||||
object with simple state requirements (such as
|
||||
specifier with simple state requirements (such as
|
||||
threading.RLock) may provide its own __enter__() and __exit__()
|
||||
methods, and simply return 'self' from its __context__ method. On
|
||||
the other hand, a context object with more complex state requirements
|
||||
(such as decimal.Context) may return a distinct context manager
|
||||
each time its __context__ method is invoked.
|
||||
the other hand, a context specifier with more complex state
|
||||
requirements (such as decimal.Context) may return a distinct
|
||||
context manager each time its __context__ method is invoked.
|
||||
|
||||
If the "as VAR" part of the syntax is omitted, the "VAR =" part of
|
||||
the translation is omitted (but mgr.__enter__() is still called).
|
||||
|
@ -321,9 +324,10 @@ Specification: The 'with' Statement
|
|||
of a database transaction roll-back decision.
|
||||
|
||||
To facilitate chaining of contexts in Python code that directly
|
||||
manipulates context objects, __exit__() methods should *not*
|
||||
re-raise the error that is passed in to them, because it is always
|
||||
the responsibility of the *caller* to do any reraising in that case.
|
||||
manipulates context specifiers and managers, __exit__() methods
|
||||
should *not* re-raise the error that is passed in to them, because
|
||||
it is always the responsibility of the *caller* to do any reraising
|
||||
in that case.
|
||||
|
||||
That way, if the caller needs to tell whether the __exit__()
|
||||
invocation *failed* (as opposed to successfully cleaning up before
|
||||
|
@ -349,6 +353,9 @@ Specification: The 'with' Statement
|
|||
with mgr as VAR:
|
||||
BLOCK
|
||||
|
||||
The with statement implementation and examples like the nested()
|
||||
function require this behaviour in order to be able to deal
|
||||
transparently with both context specifiers and context managers.
|
||||
|
||||
Transition Plan
|
||||
|
||||
|
@ -431,7 +438,7 @@ Generator Decorator
|
|||
Just as generator-iterator functions are very useful for writing
|
||||
__iter__() methods for iterables, generator context functions will
|
||||
be very useful for writing __context__() methods for context
|
||||
objects. These methods will still need to be decorated using the
|
||||
specifiers. These methods will still need to be decorated using the
|
||||
contextmanager decorator. To ensure an obvious error message if the
|
||||
decorator is left out, generator-iterator objects will NOT be given
|
||||
a native context - if you want to ensure a generator is closed
|
||||
|
@ -486,8 +493,7 @@ Standard Terminology
|
|||
statement is called the iterator protocol and an iterator is any
|
||||
object that properly implements that protocol. The term "iterable"
|
||||
then encompasses all objects with an __iter__() method that
|
||||
returns an iterator (this means that all iterators are iterables,
|
||||
but not all iterables are iterators).
|
||||
returns an iterator.
|
||||
|
||||
This PEP proposes that the protocol consisting of the __enter__()
|
||||
and __exit__() methods, and a __context__() method that returns
|
||||
|
@ -495,17 +501,18 @@ Standard Terminology
|
|||
objects that implement that protocol be known as "context
|
||||
managers".
|
||||
|
||||
The term "context object" then encompasses all objects with a
|
||||
The term "context specifier" then encompasses all objects with a
|
||||
__context__() method that returns a context manager. The protocol
|
||||
these objects implement is called the "context protocol". This
|
||||
means that all context managers are context objects, but not all
|
||||
context objects are context managers, just as all iterators are
|
||||
iterables, but not all iterables are iterators.
|
||||
these objects implement is called the "context specification
|
||||
protocol". This means that all context managers are context
|
||||
specifiers, but not all context specifiers are context managers,
|
||||
just as all iterators are iterables, but not all iterables are
|
||||
iterators.
|
||||
|
||||
These terms are based on the concept that the context object
|
||||
These terms are based on the concept that the context specifier
|
||||
defines a context of execution for the code that forms the body of
|
||||
the with statement. The role of the context manager is to
|
||||
translate the context object's stored state into an active
|
||||
translate the context specifier's stored state into an active
|
||||
manipulation of the runtime environment to setup and tear down the
|
||||
desired runtime context for the duration of the with statement.
|
||||
For example, a synchronisation lock's context manager acquires the
|
||||
|
@ -514,21 +521,36 @@ Standard Terminology
|
|||
with statement is that the synchronisation lock is currently held.
|
||||
|
||||
The general term "context" is unfortunately ambiguous. If necessary,
|
||||
it can be made more explicit by using the terms "context objext" for
|
||||
objects providing a __context__() method and "runtime context" for
|
||||
the runtime environment modifications made by the context manager.
|
||||
When solely discussing use of the with statement, the distinction
|
||||
between the two shouldn't matter as the context object fully
|
||||
defines the changes made to the runtime context. The distinction is
|
||||
more important when discussing the process of implementing context
|
||||
objects and context managers.
|
||||
it can be made more explicit by using the terms "context specifier"
|
||||
for objects providing a __context__() method and "runtime context"
|
||||
for the runtime environment modifications made by the context
|
||||
manager. When solely discussing use of the with statement, the
|
||||
distinction between the two shouldn't matter as the context
|
||||
specifier fully defines the changes made to the runtime context.
|
||||
The distinction is more important when discussing the process of
|
||||
implementing context specifiers and context managers.
|
||||
|
||||
Open Issues
|
||||
|
||||
1. As noted earlier, the standard terminology section has not yet
|
||||
met with consensus on python-dev. It will be refined throughout
|
||||
the Python 2.5 release cycle based on user feedback on the
|
||||
usability of the documentation.
|
||||
1. After this PEP was originally approved, a subsequent discussion
|
||||
on python-dev [4] settled on the term "context manager" for
|
||||
objects which provide __enter__ and __exit__ methods, and
|
||||
"context management protocol" for the protocol itself. With the
|
||||
addition of the __context__ method to the protocol, the natural
|
||||
adjustment is to call all objects which provide a __context__
|
||||
method "context managers", and the objects with __enter__ and
|
||||
__exit__ methods "contexts" (or "manageable contexts" in
|
||||
situations where the general term "context" would be ambiguous).
|
||||
|
||||
As noted above, the Python 2.5 release cycle revealed problems
|
||||
with the previously agreed terminology. The updated standard
|
||||
terminology section has not yet met with consensus on
|
||||
python-dev. It will be refined throughout the Python 2.5 release
|
||||
cycle based on user feedback on the usability of the
|
||||
documentation.
|
||||
The first change made as a result of the current discussion is
|
||||
replacement of the term "context object" with
|
||||
"context specifier".
|
||||
|
||||
2. The original resolution was for the decorator to make a context
|
||||
manager from a generator to be a builtin called "contextmanager".
|
||||
|
@ -595,16 +617,8 @@ Resolved Issues
|
|||
and for uninitialized objects (and for a variety of
|
||||
miscellaneous conditions)."
|
||||
|
||||
3. After this PEP was originally approved, a subsequent discussion
|
||||
on python-dev [4] settled on the term "context manager" for
|
||||
objects which provide __enter__ and __exit__ methods, and
|
||||
"context management protocol" for the protocol itself. With the
|
||||
addition of the __context__ method to the protocol, the natural
|
||||
adjustment is to call all objects which provide a __context__
|
||||
method "context managers", and the objects with __enter__ and
|
||||
__exit__ methods "contexts" (or "manageable contexts" in
|
||||
situations where the general term "context" would be ambiguous).
|
||||
This is now documented in the "Standard Terminology" section.
|
||||
3. See item 1 in open issues :)
|
||||
|
||||
|
||||
4. The originally approved version of this PEP did not include a
|
||||
__context__ method - the method was only added to the PEP after
|
||||
|
@ -640,7 +654,7 @@ Resolved Issues
|
|||
works without having to first understand the mechanics of
|
||||
how generator context managers are implemented.
|
||||
|
||||
6. See point 2 in open issues :)
|
||||
6. See item 2 in open issues :)
|
||||
|
||||
7. A generator function used to implement a __context__ method will
|
||||
need to be decorated with the contextmanager decorator in order
|
||||
|
|
Loading…
Reference in New Issue