with file(name, 'w') as f:
do_something(f)
does not close the file at the end of the with statement! On the
contrary
with open(name, 'w') as f:
do_something(f)
works fine. The docs say "When opening a file, it’s preferable to use
open() instead of invoking this constructor directly." but perhaps
they should mention why :(
Are you sure?
Python 2.6.4 (r264:75706, Nov 2 2009, 14:44:17)
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> with file("tmp.txt", "w") as f:
... print >> f, "whatever"
...
>>> f.write("something")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file
Peter
Are you sure? For me on python2.5, it works as advertised:
from __future__ import with_statement
def test(outf):
with outf:
outf.write("test\n")
try:
outf.write("test\n")
assert False, "Not closed"
except ValueError:
pass
outf = open("/tmp/foo", "w")
test(outf)
outf = file("/tmp/bar", "w")
test(outf)
Which Python do you use?
Diez
Python 2.5, but it could be an artifact of the way I am looking if a
file is closed.
I have subclassed the file builtin, added a .close method and it was
not called by the
"with" statement. This during debugging, but now I have found another
reason to explain why I was
running out of file descriptors, (I was opening too many connections
to the db).
It is entirely possible that the problem was not with the "with"
statement.
> On Dec 10, 11:04 am, "Diez B. Roggisch" <de...@nospam.web.de> wrote:
>> Are you sure? For me on python2.5, it works as advertised:
>>
>> from __future__ import with_statement
>>
>> def test(outf):
>> with outf:
>> outf.write("test\n")
>> try:
>> outf.write("test\n")
>> assert False, "Not closed"
>> except ValueError:
>> pass
>>
>> outf = open("/tmp/foo", "w")
>> test(outf)
>> outf = file("/tmp/bar", "w")
>> test(outf)
>>
>> Which Python do you use?
>>
>> Diez
>
> Python 2.5, but it could be an artifact of the way I am looking if a
> file is closed.
The above ran on python2.5 for me, no hitch.
> I have subclassed the file builtin, added a .close method and it was
> not called by the
> "with" statement. This during debugging, but now I have found another
> reason to explain why I was
> running out of file descriptors, (I was opening too many connections
> to the db).
> It is entirely possible that the problem was not with the "with"
> statement.
Probably. Closing a file through with might not involve calling close() - it
might be implemented differently in __exit__.
So overload *that*, too.
Diez
Subclassing file doesn't work properly:
http://mail.python.org/pipermail/python-list/2005-April/920562.html
Peter
In Python 2.5 you have to implement your own __enter__ and __exit__
methods if you subclass from file. The file.__exit__ function doesn't
call f.close(). The minor inconsistency has been fixed in Python 2.6.
Python 2.5:
static PyObject *
file_exit(PyFileObject *f, PyObject *args)
{
PyObject *ret = file_close(f);
if (!ret)
/* If error occurred, pass through */
return NULL;
Py_DECREF(ret);
/* We cannot return the result of close since a true
* value will be interpreted as "yes, swallow the
* exception if one was raised inside the with block". */
Py_RETURN_NONE;
}
Python 2.6:
static PyObject *
file_exit(PyObject *f, PyObject *args)
{
PyObject *ret = PyObject_CallMethod(f, "close", NULL);
if (!ret)
/* If error occurred, pass through */
return NULL;
Py_DECREF(ret);
/* We cannot return the result of close since a true
* value will be interpreted as "yes, swallow the
* exception if one was raised inside the with block". */
Py_RETURN_NONE;
}
Yes, that was my problem.