Re: [Python-Dev] Error checking in init functions

2005-04-24 Thread Armin Rigo
Hi Thomas,

On Fri, Apr 22, 2005 at 04:57:26PM +0200, Thomas Heller wrote:
> PyMODINIT_FUNC
> PyInit_zlib(void)
> {
> m = Py_InitModule4("zlib", zlib_methods,
>  zlib_module_documentation,
>  (PyObject*)NULL,PYTHON_API_VERSION);

I've seen a lot of code like this where laziness is actually buginess.  If the
Py_InitModule4() fails, you get a NULL in m, and that results in a segfault in
most of the cases.


Armin
___
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

2005-04-24 Thread John J Lee
On Sun, 24 Apr 2005, 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:
> 
> class Key2AttributeError(object):
>  def __init__(self, obj, attr):
>  self:
>  .obj_type = type(obj)
>  .attr = attr
>  def __except__(self, ex_type, ex_val, ex_tb):
>  if isinstance(ex_type, KeyError):
>   self:
>   raise AttributeError("%s instance has no attribute %s"
> % (.obj_type, .attr))
> 
> > # Somewhere else. . .
>  def __getattr__(self, name):
>  with Key2AttributeError(self, key):
>  self:
>  return ._cache[key]
[...]

+1

Purely based on my aesthetic reaction, that is.  Never having used other
languages with this 'attribute lookup shorthand' feature, that seems to
align *much* more with what I expect than the other way around.  If 'with'
is used in other languages as the keyword for attribute lookup shorthand,
though, perhaps it will confuse other people, or at least make them frown
:-(


John
___
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

2005-04-24 Thread Toby Dickenson
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.


-- 
Toby Dickenson
___
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

2005-04-24 Thread Josiah Carlson

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

2005-04-24 Thread Brett C.
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

2005-04-24 Thread holger krekel
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


Re: [Python-Dev] PEP 310 and exceptions

2005-04-24 Thread Nick Coghlan
Toby Dickenson 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.
Such existing pairings can be easily handled with a utility class like the one 
below. Besides, this part of the naming was considered for the original 
development of PEP 310 - entering and exiting the block is common to _all_ uses 
of the syntax, whereas other names are more specific to particular use cases.

class resource(object):
  def __init__(self, enter, exit):
self.enter = enter
self.exit = exit
  def __enter__(self):
self.enter()
  def __exit__(self):
self.exit()
with resource(my_resource.acquire, my_resource.release):
  # Do stuff!
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] Re: anonymous blocks

2005-04-24 Thread Guido van Rossum
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


Re: [Python-Dev] Re: anonymous blocks

2005-04-24 Thread Tim Delaney
Guido van Rossum wrote:
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
Might this be a good time to introduce __next__ (having the same signature 
and semantics as your proposed next_ex) and builtin next(obj, 
exception=None)?

def next(obj, exception=None):
   if hasattr(obj, '__next__'):
   return obj.__next__(exception)
   if exception is not None:
   return obj.next(exception) # Will raise an appropriate exception
   return obj.next()
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


[Python-Dev] site enhancements (request for review)

2005-04-24 Thread Bob Ippolito
A few weeks ago I put together a patch to site.py for Python 2.5 
 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

2005-04-24 Thread Brett C.
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(

[Python-Dev] zipfile still has 2GB boundary bug

2005-04-24 Thread Bob Ippolito
The "2GB bug" that was supposed to be fixed in 
 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 
.  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 .

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

2005-04-24 Thread Steven Bethard
Guido van Rossum wrote:
[snip illustration of how generators (and other iterators) can be
modified to be used in with-blocks]
> 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'm sure I could get used to it, but my intuition for

   with f = with_file(filename):
   for line in f:
   print process(line)

is that the f = with_file(filename) executes only once.  That is, as
you said, I don't expect this to be a looping syntax.  Of course, as
long as the generators (or other objects) here yield only one value
(like with_file does), then the with-block will execute only once. 
But because the implementation lets you make the with-block loop if
you want, it makes be nervous...

I guess it would be helpful to see example where the looping
with-block is useful.  So far, I think all the examples I've seen have
been like with_file, which only executes the block once.  Of course,
the loop allows you to do anything that you would normally do in a
for-loop, but my feeling is that this is probably better done by
composing a with-block that executes the block only once with a normal
Python for-loop.

I'd almost like to see the with-block translated into something like

   it = EXPR
   try:
   VAR = it.next()
   except StopIteration:
   raise WithNotStartedException
   err = None
   try:
   BODY
   except Exception, err: # Pretend "except Exception:" == "except:"
   pass
   try:
   it.next_ex(err)
   except StopIteration:
   pass
   else:
   raise WithNotEndedException

where there is no looping at all, and the iterator is expected to
yield exactly one item and then terminate.  Of course this looks a lot
like:

   it = EXPR
   VAR = it.__enter__()
   err = None
   try:
   BODY
   except Exception, err: # Pretend "except Exception:" == "except:"
   pass
   it.__exit__(err)

So maybe I'm just still stuck on the enter/exit semantics. ;-)

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] Re: anonymous blocks

2005-04-24 Thread Phillip J. Eby
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

2005-04-24 Thread Bob Ippolito
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


Re: [Python-Dev] Re: anonymous blocks

2005-04-24 Thread Phillip J. Eby
At 11:39 PM 4/24/05 -0400, Bob Ippolito wrote:
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.
Read Guido's post again; he proposed that passing a result would occur by 
raising a ReturnFlow exception!  In other words, it's the result passing 
that's the exceptional exception, while returning an exception is 
unexceptional.  :)

