Skip to content

Commit da5b701

Browse files
committed
Get rid of __context__, per the latest changes to PEP 343 and python-dev
discussion. There are two places of documentation that still mention __context__: Doc/lib/libstdtypes.tex -- I wasn't quite sure how to rewrite that without spending a whole lot of time thinking about it; and whatsnew, which Andrew usually likes to change himself.
1 parent 8f6cbe1 commit da5b701

15 files changed

Lines changed: 27 additions & 202 deletions

File tree

Doc/lib/libcontextlib.tex

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -54,34 +54,6 @@ \section{\module{contextlib} ---
5454
reraise that exception. Otherwise the \keyword{with} statement will
5555
treat the exception as having been handled, and resume execution with
5656
the statement immediately following the \keyword{with} statement.
57-
58-
Note that you can use \code{@contextfactory} to define a context
59-
manager's \method{__context__} method. This is usually more
60-
convenient than creating another class just to serve as a context
61-
object. For example:
62-
63-
\begin{verbatim}
64-
from __future__ import with_statement
65-
from contextlib import contextfactory
66-
67-
class Tag:
68-
def __init__(self, name):
69-
self.name = name
70-
71-
@contextfactory
72-
def __context__(self):
73-
print "<%s>" % self.name
74-
yield self
75-
print "</%s>" % self.name
76-
77-
h1 = Tag("h1")
78-
79-
>>> with h1 as me:
80-
... print "hello from", me
81-
<h1>
82-
hello from <__main__.Tag instance at 0x402ce8ec>
83-
</h1>
84-
\end{verbatim}
8557
\end{funcdesc}
8658

8759
\begin{funcdesc}{nested}{ctx1\optional{, ctx2\optional{, ...}}}
@@ -147,25 +119,6 @@ \section{\module{contextlib} ---
147119
without needing to explicitly close \code{page}. Even if an error
148120
occurs, \code{page.close()} will be called when the \keyword{with}
149121
block is exited.
150-
151-
Context managers with a close method can use this context factory
152-
to easily implement their own \method{__context__()} method.
153-
\begin{verbatim}
154-
from __future__ import with_statement
155-
from contextlib import closing
156-
157-
class MyClass:
158-
def close(self):
159-
print "Closing", self
160-
def __context__(self):
161-
return closing(self)
162-
163-
>>> with MyClass() as x:
164-
... print "Hello from", x
165-
...
166-
Hello from <__main__.MyClass instance at 0xb7df02ec>
167-
Closing <__main__.MyClass instance at 0xb7df02ec>
168-
\end{verbatim}
169122
\end{funcdesc}
170123

171124
\begin{seealso}

Doc/ref/ref3.tex

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2138,22 +2138,6 @@ \subsection{With Statement Contexts and Context Managers\label{context-managers}
21382138
see ``\ulink{Context Types}{../lib/typecontext.html}'' in the
21392139
\citetitle[../lib/lib.html]{Python Library Reference}.
21402140

2141-
\begin{methoddesc}[context manager]{__context__}{self}
2142-
Invoked when the object is used as the context expression of a
2143-
\keyword{with} statement. The returned object must implement
2144-
\method{__enter__()} and \method{__exit__()} methods.
2145-
2146-
Context managers written in Python can also implement this method
2147-
using a generator function decorated with the
2148-
\function{contextlib.contextfactory} decorator, as this can be simpler
2149-
than writing individual \method{__enter__()} and \method{__exit__()}
2150-
methods on a separate object when the state to be managed is complex.
2151-
2152-
\keyword{with} statement context objects also need to implement this
2153-
method; they are required to return themselves (that is, this method
2154-
will simply return \var{self}).
2155-
\end{methoddesc}
2156-
21572141
\begin{methoddesc}[with statement context]{__enter__}{self}
21582142
Enter the runtime context related to this object. The \keyword{with}
21592143
statement will bind this method's return value to the target(s)

Doc/ref/ref7.tex

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -322,21 +322,18 @@ \section{The \keyword{with} statement\label{with}}
322322

323323
\begin{productionlist}
324324
\production{with_stmt}
325-
{"with" \token{expression} ["as" target_list] ":" \token{suite}}
325+
{"with" \token{expression} ["as" target] ":" \token{suite}}
326326
\end{productionlist}
327327

328328
The execution of the \keyword{with} statement proceeds as follows:
329329

330330
\begin{enumerate}
331331

332-
\item The context expression is evaluated, to obtain a context manager.
332+
\item The context expression is evaluated to obtain a context manager.
333333

334-
\item The context manger's \method{__context__()} method is
335-
invoked to obtain a \keyword{with} statement context object.
334+
\item The context manager's \method{__enter__()} method is invoked.
336335

337-
\item The context object's \method{__enter__()} method is invoked.
338-
339-
\item If a target list was included in the \keyword{with}
336+
\item If a target was included in the \keyword{with}
340337
statement, the return value from \method{__enter__()} is assigned to it.
341338

342339
\note{The \keyword{with} statement guarantees that if the
@@ -347,7 +344,7 @@ \section{The \keyword{with} statement\label{with}}
347344

348345
\item The suite is executed.
349346

350-
\item The context object's \method{__exit__()} method is invoked. If
347+
\item The context manager's \method{__exit__()} method is invoked. If
351348
an exception caused the suite to be exited, its type, value, and
352349
traceback are passed as arguments to \method{__exit__()}. Otherwise,
353350
three \constant{None} arguments are supplied.

Lib/calendar.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -484,9 +484,6 @@ class TimeEncoding:
484484
def __init__(self, locale):
485485
self.locale = locale
486486

487-
def __context__(self):
488-
return self
489-
490487
def __enter__(self):
491488
self.oldlocale = locale.setlocale(locale.LC_TIME, self.locale)
492489
return locale.getlocale(locale.LC_TIME)[1]

Lib/compiler/pycodegen.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -833,8 +833,6 @@ def visitWith(self, node):
833833
self.__with_count += 1
834834
self.set_lineno(node)
835835
self.visit(node.expr)
836-
self.emit('LOAD_ATTR', '__context__')
837-
self.emit('CALL_FUNCTION', 0)
838836
self.emit('DUP_TOP')
839837
self.emit('LOAD_ATTR', '__exit__')
840838
self._implicitNameOp('STORE', exitvar)

Lib/contextlib.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ class GeneratorContext(object):
1010
def __init__(self, gen):
1111
self.gen = gen
1212

13-
def __context__(self):
14-
return self
15-
1613
def __enter__(self):
1714
try:
1815
return self.gen.next()
@@ -88,7 +85,7 @@ def helper(*args, **kwds):
8885

8986

9087
@contextfactory
91-
def nested(*contexts):
88+
def nested(*managers):
9289
"""Support multiple context managers in a single with-statement.
9390
9491
Code like this:
@@ -109,8 +106,7 @@ def nested(*contexts):
109106
exc = (None, None, None)
110107
try:
111108
try:
112-
for context in contexts:
113-
mgr = context.__context__()
109+
for mgr in managers:
114110
exit = mgr.__exit__
115111
enter = mgr.__enter__
116112
vars.append(enter())
@@ -152,8 +148,6 @@ class closing(object):
152148
"""
153149
def __init__(self, thing):
154150
self.thing = thing
155-
def __context__(self):
156-
return self
157151
def __enter__(self):
158152
return self.thing
159153
def __exit__(self, *exc_info):

Lib/decimal.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2248,7 +2248,7 @@ def __repr__(self):
22482248
s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
22492249
return ', '.join(s) + ')'
22502250

2251-
def __context__(self):
2251+
def context_manager(self):
22522252
return WithStatementContext(self.copy())
22532253

22542254
def clear_flags(self):

Lib/dummy_thread.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,6 @@ def acquire(self, waitflag=None):
118118
def __exit__(self, typ, val, tb):
119119
self.release()
120120

121-
def __context__(self):
122-
return self
123-
124121
def release(self):
125122
"""Release the dummy lock."""
126123
# XXX Perhaps shouldn't actually bother to test? Could lead

Lib/test/test_contextlib.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def test_contextfactory_no_reraise(self):
5151
@contextfactory
5252
def whee():
5353
yield
54-
ctx = whee().__context__()
54+
ctx = whee()
5555
ctx.__enter__()
5656
# Calling __exit__ should not result in an exception
5757
self.failIf(ctx.__exit__(TypeError, TypeError("foo"), None))
@@ -63,7 +63,7 @@ def whoo():
6363
yield
6464
except:
6565
yield
66-
ctx = whoo().__context__()
66+
ctx = whoo()
6767
ctx.__enter__()
6868
self.assertRaises(
6969
RuntimeError, ctx.__exit__, TypeError, TypeError("foo"), None
@@ -152,8 +152,6 @@ def test_nested_right_exception(self):
152152
def a():
153153
yield 1
154154
class b(object):
155-
def __context__(self):
156-
return self
157155
def __enter__(self):
158156
return 2
159157
def __exit__(self, *exc_info):
@@ -341,12 +339,12 @@ def testBasic(self):
341339
orig_context = ctx.copy()
342340
try:
343341
ctx.prec = save_prec = decimal.ExtendedContext.prec + 5
344-
with decimal.ExtendedContext:
342+
with decimal.ExtendedContext.context_manager():
345343
self.assertEqual(decimal.getcontext().prec,
346344
decimal.ExtendedContext.prec)
347345
self.assertEqual(decimal.getcontext().prec, save_prec)
348346
try:
349-
with decimal.ExtendedContext:
347+
with decimal.ExtendedContext.context_manager():
350348
self.assertEqual(decimal.getcontext().prec,
351349
decimal.ExtendedContext.prec)
352350
1/0

0 commit comments

Comments
 (0)