[Python-checkins] python/nondist/peps pep-0343.txt,1.25,1.26
pje@users.sourceforge.net
pje at users.sourceforge.net
Sun Jun 26 04:21:24 CEST 2005
Update of /cvsroot/python/python/nondist/peps
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19319
Modified Files:
pep-0343.txt
Log Message:
PEP 343: Remove functionality now covered under PEP 342.
Index: pep-0343.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0343.txt,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- pep-0343.txt 17 Jun 2005 21:58:59 -0000 1.25
+++ pep-0343.txt 26 Jun 2005 02:21:21 -0000 1.26
@@ -26,19 +26,9 @@
If this PEP is approved, the following PEPs will be rejected due
to overlap:
- - PEP 288, Generators Attributes and Exceptions. The current PEP
- covers its second half, generator exceptions (in fact the
- throw() method name was taken from this PEP). I'm not in favor
- of generator attributes, since they can easily be handled by
- making the generator a method or by passing a mutable argument.
-
- PEP 310, Reliable Acquisition/Release Pairs. This is the
original with-statement proposal.
- - PEP 325, Resource-Release Support for Generators. The current
- PEP covers this (in fact the close() method name was taken from
- this PEP).
-
- PEP 319, Python Synchronize/Asynchronize Block. Its use cases
can be covered by the current PEP by providing suitable
with-statement controllers: for 'synchronize' we can use the
@@ -262,91 +252,11 @@
non-local goto should be considered unexceptional for the purposes
of a database transaction roll-back decision.
-Specification: Generator Enhancements
-
- Let a generator object be the iterator produced by calling a
- generator function. Below, 'g' always refers to a generator
- object.
-
- New syntax: yield allowed inside try-finally
-
- The syntax for generator functions is extended to allow a
- yield-statement inside a try-finally statement.
-
- New generator method: throw(type, value=None, traceback=None)
-
- g.throw(type, value, traceback) causes the specified exception to
- be thrown at the point where the generator g is currently
- suspended (i.e. at a yield-statement, or at the start of its
- function body if next() has not been called yet). If the
- generator catches the exception and yields another value, that is
- the return value of g.throw(). If it doesn't catch the exception,
- the throw() appears to raise the same exception passed it (it
- "falls through"). If the generator raises another exception (this
- includes the StopIteration produced when it returns) that
- exception is raised by the throw() call. In summary, throw()
- behaves like next() except it raises an exception at the
- suspension point. If the generator is already in the closed
- state, throw() just raises the exception it was passed without
- executing any of the generator's code.
-
- The effect of raising the exception is exactly as if the
- statement:
-
- raise type, value, traceback
-
- was executed at the suspension point. The type argument should
- not be None.
-
- New standard exception: GeneratorExit
-
- A new standard exception is defined, GeneratorExit, inheriting
- from Exception. A generator should handle this by re-raising it
- or by raising StopIteration.
-
- New generator method: close()
-
- g.close() is defined by the following pseudo-code:
-
- def close(self):
- try:
- self.throw(GeneratorExit, GeneratorExit(), None)
- except (GeneratorExit, StopIteration):
- pass
- else:
- raise RuntimeError("generator ignored GeneratorExit")
- # Other exceptions are not caught
-
- New generator method: __del__()
-
- g.__del__() is an alias for g.close(). This will be called when
- the generator object is garbage-collected (in CPython, this is
- when its reference count goes to zero). If close() raises an
- exception, a traceback for the exception is printed to sys.stderr
- and further ignored; it is not propagated back to the place that
- triggered the garbage collection. This is consistent with the
- handling of exceptions in __del__() methods on class instances.
-
- If the generator object participates in a cycle, g.__del__() may
- not be called. This is the behavior of CPython's current garbage
- collector. The reason for the restriction is that the GC code
- needs to "break" a cycle at an arbitrary point in order to collect
- it, and from then on no Python code should be allowed to see the
- objects that formed the cycle, as they may be in an invalid state.
- Objects "hanging off" a cycle are not subject to this restriction.
- Note that it is unlikely to see a generator object participate in
- a cycle in practice. However, storing a generator object in a
- global variable creates a cycle via the generator frame's
- f_globals pointer. Another way to create a cycle would be to
- store a reference to the generator object in a data structure that
- is passed to the generator as an argument. Neither of these cases
- are very likely given the typical pattern of generator use.
-
Generator Decorator
- It is possible to write a decorator that makes it possible to use
- a generator that yields exactly once to control a with-statement.
- Here's a sketch of such a decorator:
+ If PEP 342 is accepted, it will be possible to write a decorator
+ that makes it possible to use a generator that yields exactly once
+ to control a with-statement. Here's a sketch of such a decorator:
class Wrapper(object):
@@ -431,28 +341,9 @@
them here, with my preferred resolution and its motivation. The
PEP as currently written reflects this preferred resolution.
- 1. What exception should be raised by close() when the generator
- yields another value as a response to the GeneratorExit
- exception?
-
- I originally chose TypeError because it represents gross
- misbehavior of the generator function, which should be fixed by
- changing the code. But the with_template decorator class uses
- RuntimeError for similar offenses. Arguably they should all
- use the same exception. I'd rather not introduce a new
- exception class just for this purpose, since it's not an
- exception that I want people to catch: I want it to turn into a
- traceback which is seen by the programmer who then fixes the
- code. So now I believe they should both raise RuntimeError.
- There are some precedents for that: it's raised by the core
- Python code in situations where endless recursion is detected,
- and for uninitialized objects (and for a variety of
- miscellaneous conditions).
-
- 2. Both the generator close() method and the __exit__() method of
- the with_template decorator class catch StopIteration and
- consider it equivalent to re-raising the exception passed to
- throw(). Is allowing StopIteration right here?
+ 1. The __exit__() method of the with_template decorator class catches
+ StopIteration and considers it equivalent to re-raising the exception
+ passed to throw(). Is allowing StopIteration right here?
This is so that a generator doing cleanup depending on the
exception thrown (like the transactional() example below) can
More information about the Python-checkins
mailing list