___
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

2005-04-24 Thread Bob Ippolito
On Apr 24, 2005, at 11:57 PM, Phillip J. Eby wrote:
At 11:39 PM 4/24/05 -0400, Bob Ippolito wrote:
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.
Read Guido's post again; he proposed that passing a result would occur 
by raising a ReturnFlow exception!  In other words, it's the result 
passing that's the exceptional exception, while returning an exception 
is unexceptional.  :)
Oh, right.  Too much cold medicine tonight I guess :)
You're right, of course.  This facility would be VERY nice to ab^Wuse 
when writing any event driven software.. not just Twisted.

-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

2005-04-24 Thread Phillip J. Eby
At 09:12 PM 4/24/05 -0600, Steven Bethard wrote:
I guess it would be helpful to see example where the looping
with-block is useful.
Automatically retry an operation a set number of times before hard failure:
with auto_retry(times=3):
do_something_that_might_fail()
Process each row of a database query, skipping and logging those that cause 
a processing error:

with x,y,z = log_errors(db_query()):
do_something(x,y,z)
You'll notice, by the way, that some of these "runtime macros" may be 
stackable in the expression.

I'm somewhat curious what happens to yields in the body of the macro block, 
but I assume they'll just do what would normally occur.  Somehow it seems 
strange, though, to be yielding to something other than the enclosing 
'with' object.

In any case, I'm personally more excited about the part where this means we 
get to build co-routines with less magic.  The 'with' statement itself is 
of interest mainly for acquisition/release and atomic/rollback scenarios, 
but being able to do retries or skip items that cause errors is often 
handy.  Sometimes you have a list of things (such as event callbacks) where 
you need to call all of them, even if one handler fails, but you can't 
afford to silence the errors either.  Code that deals with that scenario 
well is a bitch to write, and a looping 'with' would make it a bit easier 
to write once and reuse many.

___
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

2005-04-24 Thread Steven Bethard
On 4/24/05, Phillip J. Eby <[EMAIL PROTECTED]> wrote:
> At 09:12 PM 4/24/05 -0600, Steven Bethard wrote:
> >I guess it would be helpful to see example where the looping
> >with-block is useful.
> 
> Automatically retry an operation a set number of times before hard failure:
> 
>  with auto_retry(times=3):
>  do_something_that_might_fail()
> 
> Process each row of a database query, skipping and logging those that cause
> a processing error:
> 
>  with x,y,z = log_errors(db_query()):
>  do_something(x,y,z)

Thanks for the examples!  If I understand your point here right, the
examples that can't be easily rewritten by composing a
single-execution with-block with a for-loop are examples where the
number of iterations of the for-loop depends on the error handling of
the with-block.  Could you rewrite these with PEP 288 as something
like:

gen = auto_retry(times=3)
for _ in gen:
try:
do_something_that_might_fail()
except Exception, err: # Pretend "except Exception:" == "except:"
gen.throw(err)

gen = log_errors(db_query())
for x,y,z in gen:
try:
do_something(x,y,z)
except Exception, err: # Pretend "except Exception:" == "except:"
gen.throw(err)

Obviously, the code is cleaner using the looping with-block.  I'm just
trying to make sure I understand your examples right.

So assuming we had looping with-blocks, what would be the benefit of
using a for-loop instead?  Just efficiency?  Or is there something
that a for-loop could do that a with-block couldn't?

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