[Python-Dev] [OT] Re: PEP 340 -- Clayton's keyword?
Just a little offtopic note to Jeff Bone: Jeff, every time I send a message to Python-Dev, your Mail.app 2.0 sends me a nasty auto-reply that I can't quote in public. Please stop. Since I can't seem to reach you by email, I'm trying to reach you through this mailing list. The note refers to something about Shantar; maybe that will help you figure out what's wrong. Shane ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Adding DBL_MANTISSA and such to Python
Edward C. Jones wrote: The documentation should discuss portability. This is the critical issue here. Discussing portability is not enough; these features really ought to be either available on a majority of the installations, or not available at all. In particular, they would need to be available on Windows. I haven't check whether VC 7.1 provides them, and if it doesn't, somebody would have to provide a direct implementation. I'd say contributions are welcome. Regards, Martin ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340: Breaking out.
On Thu, 5 May 2005, Delaney, Timothy C (Timothy) wrote: Aahz wrote: My standard workaround is using exceptions, but I'm not sure how that interacts with a block: try: for name in filenames: with opened(name) as f: if f.read(2) == 0xFEB0: raise Found except Found: pass For any sane block iterator, it will work as expected. However, an evil block iterator could suppress the `Found` exception. I was thinking about more use cases for the block statement, and one of the ideas was an exception-logging block: def logged_exceptions(file): try: yield except Exception, value: file.write(repr(value) + '\n') block logged_exceptions(file): do stuff do stuff do stuff ...but then i wasn't sure whether this was supposed to be possible in the proposed scheme. Currently, generators do not catch exceptions raised in the code that they yield values to, because the target of the yield is in a higher stack frame. This makes sense from a language design perspective, since there is no try...finally construct lexically wrapping the thing that raises the exception. In current Python, for example, this says 'caught outside generator': def spam_generator(): try: yield 'spam' except ValueError, value: print 'caught inside generator' try: g = spam_generator() i = g.next() raise ValueError(5) except ValueError, value: print 'caught outside generator' But now i'm confused. Tim's words above seem to suggest that the interior generator could actually catch exceptions raised outside, by whatever is on the other end of the yield. So, could a block statement really catch that exception inside? I think it might be too confusing if it were possible. -- ?!ng ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Adding DBL_MANTISSA and such to Python
Edward C. Jones [EMAIL PROTECTED] wrote: 3. Add full tostring and fromstring capabilities for Python numeric types. tostring(x) would return a string containing the binary representation of x. For example, if x is a Python float, tostring(x) would have eight characters. fromstring(s, atype) does the reserve, so fromstring(tostring(x), type(x)) == x For floats: struct.pack(d,...) struct.unpack(d,...) For 32-bit signed integers: struct.pack(l,...) struct.unpack(l,...) For 64 bit signed integers: struct.pack(Q,...) struct.unpack(Q,...) Heck, you can even get big-endian output on little-endian machines (or vv.) if you want! Or you can toss the signs on the integers, get shorts, or even chars. Python already has such functionality in the standard library, though perhaps it isn't the most aptly named (being in 'struct' rather than a 'value_packing' module...though its functionality was for packing and unpacking of c-style structs...). Alternatively, you can create an array (using similar typecodes), and use the .tostring() and .fromstring() mechanism. 4. Add some functions that process floating point types at a low level. I suggest borrowing from C (mantissa, exponent) = frexp(x) What about the sign? Here's an implementation for you that includes the sign... def frexp(f): if not isinstance(f, float): raise TypeError, Requires float argument v, = struct.unpack(Q, struct.pack(d, f)) #we ignore denormalized values, NANs, and infinities... return v63, 1 + (v(2**52-1))/(2.0**52), ((v52)2047)-1023 Is that enough? Or did you want to convert back into a float? def inv_frexp(sign, mantissa, exponent): #I don't know what this is normally called in C... v = bool(sign)*2**63 v += (abs(int(exponent+1023))2047)*2**52 v += abs(int(((mantissa-1)*2**52)))(2**52-1) f, = struct.unpack(d, struct.pack(Q, v)) return f Yeah, there's some bit work in there, and some is merely protection against foolish inputs, but it's not that bad. - Josiah ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] python-dev Summary for 2005-04-16 through 2005-04-30 [draft]
Here's April Part Two. If anyone can take their eyes of the anonymous block threads for a moment and give this a once-over, that would be great! Please send any corrections or suggestions to Tim (tlesher at gmail.com), Steve (steven.bethard at gmail.com) and/or me, rather than cluttering the list. Ta! == Summary Announcements == --- Exploding heads --- After a gentle introduction for our first summary, python-dev really let loose last fortnight; not only with the massive PEP 340 discussion, but also more spin-offs than a `popular`_ `TV`_ `series`_, and a few stand-alone threads. Nearly a week into May, and the PEP 340 talk shows no sign of abating; this is unfortunate, since Steve's head may explode if he has to write anything more about anonymous blocks. Just as well there are three of us! .. _popular: http://imdb.com/title/tt0060028/ .. _TV: http://imdb.com/title/tt0098844/ .. _series: http://imdb.com/title/tt0247082/ [TAM] --- PEP 340 --- A request for anonymous blocks by Shannon -jj Behrens launched a massive discussion about a variety of related ideas. This discussion is split into different sections for the sake of readability, but as the sections are extracted from basically the same discussion, it may be easiest to read them in the following order: 1. `Localized Namespaces`_ 2. `The Control Flow Management Problem`_ 3. `Block Decorators`_ 4. `PEP 310 Updates Requested`_ 5. `Sharing Namespaces`_ 6. `PEP 340 Proposed`_ [SJB] = Summaries = Localized Namespaces Initially, the anonymous blocks discussion focused on introducing statement-local namespaces as a replacement for lambda expressions. This would have allowed localizing function definitions to a single namespace, e.g.:: foo = property(get_foo) where: def get_foo(self): ... where get_foo is only accessible within the ``foo = ...`` assignment statement. However, this proposal seemed mainly to be motivated by a desire to avoid namespace pollution, an issue which Guido felt was not really that much of a problem. Contributing threads: - `anonymous blocks http://mail.python.org/pipermail/python-dev/2005-April/052717.html`__ [SJB] --- The Control Flow Management Problem --- Guido suggested that if new syntax were to be introduced for anonymous blocks, it should address the more important problem of being able to extract common patterns of control flow. A very typical example of such a problem, and thus one of the recurring examples in the thread, is that of a typical acquire/release pattern, e.g.:: lock.acquire() try: CODE finally: lock.release() Guido was hoping that syntactic sugar and an appropriate definition of locking() could allow such code to be written as:: locking(lock): CODE where locking() would factor out the acquire(), try/finally and release(). For such code to work properly, ``CODE`` would have to execute in the enclosing namespace, so it could not easily be converted into a def-statement. Some of the suggested solutions to this problem: - `Block Decorators`_ - `PEP 310 Updates Requested`_ - `Sharing Namespaces`_ - `PEP 340 Proposed`_ Contributing threads: - `anonymous blocks http://mail.python.org/pipermail/python-dev/2005-April/052717.html`__ [SJB] Block Decorators One of the first solutions to `The Control Flow Management Problem`_ was block decorators. Block decorators were functions that accepted a block object (also referred to in the thread as a thunk), defined a particular control flow, and inserted calls to the block object at the appropriate points in the control flow. Block objects would have been much like function objects, in that they encapsulated a sequence of statements, except that they would have had no local namespace; names would have been looked up in their enclosing function. Block decorators would have wrapped sequences of statements in much the same way as function decorators wrap functions today. Block decorators would have allowed locking() to be written as:: def locking(lock): def block_deco(block): lock.acquire() try: block() finally: lock.release() return block_deco and invoked as:: @locking(lock): CODE The implementation of block objects would have been somewhat complicated if a block object was a first class object and could be passed to other functions. This would have required all variables used in a block object to be cells (which provide slower access than normal name lookup). Additionally, first class block objects, as a type of callable, would have confused the meaning of the return statement - should the return exit the block or the enclosing function?
Re: [Python-Dev] Adding DBL_MANTISSA and such to Python
Josiah Carlson [EMAIL PROTECTED] wrote: unsigned vv For 64 bit signed integers: struct.pack(Q,...) struct.unpack(Q,...) My fingers were typing too fast (I do much work with unsigned 64 bit integers, but not much with unsigned ones). - Josiah ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Adding DBL_MANTISSA and such to Python
Edward C. Jones [EMAIL PROTECTED] writes: Recently I needed some information about the floating point numbers on my machine. So I wrote a tiny C99 program with the line printf(%a\n, DBL_EPSILON); The answer was 0x1p-52. A search of comp.lang.python shows that I was not alone. Here are some ideas. 1. Add to Python the constants in float.h and limits.h. Where? 2. Add the C99 %a format to the % operator for strings and allow it in floating point literals. Is there an implementation of this somewhere? We mostly certainly are not demanding a C99 compiler yet. 3. Add full tostring and fromstring capabilities for Python numeric types. tostring(x) would return a string containing the binary representation of x. For example, if x is a Python float, tostring(x) would have eight characters. fromstring(s, atype) does the reserve, so fromstring(tostring(x), type(x)) == x We have this already in the struct module. I have a patch that should improve the robustness of these functions on IEEE-754 platforms in the face of special values that you can review if you like: http://python.org/sf/1181301 (my not-so-recent anguished will one of you bastards please review this and/or 1180995 for me? still applies, btw) 4. Add some functions that process floating point types at a low level. I suggest borrowing from C (mantissa, exponent) = frexp(x) where mantissa is a float and exponent is an int. The mantissa can be 0.0 or 0.5 = mantissa 1.0. Also x = mamtissa * 2**exponent. If x == 0.0, the function returns (0.0, 0). (This is almost a quote from Harbison and Steele.) math.frexp(math.pi) (0.78539816339744828, 2) What am I missing? 5. Add the C99 constants and functions involving special floating point values: FP_INFINITE, FP_NAN, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, fpclassify, isfinite, isinf, isnan, isnormal, signbit, copysign, nan, nextafter, and nexttoward. There has been controversy about these in the past, but I am in favor of them. The documentation should discuss portability. If you can supply a patch to make all the compilers out there behave with respect to these functions, I'll be impressed (they seem to exist on Mac OS X 10.3, dunno if they work though :). Cheers, mwh -- If you're talking useful, I'm not your bot. -- Tim Peters, 08 Nov 2001 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Pre-PEP: Unifying try-except and try-finally
Shane Holloway (IEEE) [EMAIL PROTECTED] writes: And per the PEP, I think the explaining that:: try: A except: B else: C finally: D is *exactly* equivalent to:: try: try: A except: B else: C finally: D Resolved all the questions about control flow for me. Well, yes, that makes sense, but also raises a small and the point is...? flag in my head. Cheers, mwh -- This is the fixed point problem again; since all some implementors do is implement the compiler and libraries for compiler writing, the language becomes good at writing compilers and not much else! -- Brian Rogoff, comp.lang.functional ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340: Breaking out.
Steven Bethard wrote: Makes me wonder if we shouldn't just return to the __enter__() and __exit__() names of PEP 310[1] where for a generator __enter__() is just an alias for next(). We could even require Phillip J. Eby's blockgenerator decorator to rename next() to __enter__(), and add the appropriate __exit__() method. You must be reading my mind or something. . . Unless there is something in today's 80-odd messages to make it redundant, look for a post entitled something like Minimalist PEP 340 (aka PEP 310 redux) Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.skystorm.net ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340: Breaking out.
Alex Martelli wrote: Looking for a file with a certain magicnumber in its 1st two bytes...? for name in filenames: opening(name) as f: if f.read(2) == 0xFEB0: break This does seem to make real-life sense to me... Also consider the vast semantic differences between: locking(lock): for item in items: if can_handle(item): break for item in items: locking(lock): if can_handle(item): break Instead of simply acquiring and releasing the lock on each iteration as one might expect, moving to the latter version *also* causes every item to be checked, instead of only items up to the first one that can be handled. The break magically becomes meaningless. How does this even come close to executable pseudocode? I also think another factor is that currently, instead of doing try/finally's in loops, there is a tendency to push the try/finally into a function, then call that function inside the loop. The introduction of block statements means that a number of those inner functions are likely to be handled as block statements instead - with the above highly confusing result. Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.skystorm.net ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340 -- loose ends
Shane Holloway (IEEE) wrote: It might actually be workable in the transaction scenario, as well as others. I'm not sure if I love or hate the idea though. Given that this is officially a violation of the iterator protocol. . . (check the docs for well-behaved iterators) Another thing. In the specification of the Anonymous Block function, is there a reason that itr = EXPR1 instead of itr = iter(EXPR1)? It seems to be a dis-symmetry with the 'for' loop specification. Indeed - and a deliberate one, at least partly to discourage caching of block iterators. Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.skystorm.net ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Pre-PEP: Unifying try-except and try-finally
Michael Hudson wrote: Shane Holloway (IEEE) [EMAIL PROTECTED] writes: And per the PEP, I think the explaining that:: try: A except: B else: C finally: D is *exactly* equivalent to:: try: try: A except: B else: C finally: D Resolved all the questions about control flow for me. Well, yes, that makes sense, but also raises a small and the point is...? flag in my head. Someone writing a patch and profiling the two versions would serve to convince me :) Cheers, Nick. P.S. Well, assuming the flattened version is faster. . . -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.skystorm.net ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] PEP 340 keyword: after
I haven't followed the PEP 340 discussion in detail, but as the PEP doesn't list keywords that have been considered and rejected, I'd like to propose my own: use after instead of block: after opening(/etc/passwd) as f: for line in f: print line.rstrip() after locking(myLock): # code that needs to hold the lock Regards, Martin ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340: Breaking out.
Ronald Oussoren wrote: What's bothering me about the proposed semantics is that block statement behaves like a loop while most use cases do no looping whatsoever. Furthermore the it doesn't feel like loop either. In all three examples on this page I'd assume that the break would break out of the for loop. I'm bothered the same way. IMHO control constructs should be very clear. No implicit looping, conditionals etc. Especially since the main reason to have this whole discussion is about resource management. The main pattern of use I have in mind is: resource = grab/allocate/open/whatever(...) try: do something possibly with the resource except ...: ... finally: ... resource.release/deallocate/close/whatever() This is linear. No looping whatsoever. And easily translated to a simple language construct and a protocol: class resource(object): def __init__(self,...): # store resource parameters def __acquire__(self): # whatever it takes to grab the resource def __release__(self): # free the resource res = resource(...) acquire res: do something possibly with the resource except ...: ... finally: ... The resource is automagically released at the end of the 'acquire' block (keyword up for other proposals :-) An alternative syntax could also be allowed: acquire resource(...) as res: ...etc... Then 'res' would be undefined after the 'acquire' block. --eric ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] PEP 340: Non-looping version (aka PEP 310 redux)
The discussion on the meaning of break when nesting a PEP 340 block statement inside a for loop has given me some real reasons to prefer PEP 310's single pass semantics for user defined statements (more on that at the end). The suggestion below is my latest attempt at combining the ideas of the two PEP's. For the keyword, I've used the abbreviation 'stmt' (for statement). I find it reads pretty well, and the fact that it *isn't* a real word makes it easier for me to track to the next item on the line to find out the actual statement name (I think this might be similar to the effect of 'def' not being a complete word making it easier for me to pick out the function name). I consequently use 'user statement' or 'user defined statement' to describe what PEP 340 calls anonymous block statements. I'm still fine with the concept of not using a keyword at all, though. Cheers, Nick. == User Defined Statement Usage Syntax == stmt EXPR1 [as VAR1]: BLOCK1 == User Defined Statement Semantics == the_stmt = EXPR1 terminated = False try: stmt_enter = the_stmt.__enter__ stmt_exit = the_stmt.__exit__ except AttributeError: raise TypeError(User statement required) try: VAR1 = stmt_enter() # Omit 'VAR1 =' if no 'as' clause except TerminateBlock: pass # Block is not entered at all in this case # If an else clause were to be permitted, the # associated block would be executed here else: try: try: BLOCK1 except: exc = sys.exc_info() terminated = True try: stmt_exit(*exc) except TerminateBlock: pass finally: if not terminated: try: stmt_exit(TerminateBlock) except TerminateBlock: pass Key points: * The supplied expression must have both __enter__ and __exit__ methods. * The result of the __enter__ method is assigned to VAR1 if VAR1 is given. * BLOCK1 is not executed if __enter__ raises an exception * A new exception, TerminateBlock, is used to signal statement completion * The __exit__ method is called with the exception tuple if an exception occurs * Otherwise it is called with TerminateBlock as the argument * The __exit__ method can suppress an exception by converting it to TerminateBlock or by returning without reraising the exception * return, break, continue and raise StopIteration are all OK inside BLOCK1. They affect the surrounding scope, and are in no way tampered with by the user defined statement machinery (some user defined statements may choose to suppress the raising of StopIteration, but the basic machinery doesn't do that) * Decouples user defined statements from yield expressions, the enhanced continue statement and generator finalisation. == New Builtin: statement == def statement(factory): try: factory.__enter__ factory.__exit__ # Supplied factory is already a user statement factory return factory except AttributeError: # Assume supplied factory is an iterable factory # Use it to create a user statement factory class stmt_factory(object): def __init__(*args, **kwds) self = args[0] self.itr = iter(factory(*args[1:], **kwds)) def __enter__(self): try: return self.itr.next() except StopIteration: raise TerminateBlock def __exit__(self, *exc_info): try: stmt_exit = self.itr.__exit__ except AttributeError: try: self.itr.next() except StopIteration: pass raise *exc_info # i.e. re-raise the supplied exception else: try: stmt_exit(*exc_info) except StopIteration: raise TerminateBlock Key points: * The supplied factory is returned unchanged if it supports the statement API (such as a class with both __enter__ and __exit__ methods) * An iterable factory (such as a generator, or class with an __iter__ method) is converted to a block statement factory * Either way, the result is a callable whose results can be used as EXPR1 in a user defined statement. * For statements constructed from iterators, the iterator's next() method is called once when entering the statement, and the result is assigned to VAR1 * If the iterator has an __exit__ method, it is invoked when the statement is exited. The __exit__ method is passed the exception information (which may indicate that no exception occurred). * If the iterator does not have an __exit__ method, it's
Re: [Python-Dev] PEP 340: Breaking out.
On 5/5/05, Nick Coghlan [EMAIL PROTECTED] wrote: Steven Bethard wrote: Makes me wonder if we shouldn't just return to the __enter__() and __exit__() names of PEP 310[1] where for a generator __enter__() is just an alias for next(). We could even require Phillip J. Eby's blockgenerator decorator to rename next() to __enter__(), and add the appropriate __exit__() method. You must be reading my mind or something. . . Unless there is something in today's 80-odd messages to make it redundant, look for a post entitled something like Minimalist PEP 340 (aka PEP 310 redux) Yeah, I should have linked to that discussion [1]. I wonder if it would be possible to update PEP 310 with your ideas, or perhaps start a new PEP? I'd like to see a competitor for PEP 340 that addresses some of the issues that came up, e.g. that the block-statement doesn't look like a loop, so break and continue might look like they break out of an enclosing loop. It might also be a good place to mirror Guido's PEP 340 examples with PEP 310-style examples -- I know the first attempts at writing some of them weren't as clean as the later attempts, so it would be nice to have somewhere to look for the current version of everything. STeVe [1]http://mail.python.org/pipermail/python-dev/2005-April/053039.html -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Pre-PEP: Unifying try-except and try-finally
Eric Nieuwland wrote: Wouldn't it be easier to change it to: try_stmt: ('try' ':' suite (except_clause ':' suite)* ['else' ':' suite] ['finally' ':' suite] ) ? What does a try statement with neither an except clause nor a finally clause mean? Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.skystorm.net ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] problems with memory management
Hi All, I do hava a problem with python and it is that it raise an outofmemory (i comment lines in Py.java to avoid system.exit, to debug), i try to debug this issue with jprobe and realize that i get the exception even although the java heap is not in the limit, i book 64- 256M and the java heap waslessthan60 M. The program is a command line that receive a line that python parse an call some java classes ti execute the appropiate command, any idea? Thansk, ==Carlos García Phone : +34 91 714 8796Lucent Technologies e-mail : [EMAIL PROTECTED]Avenida de Bruselas , 8 - 28108 Alcobendas (Madrid)== ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340 keyword: Extended while syntax
I expect there's an obvious reason why this hasn't been suggested already that I'm not currently thinking of, but here it is anyway. :-) How about an *extended while* syntax as a block keyword alternative? Reasoning: The block statement resembles a while block in some ways in that it is a conditional block that may be executed only once, or possibly not at all (or many times). And the word while is also descriptive of how a block is used. while VAR1 from EXPR1(): BLOCK This will require a new keyword/operator 'from' to use in a 'from' expression: VAR1 from EXPR1() Where EXPR1 returns an anonymous iterator, and the expression (VAR1 from EXPR1()) evaluates as True only if a value from the EXPR1 iterator is received. Or possibly False if it is received and is None. [* see below] The for tests for the name binding instead of testing the value of VAR1, it may also be desirable to check VAR1 for None after it is recieved. This would be translated as follows: 1 -- while VAR1 from EXPR1(): raise an error if EXPR1 is not an iterator. 2 -- while (VAR1 = _EXPR1_iter.__next__()): # internal 3 -- while True: # if VAR1 gets a new value or 3 - while False: # if VAR1 fails to get a value [*]or 3 - while False: # if VAR1 receives None * Undecided on check for None. An iterator could always return something, so testing for None would be needed; or it could refuse and break the request somehow after it is called. In the later case None could be a valid return value it may not desirable to finalize the block. A while *might* be able to test for both. while VAR1 from EXPR1() and VAR1!=None: or ... while VAR1 from EXPR1() and VAR1: Order of placement could make a difference. while VAR1 and VAR1 from EXPR1(): This would test the *last* VAR1 before getting a new value. That might be useful in some situations. This may also be inconsistent with how expressions are currently evaluated. I'm not sure if it's allowed for names to rebound while evaluating an expression. Examples: while lock from locking(myLock): # Code here executes with myLock held. while f from opening(/etc/passwd): for line in f: print line.rstrip() while retry from auto_retry(3, IOError): f = urllib.urlopen(http://python.org/peps/pep-0340.html;) print f.read() while f from locking_opening(myLock, /etc/passwd): for line in f: print line.rstrip() while f from opening(filename, w): while re_out from redirecting_stdout(f): print Hello world while f, err from opening_w_error(/etc/passwd, a): if err: print IOError:, err else: f.write(guido::0:0::/:/bin/sh\n) Because the *from expression* evaluates to a bool, it might be useful in other places, although there may be reason to prevent it from being used as such. if VAR1 from GEN: print VAR1 else: print GEN didn't give me anything Another possibility is the use of xrange() in a block statements/ or extended while statements. while VAR1 from xrange(100): block This may blur the distinction between for loops and while loops, although it may be a *good* thing since for can then always used sequences, and the *extended while syntax* always use iterators. Which to use, would be up to the programmer. With that change xrange() support could be removed from for statements in Python 3000, (I think Guido wants to do that.), and it then could be used with extended while statements. With this suggestion there will still only be two looping constructs, for and while, and I think the distinction between a normal while and an extended while is made clear with the from keyword. I think this would be much easier to understand, IMO, and also much easier to read and teach as well. It uses already familiar syntax and adds a new expression keyword instead of a new statement keyword. A symbol might be possible instead of from, so adding new keywords could be avoided if from is out of the question. Optimistically, Ron_Adam ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340: Breaking out.
Ka-Ping Yee [EMAIL PROTECTED] wrote: On Thu, 5 May 2005, Josiah Carlson wrote: Ka-Ping Yee [EMAIL PROTECTED] wrote: continue with 2 There is something about action which level that I just don't like. Just to clarify: if by level you mean nesting level, did it appear that the 2 in my example was a count of block levels? I didn't mean it that way -- the 2 is a value passed in to the generator that appears as the value of the yield expression, as in PEP 340. I remember reading that, but I seem to have forgotten it when I was composing my reply. Thankfully, sleeping on it has helped me discover what I really don't like. With the 'passing value' semantic, the action [ which ] [ value ] is only useful for the deepest loop of a particular type. Take for example... for ...: for ...: for ...: break/continue [for] That break or continue can only affect that last for loop. It doesn't make any easier the use of nested fors, nested whiles, or even nested blocks. It only really helps you if you mix and match all possible looping constructs, and even then, only gives the granularity of the most recent block of a particular type. In that sense, I think it is a nonstarter, because it doesn't really add functionality in common uses of for and while statements. If one allowed action [which] [value] , [level], then one could jump to arbitrary loops. Now, I'm not condoning this, and I don't even like it. Sure, it allows breaking or continuing to any for, while, or block statement in the current scope, but the level argument is as equivalently ambiguous as package-relative imports using a leading integer (http://python.org/peps/pep-0328.html). Now, one can remove ambiguity if we were able to 'label' while loops and for loops producing action [ label ] , [ value ], but at that point we are getting into the discussion of a loop-aware goto with loop/block cleanup, and a syntax for labeling loops. Ick. - Josiah ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340 keyword: Extended while syntax
Gustavo Niemeyer wrote: Greetings, Reasoning: The block statement resembles a while block in some ways in that it is a conditional block that may be executed only once, or possibly not at all (or many times). And the word while is also descriptive of how a block is used. while VAR1 from EXPR1(): BLOCK This is an interesting propose, but for a different PEP. Maybe someone who is more familiar with submitting a PEP could submit it as a competing PEP to 340 then. In the current propose VAR1 is not evaluated for truthness, and many of the usage examples doesn't even require it. VAR1 isn't evaluated for truthfulness, but the expression as a whole is. It just says, EXPR1 is a iterator, and VAR1 received a value from it. Evaluating to a bool makes it consistent with the 'while' statement usage and those checks are all-ready taking place in the block statement. Here they are explicit instead of implicit which adds to the readability. IMHO of course. This looks quite strange, for instance: while dummy from locking(myLock): # Do something I thought of that, but I could get use to it. The dummy helps make it readable although the value may not actually be used in the block. One use with locks is to return a count of the current locks. Useful for monitoring what the iterator is doing. A shorter while locking(myLock): could be used, and the dummy from be optional. In that case the returned None would be discarded. while [NAME from] ITERATOR(): Or it could be made explicit with: while None == locking(myLock): Although I suppose this would look strange to some also. In this case, an explicit test is being made of the returned VAR1. Testing for other values could be possible. And also, this would require a break necessarily: while (foo, bar) from locking(): # Pass If the iterator is written without a loop in it, it will only execute one yield, so the second time though it will end without returning a value. def locking(): try: yield lock() finally: release lock() This will execute once in an extended while. def locking(): try: while True: yield new_lock() finally: release_all_locks() This would need to be broken out of. This will require a new keyword/operator 'from' to use in a 'from' expression: 'from' is already a keyword, btw. Oh, um... need more sleep. ;-) So no new keywords would be needed in this example, just an alternate use of an existing keyword. Replace the above with... This will require *no* new keyword, the keyword/operator 'from' will have a new use in an extended while expression: Since I tend to put imports at the top of my programs and never see 'from' anywhere else, it didn't ring a bell. Any reason why they both couldn't work? Cheers, Ron_Adam ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] New Py_UNICODE doc
On May 4, 2005, at 6:03 PM, Martin v. Löwis wrote: Nicholas Bastin wrote: This type represents the storage type which is used by Python internally as the basis for holding Unicode ordinals. Extension module developers should make no assumptions about the size of this type on any given platform. But people want to know Is Python's Unicode 16-bit or 32-bit? So the documentation should explicitly say it depends. The important piece of information is that it is not guaranteed to be a particular one of those sizes. Once you can't guarantee the size, no one really cares what size it is. The documentation should discourage developers from attempting to manipulate Py_UNICODE directly, which, other than trivia, is the only reason why someone would care what size the internal representation is. -- Nick ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340: Breaking out.
On 5/5/05, Nick Coghlan [EMAIL PROTECTED] wrote: Well, Michael Hudson and Paul Moore are the current authors of PEP 310, so updating it with any of my ideas would be their call. I'm willing to consider an update - I don't know Michael's view. I currently find myself in the odd situation of defending PEP 340 against PEP 310, though. I'll try to rationalise why below... Either way, my latest and greatest version of the non-looping block statement semantics can be found here: http://mail.python.org/pipermail/python-dev/2005-May/053400.html I can't reconcile this description with that of PEP 310. The basic reason is that the styles are very different, compounded by the fact that I don't have the time to give this the analysis it needs. My instinct is that if your proposal can't be described in terms of a relatively small change to one of PEP 310 or 340, then my view is it's a 3rd proposal in its own right, and I'd rather not open things up that much again. Some key advantages of that proposal are: 1. It's not a loop, so nesting it inside another loop 'just works' This, to me, is the main issue 2. Manual protocol implementations are _significantly_ easier to write Hmm, I've not tried so I'll have to take your word for this. But I don't imagine writing manual implementations much - one of the key features I like about Guido's proposal is that generators can be used, and the implementation is a clear template, with yield acting as a put the block here marker (yes, I know that's an oversimplification!). 3. try/finally can be done with generators _without_ changing generators How is this an advantage? PEP 340 allows try/finally inside generators - if that counts as changing generators I don't see why I care (as a user). But I think I'm missing something here - I never really followed (or cared about) the generator finalisation issues. 4. try/except/else can be done with generators if they provide an __exit__ method that raises the exception at the point of the last yield As above - I'm not sure I follow. 5. Clearly distinct construct, no potential for confusion with for loops OK, but that's really just saying not a loop again. 6. Generators must be clearly marked as creating a user defined statement (although this could be changed by giving them an __enter__ method and an __exit__ method) I still don't see a compelling argument that this is a good thing. I'm neutral on this. The one downside relative to PEP 340 is that looping constructs like auto_retry are slightly harder to write, albeit not hugely so (once you remember that an iterable can be a class instead of a generator!). Are you *sure* that's the only downside? Early on in the PEP 340 discussion, generator finalisation was a point of discussion. I didn't follow the details, but I believe that one of the points of PEP 340 was that it addressed the issues (to some extent - I really don't know if the generator finalisation PEPs are rendered obsolete by PEP 340, are completely orthogonal, or somewhere in between). I have no feel for whether your proposal covers these issues in the same way as PEP 340 does. And does your proposal allow for continue EXPR as supported by PEP 340? I can't see that it could, given that your proposal treats block statements as not being loops. Having just noticed this, I start to feel less convinced that block-as-loop is ultimately wrong. There aren't any examples of continue EXPR included in PEP 340 yet - a fact that Guido has acknowledged in item 9 of the examples section. Maybe Philip or one of the other coroutine fans would like to contribute some examples? On the usage front, I find the 'loop over an iterator returning user defined statements' does a much better job of making the iteration clear, so I'd be inclined to count that as an advantage of a PEP 310 style approach. I can accept that. It's a minor style point either way. The wording of it - as returning user defined statements makes me nervous though, as it implies that user-defined statements are first class objects - which feels wrong. Anyway, I've already been spending more time on this than I should (sleep is optional, right?), so I won't be prettying it up into PEP format any time soon. I have no objection to someone else rolling some of the ideas into a PEP, though :) I think *someone* has to care enough (and have the time) to make a proper PEP out of this. If it's a minor change to either of PEP 310 or PEP 340, that's OK. If it's too big for that, it needs to be fleshed out as a full competing PEP in its own right. Oh - and the promised rationalisation of my preference for PEP 340 over PEP 310. Things I like about PEP 340: - Using generators as templates with yield as a put the block here placeholder. It may be that a modification of PEP 310 can provide this, but that PEP doesn't exist yet (sorry!) - The coroutine style continue EXPR feature (I still need motivating examples but as a
Re: [Python-Dev] PEP 340: Breaking out.
On 5/5/05, Paul Moore [EMAIL PROTECTED] wrote: And does your proposal allow for continue EXPR as supported by PEP 340? I can't see that it could, given that your proposal treats block statements as not being loops. Read PEP 340 again -- the continue EXPR syntax is orthogonal to the discussion -- PEP 340 adds it for *all* for loops, so for loops with the non-looping block statements would also be able to use it. The looping behaviour is a (fairly nasty) wart, but I'm not sure I would insist on removing it at the cost of damaging other features I like. I don't think it damages any features. Are there features you still think the non-looping proposal removes? (I'm not counting orthogonal feautres like continue EXPR which could easily be added as an entirely separate PEP.) STeVe -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] New Py_UNICODE doc
Nicholas Bastin wrote: On May 4, 2005, at 6:20 PM, Shane Hathaway wrote: On a related note, it would be help if the documentation provided a little more background on unicode encoding. Specifically, that UCS-2 is not the same as UTF-16, even though they're both two bytes wide and most of the characters are the same. UTF-16 can encode 4 byte characters, while UCS-2 can't. A Py_UNICODE is either UCS-2 or UCS-4. It took me I'm not sure the Python documentation is the place to teach someone about unicode. The ISO 10646 pretty clearly defines UCS-2 as only containing characters in the BMP (plane zero). On the other hand, I don't know why python lets you choose UCS-2 anyhow, since it's almost always not what you want. Then something in the Python docs ought to say why UCS-2 is not what you want. I still don't know; I've heard differing opinions on the subject. Some say you'll never need more than what UCS-2 provides. Is that incorrect? More generally, how should a non-unicode-expert writing Python extension code find out the minimum they need to know about unicode to use the Python unicode API? The API reference [1] ought to at least have a list of background links. I had to hunt everywhere. .. [1] http://docs.python.org/api/unicodeObjects.html Shane ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] PEP 340: Examples as class's.
Eric Nieuwland wrote: Ron Adam wrote: Eric Nieuwland wrote: This is linear. No looping whatsoever. And easily translated to a simple language construct and a protocol: class resource(object): def __init__(self,...): # store resource parameters def __acquire__(self): # whatever it takes to grab the resource def __release__(self): # free the resource I wanted to see what the examples in PEP340 would look like written with standard class's using object inheritance and overriding to define resource managers. If anyone's interested I can post it. I'm interested. My block class is non-looping as I found in most cases looping isn't required, and looping complicates things because you have to pass around a loop expression due to not all loops will want to behave that same way. The solution was to put the loop in the body method and call a repeat_body method (the repeated body section) which is added to the class when needed. Show us your stuff! ;-) --eric Ok, :) These probably can be improved on, and renamed, and I don't know how many problems there may be with it, but they work in these examples. This is just one way to do it, so critique, correct, and improve as needed. Just no flames please. ;-) Cheers, Ron_Adam # --- start --- ## blockclass.py ## A base class that manages resource acquire and release. class Block(object): A manager class for working with resources. def __init__(self,*args): self._cleanup = False self.__err__ = None try: self.start(*args) self._cleanup = True except: raise def __call__(self, *args): self.block(*args) self.__del__() def __del__(self): if self._cleanup: try: self.final() self._cleanup = False except: raise if self.__err__: raise self.__err__ def start(self,*args): Override to add initialization code pass def final(self): Override to add finalization code pass def block(self,*args): Override to add main block body pass ## A dummy lock for test calls only class mylock: def acquire(self): print Lock acquired def release(self): print Lock released ## 1. A template for ensuring that a lock, acquired at the start of a ## block, is released when the block is left: class Get_Lock(Block): def start(self, lock): self.lock = lock self.lock.acquire() def final(self): self.lock.release() def block(self): pass class Lock_It(Get_Lock): def block(self): print Do stuff while locked Lock_It(mylock())() ## 2. A template for opening a file that ensures the file is closed: class File_Opener(Block): def start(self, filename, mode='r'): self.filename = filename self.mode = mode self.f = open(filename, mode) def final(self): self.f.close() def block(self): pass class Line_Printer(File_Opener): def block(self): n = 0 for line in self.f: print n, line.rstrip() n += 1 Line_Printer('blockclass.py')() ### 3. A template for committing or rolling back a database: #def transactional(db): #try: #yield #except: #db.rollback() #raise #else: #db.commit() I'm not exactly sure how this one should work, so maybe some one else can give an example using the block class above. ## 4. A template that tries something up to n times: import urllib class Auto_Retry(Block): def start(self, n=3, exc=Exception): self.n = n self.exc = exc def block(self, *args): while self.n: try: self.repeat_block(*args) break except self.exc, self.__err__: self.n -= 1 def repeat_block(self, *args): Try this block n times pass class Retry_Url(Auto_Retry): def repeat_block(self, url): f = urllib.urlopen(url) print f.read() # This could be slow, so wait for it. try: Retry_Url(3, IOError)(http://cantfind.com/this.html;) except IOError, err: print err Retry_Url(3, IOError)(http://python.org/peps/pep-0340.html;) ## 5. It is possible to nest blocks and combine templates: class Lockit(Get_Lock): def block(self, job): job() Lockit(mylock())(Line_Printer(blockclass.py)) ## 7. Redirect stdout temporarily: import sys class Redirect_Stdout(Block): def start(self, handle=sys.stdout): self.save_stdout = sys.stdout sys.stdout = handle def final(self): sys.stdout.close() sys.stdout = self.save_stdout def block(self): pass class New_Out(Redirect_Stdout): def block(self): print Writing to
Re: [Python-Dev] PEP 340: Breaking out.
Seems to me it should be up to the block iterator whether a break statement gets caught or propagated, since it's up to the block iterator whether the construct behaves like a loop or not. This could be achieved by having a separate exception for breaks, as originally proposed. If the iterator propagates the Break exception back out, the block statement should break any enclosing loop. If the iterator wants to behave like a loop, it can catch the Break exception and raise StopIteration instead. -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340: propose to get rid of 'as' keyword
Fredrik Lundh wrote: the current proposal stems from the observation that for-loop plus generators in today's Python does in fact provide a block implementation that solves many use cases in an elegant way. PEP 340 builds on this, sorts out a couple of weak points in the current design, and adds an elegant syntax for most remaining use cases. I still can't help feeling we're making a cart/horse ordering error here, though. Part of me regards the for-loop plus generators idea as an elegant hack, whose elegance only extends as far as it *doesn't* require anything beyond existing syntax and semantics. If new syntax and tricky new interactions with iterators are needed to support it, it doesn't seem so elegant any more. -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340 - Remaining issues - keyword
Nick Coghlan wrote: Something relatively nonsensical, but usefully mnemonic (like 'stmt') may be a good way to go. How about 'do'? do opening(filename) as f: ... do locking(obj): ... do carefully(): # :-) ... -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340: Breaking out.
Simon Percivall wrote: And this is not confusing in what way? I don't think it's any less confusing than having a construct in the first place which can either be a loop or not. You need to know the semantics of the block iterator in order to know whether it's a loop. Once you know that, you know how break behaves (as long as the iterator is sanely designed). Making it depend means you constantly have to readjust your understanding of the statement based on the context. And this is _if_ you know how it behaves in the particular case. If you're trying to understand the source code, having break depend on something defined somewhere completely else seems like an obstacle to easy understanding. IMHO, of course. //Simon -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340: Breaking out.
Delaney, Timothy C (Timothy) wrote: In this scenario (and I'm not saying I approve or disapprove) I think BreakIteration should inherit from StopIteration (thus retaining the existing PEP 340 semantics if uncaught):: Not sure I understand. The point of my suggestion was to *not* retain existing PEP 340 semantics if uncaught, i.e. break an enclosing loop rather than just terminate the block statement. -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Pre-PEP: Unifying try-except and try-finally
Nick Coghlan wrote: What does a try statement with neither an except clause nor a finally clause mean? I guess it would mean the same as if 1: ... Not particularly useful, but maybe it's not worth complexifying the grammar just for the sake of disallowing it. Also, some people might find it useful for indenting a block of code for cosmetic reasons, although that could easily be seen as an abuse... -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] PEP 340 - For loop cleanup, and feature separation
I'm still bothered by the idea of for-loops not participating in the new generator finalization protocol. It's all very well to say that iterators designed for block statements shouldn't be used in for-loops, but there may be more subtle cases to consider, such as def file_frobulations(filenames): for filename in filenames: block opening(filename) as f: yield something_derived_from(f) This is clearly intended to be a normal iterator, not a block iterator, and thus should be usable in a for-loop. But if for-loops don't use the finalization protocol, it won't be guaranteed to work correctly. So I think that, in the interests of least surprise, for-loops should provide the same finalization promises as block statements. If that is done, it becomes easier to decide whether the block statement should loop. The answer is probably no: If you're writing a loop, you use a for-statement; if you're not, you use a block-statement. This helps to clearly differentiate the two, and provide justification for having two statements. I'm also starting to like the idea of having a completely separate protocol for block-statements, and an adaptor of some kind for using generators to implement them. We would then have two *totally* separated new features: 1) A block-statement, and an associated protocol designed specifically for it, independent of any existing protocols. 2) A mechanism for passing values and exceptions into generators, which is useful in its own right and already has use cases. With the addition of an adaptor between the block protocol and the iterator protocol, which can be implemented *without* needing any further features, these two features then combine synergistically to give you block iterators implemented by generators. This makes a lot more sense to me than trying to warp the iterator protocol to make it into a block protocol as well. Let's keep the two things orthogonal. -- Greg Ewing, Computer Science Dept, +--+ University of Canterbury, | A citizen of NewZealandCorp, a | Christchurch, New Zealand | wholly-owned subsidiary of USA Inc. | [EMAIL PROTECTED] +--+ ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340 - For loop cleanup, and feature separation
Greg Ewing wrote: I'm still bothered by the idea of for-loops not participating in the new generator finalization protocol. I agree - that's always been nagging at me too. The problem with it is that then you either: 1. Have a guarantee that an iterator will be exhausted when the for loop exits (as per block statements); OR 2. Rely on garbage collection (reference counting, etc) to ensure finalisation. Personally, I'm of the opinion that we should make a significant break (no pun intended ;) and have for-loops attempt to ensure that iterators are exhausted. An iterator could be specifically designed to prevent that if needed, but in the vast majority of cases an iterator is never used after the for-loop. An example of an iterator that was specifically designed to continue working after its initial for-loop would be:: def gen(): try: setup1() try: yield 1 finally: cleanup1() except StopIteration: pass setup2() try: yield 2 finally: cleanup2() This allows cleanup, but then continued usage. So I think that, in the interests of least surprise, for-loops should provide the same finalization promises as block statements. Agreed. If that is done, it becomes easier to decide whether the block statement should loop. The answer is probably no: If you're writing a loop, you use a for-statement; if you're not, you use a block-statement. This helps to clearly differentiate the two, and provide justification for having two statements. Agreed. I'm also starting to like the idea of having a completely separate protocol for block-statements +1 and an adaptor of some kind for using generators to implement them. My preference would be direct syntactic support... Tim Delaney ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com