By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,270 Members | 1,703 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,270 IT Pros & Developers. It's quick & easy.

PEP 343, second look

P: n/a

After taking a break from following PEP 343 and it's associated PEPs, I
wanted to look at it again because it still seemed a bit hard to get my
mind around.

http://www.python.org/peps/pep-0343.html

A new statement is proposed with the syntax:

with EXPR as VAR:
BLOCK

Here, 'with' and 'as' are new keywords; EXPR is an arbitrary
expression (but not an expression-list) and VAR is a single
assignment target.


How is EXPR arbitrary? Doesn't it need to be or return an object that
the 'with' statement can use? (a "with" object with an __enter__ and
__exit__ method?)

And if so, what is the minimum 'with' class needed to create such an
object? It would need an __exit__ method, because there would be no
point if it didn't have one. Does it absolutely need an __enter__
method? Are there any uses that might not require an __enter__?

Presuming __enter__ is always needed, would this be a minimum class that
returns a 'with' object?

class With(object):
def __enter__(self):
pass
def __exit__(self):
pass
A 'with-generator' object would need __enter__ and __exit__ methods, and
a try-yield-finally generator. Is there a name for a 'with-generator'
object? (a witherator ?)

It's possible that a function may be used that returns an
'with-generator' object and would be used in the same way that range()
is used in 'for' statements.

func with_gen(func, *args, **args):
wg = WithGen()
wg.gen = func(*arg, **args)
return wg
Which would use a generic with-generator base class.

class WithGen(object):
def gen(self): # Should this raise an error
try: # if it does't get over ridden?
yield None
finally:
pass
def __enter__(self):
try:
return self.gen.next()
except StopIteration:
raise RuntimeError("generator didn't yield")
def __exit__(self, type, value, traceback):
if type is None:
try:
self.gen.next()
except StopIteration:
print "file closed by with statement"
return
else:
raise RuntimeError("generator didn't stop")
else:
try:
self.gen.throw(type, value, traceback)
except (type, StopIteration):
return
else:
raise RuntimeError("generator caught exception")
And used like this:

def opening(filename, mode):
f = open(filename, mode)
try:
yield f
finally:
f.close()

with with_gen(opening, "testfile", "w") as f:
f.write("test file")
This seems (to me) to be an easier to understand alternative to the
decorator version. The class could also be used as a base class for
constructing other 'with' class's as well as the with_template decorator.

Will this work or am I missing something? Any suggestions for a
different (better) name for the with_gen function?

Regards,
Ron

Jul 19 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Ron Adam <rr*@ronadam.com> writes:
A new statement is proposed with the syntax:
with EXPR as VAR:
BLOCK
Here, 'with' and 'as' are new keywords; EXPR is an arbitrary
expression (but not an expression-list)...


How is EXPR arbitrary? Doesn't it need to be or return an object that
the 'with' statement can use? (a "with" object with an __enter__ and
__exit__ method?)


That's not a syntactic issue. "x / y" is a syntactically valid
expression even though y==0 results in in a runtime error.
Jul 19 '05 #2

P: n/a
Paul Rubin wrote:
Ron Adam <rr*@ronadam.com> writes:
A new statement is proposed with the syntax:
with EXPR as VAR:
BLOCK
Here, 'with' and 'as' are new keywords; EXPR is an arbitrary
expression (but not an expression-list)...


How is EXPR arbitrary? Doesn't it need to be or return an object that
the 'with' statement can use? (a "with" object with an __enter__ and
__exit__ method?)

That's not a syntactic issue. "x / y" is a syntactically valid
expression even though y==0 results in in a runtime error.


The term 'arbitrary' may be overly broad. Take for example the
description used in the 2.41 documents for the 'for' statement.

"The expression list is evaluated once; it should yield an iterable object."
If the same style is used for the with statement it would read.

"The expression, (but not an expression-list), is evaluated once; it
should yield an object suitable for use with the 'with' statement. ... "

Or some variation of this.
Regards,
Ron


Jul 19 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.