Re: [Python-Dev] PEP 310 and exceptions
Shane Hathaway wrote: Nick Coghlan wrote: Which means finding a different name for '__else__'. Two possibilities that occur to me are '__ok__' or '__no_except__'. The latter makes a fair amount of sense, since I can't think of a way to refer to the thing other than as a 'no exception' handler. While we're on the subject of block handler method names, do the method names need four underscores? 'enter' and 'exit' look better than '__enter__' and '__exit__'. It's traditional for slots (or pseudo-slots) to have magic method names. It implies that the methods are expected to be called implicitly via special syntax or builtin functions, rather than explicitly in a normal method call. The only exception I can think of is the 'next' method of the iterator protocol. That method is often called explicitly, so the exception makes sense. For resources, there doesn't seem to be any real reason to call the methods directly - the calls will generally be hidden behind the 'with' block syntax. Hence, magic methods. 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 310 and exceptions
Toby Dickenson [EMAIL PROTECTED] wrote: On Sunday 24 April 2005 07:42, Nick Coghlan wrote: Shane Hathaway wrote: While we're on the subject of block handler method names, do the method names need four underscores? 'enter' and 'exit' look better than '__enter__' and '__exit__'. I quite like .acquire() and .release(). There are plenty of classes (and not just in the threading module) which already have methods with those names that could controlled by a 'with'. Those names also make the most sense in the C++ 'resource acquisition' model. Perhaps, but names for the equivalent of acquire resource and release resource are not consistant accross modules. Also, re-read Nick Coghlan's email with message id [EMAIL PROTECTED]. - 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] Proper place to put extra args for building
OK, EXTRA_CFLAGS support has been checked into Makefile.pre.in and distutils.sysconfig . Martin, please double-check I tweaked sysconfig the way you wanted. I also wasn't sure of compatibility for Distutils (first time touching it); checked PEP 291 but Distutils wasn't listed. I went ahead and used a genexp; hope that is okay. I also did it through Lib/distutils instead of the separate distutils top directory in CVS. I didn't bother with touching setup.py because I realized that sysconfig should take care of that. If that is wrong let me know and I can check in a change (and if I am right that line dealing with OPT in setup.py could probably go). Here are the revisions. Checking in Makefile.pre.in; /cvsroot/python/python/dist/src/Makefile.pre.in,v -- Makefile.pre.in new revision: 1.152; previous revision: 1.151 done Checking in README; /cvsroot/python/python/dist/src/README,v -- README new revision: 1.188; previous revision: 1.187 done Checking in Lib/distutils/sysconfig.py; /cvsroot/python/python/dist/src/Lib/distutils/sysconfig.py,v -- sysconfig.py new revision: 1.64; previous revision: 1.63 done Checking in Misc/SpecialBuilds.txt; /cvsroot/python/python/dist/src/Misc/SpecialBuilds.txt,v -- SpecialBuilds.txt new revision: 1.20; previous revision: 1.19 done Checking in Misc/NEWS; /cvsroot/python/python/dist/src/Misc/NEWS,v -- NEWS new revision: 1.1288; previous revision: 1.1287 done -Brett ___ 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] Re: __except__ use cases
Hi Nick, On Sun, Apr 24, 2005 at 12:40 +1000, Nick Coghlan wrote: Seeing this example has convinced me of something. PEP 310 should use the 'with' keyword, and 'expression block' syntax should be used to denote the 'default object' semantics proposed for Python 3K. For example: While that may be true, i don't care too much about the syntax yet but more about the idea and semantics of an __except__ hook. I simply followed the syntax that Guido currently seems to prefer. holger ___ 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] Re: anonymous blocks
After reading a lot of contributions (though perhaps not all -- this thread seems to bifurcate every time someone has a new idea :-) I'm back to liking yield for the PEP 310 use case. I think maybe it was Doug Landauer's post mentioning Beta, plus scanning some more examples of using yield in Ruby. Jim Jewett's post on defmacro also helped, as did Nick Coghlan's post explaining why he prefers 'with' for PEP 310 and a bare expression for the 'with' feature from Pascal (and other languages :-). It seems that the same argument that explains why generators are so good for defining iterators, also applies to the PEP 310 use case: it's just much more natural to write def with_file(filename): f = open(filename) try: yield f finally: f.close() than having to write a class with __entry__ and __exit__ and __except__ methods (I've lost track of the exact proposal at this point). At the same time, having to use it as follows: for f in with_file(filename): for line in f: print process(line) is really ugly, so we need new syntax, which also helps with keeping 'for' semantically backwards compatible. So let's use 'with', and then the using code becomes again this: with f = with_file(filename): for line in f: print process(line) Now let me propose a strawman for the translation of the latter into existing semantics. Let's take the generic case: with VAR = EXPR: BODY This would translate to the following code: it = EXPR err = None while True: try: if err is None: VAR = it.next() else: VAR = it.next_ex(err) except StopIteration: break try: err = None BODY except Exception, err: # Pretend except Exception: == except: if not hasattr(it, next_ex): raise (The variables 'it' and 'err' are not user-visible variables, they are internal to the translation.) This looks slightly awkward because of backward compatibility; what I really want is just this: it = EXPR err = None while True: try: VAR = it.next(err) except StopIteration: break try: err = None BODY except Exception, err: # Pretend except Exception: == except: pass but for backwards compatibility with the existing argument-less next() API I'm introducing a new iterator API next_ex() which takes an exception argument. If that argument is None, it should behave just like next(). Otherwise, if the iterator is a generator, this will raised that exception in the generator's frame (at the point of the suspended yield). If the iterator is something else, the something else is free to do whatever it likes; if it doesn't want to do anything, it can just re-raise the exception. Also note that, unlike the for-loop translation, this does *not* invoke iter() on the result of EXPR; that's debatable but given that the most common use case should not be an alternate looping syntax (even though it *is* technically a loop) but a more general macro statement expansion, I think we can expect EXPR to produce a value that is already an iterator (rather than merely an interable). Finally, I think it would be cool if the generator could trap occurrences of break, continue and return occurring in BODY. We could introduce a new class of exceptions for these, named ControlFlow, and (only in the body of a with statement), break would raise BreakFlow, continue would raise ContinueFlow, and return EXPR would raise ReturnFlow(EXPR) (EXPR defaulting to None of course). So a block could return a value to the generator using a return statement; the generator can catch this by catching ReturnFlow. (Syntactic sugar could be VAR = yield ... like in Ruby.) With a little extra magic we could also get the behavior that if the generator doesn't handle ControlFlow exceptions but re-raises them, they would affect the code containing the with statement; this means that the generator can decide whether return, break and continue are handled locally or passed through to the containing block. Note that EXPR doesn't have to return a generator; it could be any object that implements next() and next_ex(). (We could also require next_ex() or even next() with an argument; perhaps this is better.) -- --Guido van Rossum (home page: http://www.python.org/~guido/) ___ 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] site enhancements (request for review)
A few weeks ago I put together a patch to site.py for Python 2.5 http://python.org/sf/1174614 that solves three major deficiencies: (1) All site dirs must exist on the filesystem: Since PEP 302 (New Import Hooks) was adopted, this is not necessarily true. sys.meta_path and sys.path_hooks can have valid uses for non- existent paths. Even the standard zipimport hook supports in-zip- file paths (i.e. foo.zip/bar). (2) The directories added to sys.path by .pth files are not scanned for further .pth files. If they were, you could make life much easier on developers and users of multi-user systems. For example, it would be possible for an administrator to drop in a .pth file into the system-wide site-packages to allow users to have their own local site-packages folder. Currently, you could try this, but it wouldn't work because many packages such as PIL, Numeric, and PyObjC take advantage of .pth files during their installation. (3) To support the above use case, .pth files should be allowed to use os.path.expanduser(), so you can toss a tilde in front and do the right thing. Currently, the only way to support (2) is to use an ugly import pth hook. So far, it seem that only JvR has reviewed the patch, and recommends apply. I'd like to apply it, but it should probably have a bit more review first. If no negative comments show up for a week or two, I'll assume that people like it or don't care, and apply. -bob ___ 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] Re: anonymous blocks
Guido van Rossum wrote: [SNIP] Now let me propose a strawman for the translation of the latter into existing semantics. Let's take the generic case: with VAR = EXPR: BODY This would translate to the following code: [SNIP] it = EXPR err = None while True: try: VAR = it.next(err) except StopIteration: break try: err = None BODY except Exception, err: # Pretend except Exception: == except: pass but for backwards compatibility with the existing argument-less next() API I'm introducing a new iterator API next_ex() which takes an exception argument. Can I suggest the name next_exc() instead? Everything in the sys module uses exc as the abbreviation for exception. I realize you might be suggesting using the ex as the suffix because of the use of that as the suffix in the C API for an extended API, but that usage is not prominent in the stdlib. Also, would this change in Python 3000 so that both next_ex() and next() are merged into a single method? As for an opinion of the need of 'with', I am on the fence, leaning towards liking it. To make sure I am understanding the use case, it is to help encapsulate typical resource management with proper cleanup in another function instead of having to constantly pasting in boilerplate into your code, right? So the hope is to be able to create factory functions, typically implemented as a generator, that encapsulate the obtaining, temporary lending out, and cleanup of a resource? Is there some other use that I am totally missing that is obvious? If that argument is None, it should behave just like next(). Otherwise, if the iterator is a generator, this will raised that exception in the generator's frame (at the point of the suspended yield). If the iterator is something else, the something else is free to do whatever it likes; if it doesn't want to do anything, it can just re-raise the exception. Also note that, unlike the for-loop translation, this does *not* invoke iter() on the result of EXPR; that's debatable but given that the most common use case should not be an alternate looping syntax (even though it *is* technically a loop) but a more general macro statement expansion, I think we can expect EXPR to produce a value that is already an iterator (rather than merely an interable). Finally, I think it would be cool if the generator could trap occurrences of break, continue and return occurring in BODY. We could introduce a new class of exceptions for these, named ControlFlow, and (only in the body of a with statement), break would raise BreakFlow, continue would raise ContinueFlow, and return EXPR would raise ReturnFlow(EXPR) (EXPR defaulting to None of course). So a block could return a value to the generator using a return statement; the generator can catch this by catching ReturnFlow. (Syntactic sugar could be VAR = yield ... like in Ruby.) With a little extra magic we could also get the behavior that if the generator doesn't handle ControlFlow exceptions but re-raises them, they would affect the code containing the with statement; this means that the generator can decide whether return, break and continue are handled locally or passed through to the containing block. Honestly, I am not very comfortable with this magical meaning of 'break', 'continue', and 'return' in a 'with' block. I realize 'return' already has special meaning in an generator, but I don't think that is really needed either. It leads to this odd dichotomy where a non-exception-related statement directly triggers an exception in other code. It seems like code doing something behind my back; remember, it looks like a 'continue', but it really is a method call with a specific exception instance. Surprise! Personally, what I would rather see, is to have next_ex(), for a generator, check if the argument is a subclass of Exception. If it is, raise it as such. If not, have the 'yield' statement return the passed-in argument. This use of it would make sense for using the next_ex() name. Then again I guess having exceptions triggering a method call instead of hitting an 'except' statement is already kind of surprise semantics anyway. =) Still, I would like to minimize the surprises that we could spring. And before anyone decries the fact that this might confuse a newbie (which seems to happen with every advanced feature ever dreamed up), remember this will not be meant for a newbie but for someone who has experience in Python and iterators at the minimum, and hopefully with generators. Not exactly meant for someone for which raw_input() still holds a wow factor for. =) Note that EXPR doesn't have to return a generator; it could be any object that implements next() and next_ex(). (We could also require next_ex() or even next() with an argument; perhaps this is better.) Yes, that requirement would
[Python-Dev] zipfile still has 2GB boundary bug
The 2GB bug that was supposed to be fixed in http://python.org/sf/679953 was not actually fixed. The zipinfo offsets in the structures are still signed longs, so the fix allows you to write one file that extends past the 2G boundary, but if any extend past that point you are screwed. I have opened a new bug and patch that should fix this issue http://python.org/sf/1189216. This is a backport candidate to 2.4.2 and 2.3.6 (if that ever happens). On a related note, if anyone else has a bunch of really big and ostensibly broken zip archives created by dumb versions of the zipfile module, I have written a script that can rebuild the central directory in-place. Ping me off-list if you're interested and I'll clean it up. Someone should think about rewriting the zipfile module to be less hideous, include a repair feature, and be up to date with the latest specifications http://www.pkware.com/company/standards/appnote/. Additionally, it'd also be useful if someone were to include support for Apple's extensions to the zip format (the __MACOSX folder and its contents) that show up when BOM (private framework) is used to create archives (i.e. Finder in Mac OS X 10.3+). I'm not sure if these are documented anywhere, but I can help with reverse engineering if someone is interested in writing the code. On that note, Mac OS X 10.4 (Tiger) is supposed to have new APIs (or changes to existing APIs?) to facilitate resource fork preservation, ACLs, and Spotlight hooks in tar, cp, mv, etc. Someone should spend some time looking at the Darwin 8 sources for these tools (when they're publicly available in the next few weeks) to see what would need to be done in Python to support them in the standard library (the os, tarfile, etc. modules). -bob ___ 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] Re: anonymous blocks
At 04:57 PM 4/24/05 -0700, Guido van Rossum wrote: So a block could return a value to the generator using a return statement; the generator can catch this by catching ReturnFlow. (Syntactic sugar could be VAR = yield ... like in Ruby.) [uncontrolled drooling, followed by much rejoicing] If this were available to generators in general, you could untwist Twisted. I'm basically simulating this sort of exception/value passing in peak.events to do exactly that, except I have to do: yield somethingBlocking(); result=events.resume() where events.resume() magically receives a value or exception from outside the generator and either returns or raises it. If next()-with-argument and next_ex() are available normally on generators, this would allow you to simulate co-routines without the events.resume() magic; the above would simply read: result = yield somethingBlocking() The rest of the peak.events coroutine simulation would remain around to manage the generator stack and scheduling, but the syntax would be cleaner and the operation of it entirely unmagical. ___ 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] Re: anonymous blocks
On Apr 24, 2005, at 11:32 PM, Phillip J. Eby wrote: At 04:57 PM 4/24/05 -0700, Guido van Rossum wrote: So a block could return a value to the generator using a return statement; the generator can catch this by catching ReturnFlow. (Syntactic sugar could be VAR = yield ... like in Ruby.) [uncontrolled drooling, followed by much rejoicing] If this were available to generators in general, you could untwist Twisted. I'm basically simulating this sort of exception/value passing in peak.events to do exactly that, except I have to do: yield somethingBlocking(); result=events.resume() where events.resume() magically receives a value or exception from outside the generator and either returns or raises it. If next()-with-argument and next_ex() are available normally on generators, this would allow you to simulate co-routines without the events.resume() magic; the above would simply read: result = yield somethingBlocking() The rest of the peak.events coroutine simulation would remain around to manage the generator stack and scheduling, but the syntax would be cleaner and the operation of it entirely unmagical. Only if result = yield somethingBlocking() could also raise an exception. -bob ___ 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