[Python-Dev] PEP 340: Deterministic Finalisation (new PEP draft, either a competitor or update to PEP 340)

Nick Coghlan ncoghlan at gmail.com
Sun May 8 13:20:44 CEST 2005


Ron Adam wrote:
> Question:  Is the 'for' in your case iterating over a sequence? or is it 
> testing for an assignment to determine if it should continue?

Iterating over a sequence. If it's single-pass (and always single pass), you 
should use a user defined statement instead.

> The difference is slight I admit, and both views can be said to be true 
> for 'for' loops iterating over lists also.  But maybe looking at it as a 
> truth test of getting something instead of an iteration over a sequence 
> would fit better?  When a variable to assign is not supplied then the 
> test would be of a private continue-stop variable in the iterator or a 
> StopIteration exception.

No, that's the use case for user defined statements - if __enter__ raises 
TerminateBlock, then the body of the statement is not executed. What the 
for-loop part of the redrafted PEP is about is whether or not there should be an 
easy way to say "iterate over this iterator, and finalise it afterwards, 
regardless of how the iteration is ended", rather than having to use a 
try/finally block or a user defined statement for that purpose.

I think I need to reorder those two sections - introduce user-defined statements 
first, then consider whether or not to add direct finalisation support to for loops.

> If the keyword chosen is completely different from 'for' or 'while', 
> then it doesn't need a 'del' or 'finally' as that can be part of the new 
> definition of whatever keyword is chosen.

That's the technique suggested for the single-pass user defined statements. 
However, a 'for loop with finalisation' is *still fundamentally an iterative 
loop*, and the syntax should reflect that.

> So you might consider 'do', Guido responded with the following the other 
> day:
[snip quote from Guido]
> So it's not been ruled out, or followed though with, as far as I know. 
> And I think it will work for both looping and non looping situations.

The same keyword cannot be used for the looping vs non-looping construct, 
because of the effect on the semantics of break and continue statements.

The non-looping construct is the more fundamental of the two, since it can 
replace any current try/except/else/finally boilerplate, without any concern 
over whether or not the contained code using break or continue statements. A 
looping construct alters the meanings of those statements.

>>The last option is to leave finalisation out of the 'for' loop syntax, and 
>>introduce a user defined statement to handle the finalisation:
> 
> Yes, leaving it out of 'for' loop syntax is good.
> 
> I don't have an opinion on user defined statements yet.  But I think 
> they would be somewhat slower than a built in block that does the same 
> thing.

What do you mean by 'built in block'? The user defined statements of the PEP 
redraft are simply a non-looping version of PEP 340's anonymous block statements.

> Oops, meant that to say 'for-else' above ...
> 
> The 'else' is new isn't it?  I was thinking that putting a try-except 
> around the loop does the same thing as the else.  Unless I misunderstand 
> it's use.

No, the else clause on loops is a little known part of present day Python - it 
executes whenever the loop terminates naturally (i.e. not via a break statement).

The only thing PEP 340 adds to for loops is the semantics to handle an argument 
to continue statements - it adds nothing to do with finalisation. My PEP 
redraft, on the other hand, suggests the introduction of a 'for loop with 
finalisation' that works fairly similarly to PEP 340's anonymous block statements.

>>The PEP redraft already proposes a non-looping version as a new statement. 
>>However, since generators are likely to start using the new non-looping 
>>statement, it's important to be able to ensure timely finalisation of normal 
>>iterators as well. 
> 
> 
> Huh?  I thought a normal iterator or generator doesn't need 
> finalization?  If it does, then it's not normal.  Has a word been coined 
> for iterators with try-finally's in them yet?

An example was posted that looked like this:

   def all_lines(filenames):
       for name in filenames:
           stmt opening(name) as f:
               for line in f:
                   yield line

This is clearly intended for use as an iterator - it returns a bunch of lines. 
However, if the iterator is not finalised promptly, then the file that provided 
the last line may be left open indefinitely.

By making such an iterator easy to write, it behooves the PEP to make it easy to 
use correctly. This need *can* be met by the 'consuming' user defined statement 
I posted earlier, but a more elegant solution is to be able to iterate over this 
generator normally, while also being able to ask Python to ensure the generator 
is finalised at the end of the iteration.

Regards,
Nick.

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


More information about the Python-Dev mailing list