[Python-checkins] python/nondist/peps pep-0340.txt,1.15,1.16

gvanrossum@users.sourceforge.net gvanrossum at users.sourceforge.net
Tue May 3 18:32:27 CEST 2005


Update of /cvsroot/python/python/nondist/peps
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16785
Modified Files:
	pep-0340.txt 
Log Message:
Solidify loose ends.
Index: pep-0340.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0340.txt,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- pep-0340.txt	2 May 2005 23:35:52 -0000	1.15
+++ pep-0340.txt	3 May 2005 16:32:24 -0000	1.16
@@ -22,10 +22,6 @@
 (Reliable Acquisition/Release Pairs), and PEP 325
 (Resource-Release Support for Generators).
 
- This proposal is just a strawman; we've had a heated debate about
- this on python-dev recently [1], and I figured it would be time to
- write up a precise spec in PEP form.
-
 Motivation and Summary
 
 (Thanks to Shane Hathaway -- Hi Shane!)
@@ -70,7 +66,7 @@
 
 Use Cases
 
- TBD. For now, see the Examples section near the end.
+ See the Examples section near the end.
 
 Specification: the __next__() Method
 
@@ -159,14 +155,15 @@
 This is also the case in the body of the block-statement proposed
 below.
 
+ EXPR2 may contain commas; "continue 1, 2, 3" is equivalent to
+ "continue (1, 2, 3)".
+
 Specification: the Anonymous Block Statement
 
 A new statement is proposed with the syntax
 
 block EXPR1 as VAR1:
 BLOCK1
- else:
- BLOCK2
 
 Here, 'block' and 'as' are new keywords; EXPR1 is an arbitrary
 expression (but not an expression-list) and VAR1 is an arbitrary
@@ -268,14 +265,14 @@
 the limitations of all finalization semantics) that the block will
 be resumed eventually.
 
- I haven't decided yet whether the block-statement should also
- allow an optional else-clause, like the for-loop, but I'm leaning
- against it. I think it would be confusing, and emphasize the
+ Unlike the for-loop, the block-statement does not have an
+ else-clause. I think it would be confusing, and emphasize the
 "loopiness" of the block-statement, while I want to emphasize its
 *difference* from a for-loop. In addition, there are several
- possible semantics for an else-clause.
+ possible semantics for an else-clause, and only a very weak use
+ case.
 
-Specification: Generator Exception Handling
+Specification: Generator Exit Handling
 
 Generators will implement the new __next__() method API, as well
 as the old argument-less next() method which becomes an alias for
@@ -330,11 +327,10 @@
 When __next__() is called with an argument that is not None, the
 yield-expression that it resumes will return the value attribute
 of the argument. If it resumes a yield-statement, the value is
- ignored (or should this be considered an error?). When the
- *initial* call to __next__() receives an argument that is not
- None, the generator's execution is started normally; the
- argument's value attribute is ignored (or should this be
- considered an error?). When __next__() is called without an
+ ignored (this is similar to ignoring the value returned by a
+ function call). When the *initial* call to __next__() receives an
+ argument that is not None, TypeError is raised; this is likely
+ caused by some logic error. When __next__() is called without an
 argument or with None as argument, and a yield-expression is
 resumed, the yield-expression returns None.
 
@@ -360,22 +356,20 @@
 cases work differently; in Python, you cannot save the block for
 later use, and you cannot test whether there is a block or not.
 
-Loose Ends
-
- These are things that need to be resolved before accepting the
- PEP.
+Alternatives Considered
 
- - Fill in the remaining TBD sections.
+ - Many alternatives have been proposed for 'block', including '@'
+ and no keyword at all. I haven't seen a proposal for another
+ keyword that I like better than 'block' yet, and not using a
+ keyword at all makes many folks (including me) uncomfortable.
 
- - Address Phillip Eby's proposal to have the block-statement use
+ - Phillip Eby has proposed to have the block-statement use
 an entirely different API than the for-loop, to differentiate
- between the two (a generator would have to be wrapped in a
- decorator to make it support the block API).
-
- - Decide on the keyword ('block', 'with', '@', nothing, or
- something else?).
-
- - Whether a block-statement should allow an else-clause.
+ between the two. A generator would have to be wrapped in a
+ decorator to make it support the block API. IMO this adds more
+ complexity with very little benefit; and we can't relly deny
+ that the block-statement is conceptually a loop -- it supports
+ break and continue, after all.
 
 Comparison to Thunks
 
@@ -418,7 +412,7 @@
 and I'd be bummed if I couldn't write this as:
 
 def findSomething(self, key, default=None):
- block synchronized(self.lock):
+ block locking(self.lock):
 for item in self.elements:
 if item.matches(key):
 return item
@@ -427,7 +421,7 @@
 This particular example can be rewritten using a break:
 
 def findSomething(self, key, default=None):
- block synchronized(self.lock):
+ block locking(self.lock):
 for item in self.elements:
 if item.matches(key):
 break
@@ -478,16 +472,17 @@
 
 However, the use cases for multiple blocks seem elusive.
 
-Alternatives Considered
-
- TBD.
+ (Proposals have since been made to change the implementation of
+ thunks to remove most of these objections, but the resulting
+ semantics are fairly complex to explain and to implement, so IMO
+ that defeats the purpose of using thunks in the first place.)
 
 Examples
 
 1. A template for ensuring that a lock, acquired at the start of a
 block, is released when the block is left:
 
- def synchronized(lock):
+ def locking(lock):
 lock.acquire()
 try:
 yield
@@ -496,7 +491,7 @@
 
 Used as follows:
 
- block synchronized(myLock):
+ block locking(myLock):
 # Code here executes with myLock held. The lock is
 # guaranteed to be released when the block is left (even
 # if by an uncaught exception).
@@ -549,18 +544,40 @@
 
 5. It is possible to nest blocks and combine templates:
 
- def synchronized_opening(lock, filename, mode="r"):
- block synchronized(lock):
+ def locking_opening(lock, filename, mode="r"):
+ block locking(lock):
 block opening(filename) as f:
 yield f
 
 Used as follows:
 
- block synchronized_opening("/etc/passwd", myLock) as f:
+ block locking_opening("/etc/passwd", myLock) as f:
 for line in f:
 print line.rstrip()
 
- 6. Coroutine example TBD.
+ 6. It is possible to write a regular iterator with the
+ semantics of example 1:
+
+	class locking:
+	 def __init__(self, lock):
+	 self.lock = lock
+	 self.state = 0
+	 def __next__(self, arg=None):
+	 # ignores arg
+	 if self.state:
+		 assert self.state == 1
+		 self.lock.release()
+		 self.state += 1
+		 raise StopIteration
+	 else:
+		 self.lock.acquire()
+		 self.state += 1
+		 return None
+	 def __exit__(self, type, value=None, traceback=None):
+	 assert self.state in (0, 1, 2)
+	 if self.state == 1:
+		 self.lock.release()
+	 raise type, value, traceback
 
 Acknowledgements
 


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /