with statement syntax forces ugly line breaks?

Hi, I can't see a _nice_ way of splitting a with statement over mulitple lines: class FakeContext: def __init__(self, name): self.name = name def __enter__(self): print("enter", self.name) def __exit__(self, *args): print("exit", self.name) with FakeContext("a") as a, FakeContext("b") as b: pass # works fine with FakeContext("a") as a, FakeContext("b") as b: pass # synax error with (FakeContext("a") as a, FakeContext("b") as b): pass # synax error The use case where this mattered to me was this: with open(args.actual, encoding="utf-8") as afh, open(args.expected, encoding="utf-8") as efh: actual = [line.rstrip("\n\r") for line in afh.readlines()] expected = [line.rstrip("\n\r") for line in efh.readlines()] Naturally, I could split the line in an ugly place: with open(args.actual, encoding="utf-8") as afh, open(args.expected, encoding="utf-8") as efh: but it seems a shame to do so. Or am I missing something? I'm using Python 3.1.2. -- Mark Summerfield, Qtrac Ltd, www.qtrac.eu C++, Python, Qt, PyQt - training and consultancy "Rapid GUI Programming with Python and Qt" - ISBN 0132354187 http://www.qtrac.eu/pyqtbook.html

Mark, I have approached these cases by using the backslash line-continuation operator: with FakeContext("a") as a, \ FakeContext("b") as b: pass Nathan On Wed, Sep 8, 2010 at 12:50 PM, Mark Summerfield <mark@qtrac.eu> wrote:
Hi,
I can't see a _nice_ way of splitting a with statement over mulitple lines:
class FakeContext: def __init__(self, name): self.name = name def __enter__(self): print("enter", self.name) def __exit__(self, *args): print("exit", self.name)
with FakeContext("a") as a, FakeContext("b") as b: pass # works fine
with FakeContext("a") as a, FakeContext("b") as b: pass # synax error
with (FakeContext("a") as a, FakeContext("b") as b): pass # synax error
The use case where this mattered to me was this:
with open(args.actual, encoding="utf-8") as afh, open(args.expected, encoding="utf-8") as efh: actual = [line.rstrip("\n\r") for line in afh.readlines()] expected = [line.rstrip("\n\r") for line in efh.readlines()]
Naturally, I could split the line in an ugly place:
with open(args.actual, encoding="utf-8") as afh, open(args.expected, encoding="utf-8") as efh:
but it seems a shame to do so. Or am I missing something?
I'm using Python 3.1.2.
-- Mark Summerfield, Qtrac Ltd, www.qtrac.eu C++, Python, Qt, PyQt - training and consultancy "Rapid GUI Programming with Python and Qt" - ISBN 0132354187 http://www.qtrac.eu/pyqtbook.html _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas

On Wed, Sep 8, 2010 at 10:00 AM, Nathan Schneider <nathan@cmu.edu> wrote:
Mark,
I have approached these cases by using the backslash line-continuation operator:
with FakeContext("a") as a, \ FakeContext("b") as b: pass
Nathan
I'm in the "\ is evil" at all costs camp so I'd suggest either the nested with statements or alternatively do this: fc = FakeContext with fc("a") as a, fc("b") as b: pass
On Wed, Sep 8, 2010 at 12:50 PM, Mark Summerfield <mark@qtrac.eu> wrote:
Hi,
I can't see a _nice_ way of splitting a with statement over mulitple lines:
class FakeContext: def __init__(self, name): self.name = name def __enter__(self): print("enter", self.name) def __exit__(self, *args): print("exit", self.name)
with FakeContext("a") as a, FakeContext("b") as b: pass # works fine
with FakeContext("a") as a, FakeContext("b") as b: pass # synax error
with (FakeContext("a") as a, FakeContext("b") as b): pass # synax error
The use case where this mattered to me was this:
with open(args.actual, encoding="utf-8") as afh, open(args.expected, encoding="utf-8") as efh: actual = [line.rstrip("\n\r") for line in afh.readlines()] expected = [line.rstrip("\n\r") for line in efh.readlines()]
Naturally, I could split the line in an ugly place:
with open(args.actual, encoding="utf-8") as afh, open(args.expected, encoding="utf-8") as efh:
but it seems a shame to do so. Or am I missing something?
I'm using Python 3.1.2.
-- Mark Summerfield, Qtrac Ltd, www.qtrac.eu C++, Python, Qt, PyQt - training and consultancy "Rapid GUI Programming with Python and Qt" - ISBN 0132354187 http://www.qtrac.eu/pyqtbook.html _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
_______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas

"Gregory P. Smith" <greg@krypto.org> writes:
On Wed, Sep 8, 2010 at 10:00 AM, Nathan Schneider <nathan@cmu.edu> wrote:
I have approached these cases by using the backslash line-continuation operator:
with FakeContext("a") as a, \ FakeContext("b") as b: pass
I'm in the "\ is evil" at all costs camp […]
I agree, especially when we have a much neater continuation mechanism that could work just fine here:: with (FakeContext("a") as a, FakeContext("b") as b): pass -- \ “[Entrenched media corporations will] maintain the status quo, | `\ or die trying. Either is better than actually WORKING for a | _o__) living.” —ringsnake.livejournal.com, 2007-11-12 | Ben Finney

Am 09.09.2010 09:55, schrieb Ben Finney:
"Gregory P. Smith" <greg@krypto.org> writes:
On Wed, Sep 8, 2010 at 10:00 AM, Nathan Schneider <nathan@cmu.edu> wrote:
I have approached these cases by using the backslash line-continuation operator:
with FakeContext("a") as a, \ FakeContext("b") as b: pass
I'm in the "\ is evil" at all costs camp […]
I agree, especially when we have a much neater continuation mechanism that could work just fine here::
with (FakeContext("a") as a, FakeContext("b") as b): pass
No, it could not work just fine. You are basically banning tuples from the context expression (remember that the "as" clause is optional). You would argue that this is not a problem because tuples are not context -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.

Am 09.09.2010 09:55, schrieb Ben Finney:
"Gregory P. Smith" <greg@krypto.org> writes:
On Wed, Sep 8, 2010 at 10:00 AM, Nathan Schneider <nathan@cmu.edu> wrote:
I have approached these cases by using the backslash line-continuation operator:
with FakeContext("a") as a, \ FakeContext("b") as b: pass
I'm in the "\ is evil" at all costs camp […]
I agree, especially when we have a much neater continuation mechanism that could work just fine here::
with (FakeContext("a") as a, FakeContext("b") as b): pass
No, it could not work just fine. You are basically banning tuples from the context expression (remember that the "as" clause is optional). Maybe one could argue that this is not a problem because tuples are not context managers anyway, but how would this work then: i = 0 or 1 with (a, b)[i]: Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.

On 09/09/2010 02:17 PM, Georg Brandl wrote:
Am 09.09.2010 09:55, schrieb Ben Finney:
"Gregory P. Smith"<greg@krypto.org> writes:
On Wed, Sep 8, 2010 at 10:00 AM, Nathan Schneider<nathan@cmu.edu> wrote:
I have approached these cases by using the backslash line-continuation operator:
with FakeContext("a") as a, \ FakeContext("b") as b: pass
I'm in the "\ is evil" at all costs camp […]
I agree, especially when we have a much neater continuation mechanism that could work just fine here::
with (FakeContext("a") as a, FakeContext("b") as b): pass
No, it could not work just fine. You are basically banning tuples from the context expression (remember that the "as" clause is optional).
Maybe one could argue that this is not a problem because tuples are not context managers anyway, but how would this work then:
i = 0 or 1 with (a, b)[i]:
Georg
Just write: with ((a, b)[i]): It's ugly but it would work. ;) -panzi

Hi Nathan, On Wed, 8 Sep 2010 13:00:25 -0400 Nathan Schneider <nathan@cmu.edu> wrote:
Mark,
I have approached these cases by using the backslash line-continuation operator:
with FakeContext("a") as a, \ FakeContext("b") as b: pass
Yes, of course, and that's the way I've done it. But it seems a pity to do it this way when the documentation explicitly discourages the use of the backslash for line continuation: http://docs.python.org/py3k/howto/doanddont.html (look at the very last item)
Nathan
On Wed, Sep 8, 2010 at 12:50 PM, Mark Summerfield <mark@qtrac.eu> wrote:
Hi,
I can't see a _nice_ way of splitting a with statement over mulitple lines:
class FakeContext: def __init__(self, name): self.name = name def __enter__(self): print("enter", self.name) def __exit__(self, *args): print("exit", self.name)
with FakeContext("a") as a, FakeContext("b") as b: pass # works fine
with FakeContext("a") as a, FakeContext("b") as b: pass # synax error
with (FakeContext("a") as a, FakeContext("b") as b): pass # synax error
The use case where this mattered to me was this:
with open(args.actual, encoding="utf-8") as afh, open(args.expected, encoding="utf-8") as efh: actual = [line.rstrip("\n\r") for line in afh.readlines()] expected = [line.rstrip("\n\r") for line in efh.readlines()]
Naturally, I could split the line in an ugly place:
with open(args.actual, encoding="utf-8") as afh, open(args.expected, encoding="utf-8") as efh:
but it seems a shame to do so. Or am I missing something?
I'm using Python 3.1.2.
-- Mark Summerfield, Qtrac Ltd, www.qtrac.eu C++, Python, Qt, PyQt - training and consultancy "Rapid GUI Programming with Python and Qt" - ISBN 0132354187 http://www.qtrac.eu/pyqtbook.html _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- Mark Summerfield, Qtrac Ltd, www.qtrac.eu C++, Python, Qt, PyQt - training and consultancy "Programming in Python 3" - ISBN 0321680561 http://www.qtrac.eu/py3book.html

Am 09.09.2010 07:49, schrieb Mark Summerfield:
Hi Nathan,
On Wed, 8 Sep 2010 13:00:25 -0400 Nathan Schneider <nathan@cmu.edu> wrote:
Mark,
I have approached these cases by using the backslash line-continuation operator:
with FakeContext("a") as a, \ FakeContext("b") as b: pass
Yes, of course, and that's the way I've done it. But it seems a pity to do it this way when the documentation explicitly discourages the use of the backslash for line continuation: http://docs.python.org/py3k/howto/doanddont.html (look at the very last item)
Which is actually factually incorrect and should be rewritten. The only situation where stray whitespace after a backslash is valid syntax is within a string literal (and there, there is no alternative). So at least the "stray whitespace leads to silently buggy code" reason not to use backslashes is wrong. Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.

On 9/9/2010 8:14 AM, Georg Brandl wrote:
Am 09.09.2010 07:49, schrieb Mark Summerfield:
Hi Nathan,
On Wed, 8 Sep 2010 13:00:25 -0400 Nathan Schneider<nathan@cmu.edu> wrote:
Mark,
I have approached these cases by using the backslash line-continuation operator:
with FakeContext("a") as a, \ Adding a space makes the following a SyntaxError. No silent error here.
FakeContext("b") as b: pass
Yes, of course, and that's the way I've done it. But it seems a pity to do it this way when the documentation explicitly discourages the use of the backslash for line continuation: http://docs.python.org/py3k/howto/doanddont.html (look at the very last item)
If no one uses \ for end of line escape, it should be removed ... But I am not suggesting that.
Which is actually factually incorrect and should be rewritten. The only situation where stray whitespace after a backslash is valid syntax is within a string literal (and there, there is no alternative).
So at least the "stray whitespace leads to silently buggy code" reason not to use backslashes is wrong.
Georg
-- Terry Jan Reedy

On Wed, 8 Sep 2010 17:50:29 +0100 Mark Summerfield <mark@qtrac.eu> wrote:
Hi,
I can't see a _nice_ way of splitting a with statement over mulitple lines:
class FakeContext: def __init__(self, name): self.name = name def __enter__(self): print("enter", self.name) def __exit__(self, *args): print("exit", self.name)
with FakeContext("a") as a, FakeContext("b") as b: pass # works fine
with FakeContext("a") as a, FakeContext("b") as b: pass # synax error
with (FakeContext("a") as a, FakeContext("b") as b): pass # synax error
How about: with FakeContext("a") as a: with FakeContext("B") as b: If the double-indent bothers you, using two two-space indents might be acceptable in this case. <mike -- Mike Meyer <mwm@mired.org> http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O< ascii ribbon campaign - stop html mail - www.asciiribbon.org

Am 08.09.2010 18:50, schrieb Mark Summerfield:
Hi,
I can't see a _nice_ way of splitting a with statement over mulitple lines:
class FakeContext: def __init__(self, name): self.name = name def __enter__(self): print("enter", self.name) def __exit__(self, *args): print("exit", self.name)
with FakeContext("a") as a, FakeContext("b") as b: pass # works fine
with FakeContext("a") as a, FakeContext("b") as b: pass # synax error
with (FakeContext("a") as a, FakeContext("b") as b): pass # synax error
In addition to the backslash hint already given, I'd like to explain why this version isn't allowed: the parser couldn't distinguish between a multi-context with and an expression in parentheses. (In the case of import, where parens can be used around the import list, this is different, no arbitrary expression is allowed.) Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.

On Thu, Sep 9, 2010 at 4:07 AM, Georg Brandl <g.brandl@gmx.net> wrote:
In addition to the backslash hint already given, I'd like to explain why this version isn't allowed: the parser couldn't distinguish between a multi-context with and an expression in parentheses.
(In the case of import, where parens can be used around the import list, this is different, no arbitrary expression is allowed.)
I've sometimes wondered if we should consider the idea of making line continuation implicit between keywords and their associated colons. I've never seriously investigated the implications for the parser, though. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On 08/09/2010 22:30, Nick Coghlan wrote:
On Thu, Sep 9, 2010 at 4:07 AM, Georg Brandl<g.brandl@gmx.net> wrote:
In addition to the backslash hint already given, I'd like to explain why this version isn't allowed: the parser couldn't distinguish between a multi-context with and an expression in parentheses.
(In the case of import, where parens can be used around the import list, this is different, no arbitrary expression is allowed.)
I've sometimes wondered if we should consider the idea of making line continuation implicit between keywords and their associated colons. I've never seriously investigated the implications for the parser, though.
If a colon was omitted by mistake, how much later would the parser report a syntax error?

MRAB wrote:
On 08/09/2010 22:30, Nick Coghlan wrote:
I've sometimes wondered if we should consider the idea of making line continuation implicit between keywords and their associated colons.
If a colon was omitted by mistake, how much later would the parser report a syntax error?
It might be best to allow this only if the continuation lines are indented at least as far as the starting line. -- Greg

Am 09.09.2010 01:19, schrieb Greg Ewing:
MRAB wrote:
On 08/09/2010 22:30, Nick Coghlan wrote:
I've sometimes wondered if we should consider the idea of making line continuation implicit between keywords and their associated colons.
If a colon was omitted by mistake, how much later would the parser report a syntax error?
It might be best to allow this only if the continuation lines are indented at least as far as the starting line.
That is dangerous, it makes the whitespace rules more complicated. Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.

On Thu, Sep 9, 2010 at 10:08 PM, Georg Brandl <g.brandl@gmx.net> wrote:
Am 09.09.2010 01:19, schrieb Greg Ewing:
MRAB wrote:
On 08/09/2010 22:30, Nick Coghlan wrote:
I've sometimes wondered if we should consider the idea of making line continuation implicit between keywords and their associated colons.
If a colon was omitted by mistake, how much later would the parser report a syntax error?
It might be best to allow this only if the continuation lines are indented at least as far as the starting line.
That is dangerous, it makes the whitespace rules more complicated.
I'm actually not sure it is even *possible* in general to implement my suggestion given the deliberate limitations of Python's parser. Parentheses normally work their indentation-ignoring magic by dropping down into expression evaluation scope where indentation isn't significant (import is a special case where this doesn't quite happen, but it's a rather constrained one). This is definitely a wart in the with statement syntax, but it really isn't clear how best to resolve it. You can at least use parentheses in the individual context expressions, even though you can't wrap the whole thing: .>> from contextlib import contextmanager .>> @contextmanager ... def FakeContext(a): ... yield a ... .>> with FakeContext(1) as x, ( ... FakeContext(2)) as y: ... print(x, y) ... 1 2 Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia

On Wed, Sep 8, 2010 at 5:30 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
I've sometimes wondered if we should consider the idea of making line continuation implicit between keywords and their associated colons.
This would also have the nice aesthetic quality of making colons serve a purpose.

On 09/09/10 00:47, Mike Graham wrote:
On Wed, Sep 8, 2010 at 5:30 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
I've sometimes wondered if we should consider the idea of making line continuation implicit between keywords and their associated colons.
This would also have the nice aesthetic quality of making colons serve a purpose.
Good point! I'm regularly niggled that backslash continuations are needed for long conditional statements where parentheses are not logically necessary (and look disturbingly unpythonic.) There's no ambiguity in allowing statements to extend until the colon, particularly if Greg's "at least as far" indentation rule is applied. +1 from me. Andy

Mark Summerfield wrote:
Hi,
I can't see a _nice_ way of splitting a with statement over mulitple lines:
class FakeContext: def __init__(self, name): self.name = name def __enter__(self): print("enter", self.name) def __exit__(self, *args): print("exit", self.name)
with FakeContext("a") as a, FakeContext("b") as b: pass # works fine
with FakeContext("a") as a, FakeContext("b") as b: pass # synax error
with (FakeContext("a") as a, FakeContext("b") as b): pass # synax error
The use case where this mattered to me was this:
with open(args.actual, encoding="utf-8") as afh, open(args.expected, encoding="utf-8") as efh: actual = [line.rstrip("\n\r") for line in afh.readlines()] expected = [line.rstrip("\n\r") for line in efh.readlines()]
Naturally, I could split the line in an ugly place:
with open(args.actual, encoding="utf-8") as afh, open(args.expected, encoding="utf-8") as efh:
but it seems a shame to do so. Or am I missing something?
Why do you need to put everything on one line ? afh = open(args.actual, encoding="utf-8") efh = open(args.expected, encoding="utf-8") with afh, efh: ... In the context of files, the only purpose of the with statement is to close them when leaving the block.
a = open('/etc/passwd') b = open('/etc/group') with a,b: print a.readline(), b.readline() ... at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash at:!:25:
a <closed file '/etc/passwd', mode 'r' at 0x7f0093e62390> b <closed file '/etc/group', mode 'r' at 0x7f0093e62420>
-- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Sep 09 2010)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
2010-08-19: Released mxODBC 3.1.0 http://python.egenix.com/ 2010-09-15: DZUG Tagung, Dresden, Germany 6 days to go ::: Try our new mxODBC.Connect Python Database Interface for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/

On 9 September 2010 14:32, M.-A. Lemburg <mal@egenix.com> wrote:
[snip...] Why do you need to put everything on one line ?
afh = open(args.actual, encoding="utf-8") efh = open(args.expected, encoding="utf-8")
with afh, efh: ...
In the context of files, the only purpose of the with statement is to close them when leaving the block.
a = open('/etc/passwd') b = open('/etc/group')
If my understanding is correct (which is perhaps unlikely...), using a single line will close a if opening b fails. Whereas doing them separately before the with statement risks leaving the first un-exited if creating the second fails. Michael
with a,b: print a.readline(), b.readline() ... at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash at:!:25:
a <closed file '/etc/passwd', mode 'r' at 0x7f0093e62390> b <closed file '/etc/group', mode 'r' at 0x7f0093e62420>
-- Marc-Andre Lemburg eGenix.com
Professional Python Services directly from the Source (#1, Sep 09 2010)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
2010-08-19: Released mxODBC 3.1.0 http://python.egenix.com/ 2010-09-15 <http://python.egenix.com/%0A2010-09-15>: DZUG Tagung, Dresden, Germany 6 days to go
::: Try our new mxODBC.Connect Python Database Interface for free ! ::::
eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/ _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas

Michael Foord wrote:
On 9 September 2010 14:32, M.-A. Lemburg <mal@egenix.com> wrote:
[snip...] Why do you need to put everything on one line ?
afh = open(args.actual, encoding="utf-8") efh = open(args.expected, encoding="utf-8")
with afh, efh: ...
In the context of files, the only purpose of the with statement is to close them when leaving the block.
a = open('/etc/passwd') b = open('/etc/group')
If my understanding is correct (which is perhaps unlikely...), using a single line will close a if opening b fails. Whereas doing them separately before the with statement risks leaving the first un-exited if creating the second fails.
Right, but if you stuff everything on a single line, your error handling will have a hard time figuring out which of the two failed to open. I was under the impression that Mark wanted to "protect" the inner block of the with statement, not the context manager creation itself. As usual: hiding away too much stuff in your closet makes things look tidy, but causes a hell of a mess if you ever need to open it again :-)
Michael
with a,b: print a.readline(), b.readline() ... at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash at:!:25:
a <closed file '/etc/passwd', mode 'r' at 0x7f0093e62390> b <closed file '/etc/group', mode 'r' at 0x7f0093e62420>
-- Marc-Andre Lemburg eGenix.com
Professional Python Services directly from the Source (#1, Sep 09 2010)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
2010-08-19: Released mxODBC 3.1.0 http://python.egenix.com/ 2010-09-15 <http://python.egenix.com/%0A2010-09-15>: DZUG Tagung, Dresden, Germany 6 days to go
::: Try our new mxODBC.Connect Python Database Interface for free ! ::::
eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/ _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Source (#1, Sep 09 2010)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
2010-08-19: Released mxODBC 3.1.0 http://python.egenix.com/ 2010-09-15: DZUG Tagung, Dresden, Germany 6 days to go ::: Try our new mxODBC.Connect Python Database Interface for free ! :::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/

On Thu, 09 Sep 2010 15:53:49 +0200 "M.-A. Lemburg" <mal@egenix.com> wrote:
Michael Foord wrote:
On 9 September 2010 14:32, M.-A. Lemburg <mal@egenix.com> wrote:
[snip...] Why do you need to put everything on one line ?
afh = open(args.actual, encoding="utf-8") efh = open(args.expected, encoding="utf-8")
with afh, efh: ...
In the context of files, the only purpose of the with statement is to close them when leaving the block.
a = open('/etc/passwd') b = open('/etc/group')
If my understanding is correct (which is perhaps unlikely...), using a single line will close a if opening b fails. Whereas doing them separately before the with statement risks leaving the first un-exited if creating the second fails.
Right, but if you stuff everything on a single line, your error handling will have a hard time figuring out which of the two failed to open.
I was under the impression that Mark wanted to "protect" the inner block of the with statement, not the context manager creation itself.
Actually, I was more interested in the aesthetics. I've become habituated to _never_ using \ continuations and found it unsightly to need one here.
As usual: hiding away too much stuff in your closet makes things look tidy, but causes a hell of a mess if you ever need to open it again :-)
:-)
Michael
with a,b: print a.readline(), b.readline() ... at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash at:!:25:
a <closed file '/etc/passwd', mode 'r' at 0x7f0093e62390> b <closed file '/etc/group', mode 'r' at 0x7f0093e62420>
-- Marc-Andre Lemburg eGenix.com
Professional Python Services directly from the Source (#1, Sep 09 2010)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
2010-08-19: Released mxODBC 3.1.0 http://python.egenix.com/ 2010-09-15 <http://python.egenix.com/%0A2010-09-15>: DZUG Tagung, Dresden, Germany 6 days to go
::: Try our new mxODBC.Connect Python Database Interface for free ! ::::
eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/ _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- Mark Summerfield, Qtrac Ltd, www.qtrac.eu C++, Python, Qt, PyQt - training and consultancy "Programming in Python 3" - ISBN 0321680561 http://www.qtrac.eu/py3book.html

On 9 September 2010 14:53, M.-A. Lemburg <mal@egenix.com> wrote:
On 9 September 2010 14:32, M.-A. Lemburg <mal@egenix.com> wrote:
[snip...] Why do you need to put everything on one line ?
afh = open(args.actual, encoding="utf-8") efh = open(args.expected, encoding="utf-8")
with afh, efh: ...
In the context of files, the only purpose of the with statement is to close them when leaving the block.
a = open('/etc/passwd') b = open('/etc/group')
If my understanding is correct (which is perhaps unlikely...), using a single line will close a if opening b fails. Whereas doing them separately before the with statement risks leaving the first un-exited if creating
Michael Foord wrote: the
second fails.
Right, but if you stuff everything on a single line, your error handling will have a hard time figuring out which of the two failed to open.
If you *need* to distinguish at a higher level then you have no choice. I was really just pointing out that there are *semantic* differences as well, and in fact the code you posted is less safe than the one line version. You lose some of the error handling built-in to context manager creation. Michael
I was under the impression that Mark wanted to "protect" the inner block of the with statement, not the context manager creation itself.
As usual: hiding away too much stuff in your closet makes things look tidy, but causes a hell of a mess if you ever need to open it again :-)
Michael
with a,b: print a.readline(), b.readline() ... at:x:25:25:Batch jobs daemon:/var/spool/atjobs:/bin/bash at:!:25:
a <closed file '/etc/passwd', mode 'r' at 0x7f0093e62390> b <closed file '/etc/group', mode 'r' at 0x7f0093e62420>
-- Marc-Andre Lemburg eGenix.com
Professional Python Services directly from the Source (#1, Sep 09 2010)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
2010-08-19: Released mxODBC 3.1.0 http://python.egenix.com/ 2010-09-15 <http://python.egenix.com/%0A2010-09-15>: DZUG Tagung, Dresden, Germany 6 days to go
::: Try our new mxODBC.Connect Python Database Interface for free ! ::::
eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/ _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
-- Marc-Andre Lemburg eGenix.com
Professional Python Services directly from the Source (#1, Sep 09 2010)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
2010-08-19: Released mxODBC 3.1.0 http://python.egenix.com/ 2010-09-15 <http://python.egenix.com/%0A2010-09-15>: DZUG Tagung, Dresden, Germany 6 days to go
::: Try our new mxODBC.Connect Python Database Interface for free ! ::::
eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/ _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
participants (15)
-
Andy Buckley
-
Ben Finney
-
Georg Brandl
-
Greg Ewing
-
Gregory P. Smith
-
M.-A. Lemburg
-
Mark Summerfield
-
Mathias Panzenböck
-
Michael Foord
-
Mike Graham
-
Mike Meyer
-
MRAB
-
Nathan Schneider
-
Nick Coghlan
-
Terry Reedy