[pypy-svn] pypy default: file.writelines() should release the stream lock between two lines
amauryfa
commits-noreply at bitbucket.org
Thu Feb 10 17:10:59 CET 2011
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch:
Changeset: r41789:f95db44eb35a
Date: 2011-02-10 15:45 +0100
http://bitbucket.org/pypy/pypy/changeset/f95db44eb35a/
Log: file.writelines() should release the stream lock between two lines
diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py
--- a/pypy/module/_file/interp_file.py
+++ b/pypy/module/_file/interp_file.py
@@ -216,20 +216,6 @@
self.softspace = 0
self.getstream().write(data)
- def direct_writelines(self, w_lines): # note: a wrapped list!
- stream = self.getstream()
- space = self.space
- w_iterator = space.iter(w_lines)
- self.softspace = 0
- while True:
- try:
- w_line = space.next(w_iterator)
- except OperationError, e:
- if not e.match(space, space.w_StopIteration):
- raise
- break # done
- stream.write(space.str_w(w_line))
-
def direct___iter__(self):
self.getstream()
return self
@@ -374,12 +360,6 @@
Note that due to buffering, flush() or close() may be needed before
the file on disk reflects the data written.""")
- _decl(locals(), "writelines", ['self', W_Root],
- """writelines(sequence_of_strings) -> None. Write the strings to the file.
-
-Note that newlines are not added. The sequence can be any iterable object
-producing strings. This is equivalent to calling write() for each string.""")
-
_decl(locals(), "__iter__", ['self'],
"""Iterating over files, as in 'for line in f:', returns each line of
the file one by one.""")
@@ -412,6 +392,24 @@
else:
return self.space.str_w(self.space.repr(w_name))
+ def file_writelines(self, w_lines):
+ """writelines(sequence_of_strings) -> None. Write the strings to the file.
+
+Note that newlines are not added. The sequence can be any iterable object
+producing strings. This is equivalent to calling write() for each string."""
+
+ space = self.space
+ w_iterator = space.iter(w_lines)
+ while True:
+ try:
+ w_line = space.next(w_iterator)
+ except OperationError, e:
+ if not e.match(space, space.w_StopIteration):
+ raise
+ break # done
+ self.file_write(space.str_w(w_line))
+ file_writelines.unwrap_spec = ['self', W_Root]
+
def file_readinto(self, w_rwbuffer):
"""readinto() -> Undocumented. Don't use this; it may go away."""
# XXX not the most efficient solution as it doesn't avoid the copying
@@ -509,6 +507,7 @@
doc="Support for 'print'."),
__repr__ = interp2app(W_File.file__repr__),
readinto = interp2app(W_File.file_readinto),
+ writelines = interp2app(W_File.file_writelines),
__weakref__ = make_weakref_descr(W_File),
**dict([(name, interp2app(getattr(W_File, 'file_' + name)))
for name in W_File._exposed_method_names])
diff --git a/pypy/module/_file/test/test_file_extra.py b/pypy/module/_file/test/test_file_extra.py
--- a/pypy/module/_file/test/test_file_extra.py
+++ b/pypy/module/_file/test/test_file_extra.py
@@ -382,6 +382,20 @@
assert len(somelines) > 200
assert somelines == lines[:len(somelines)]
+ def test_nasty_writelines(self):
+ # The stream lock should be released between writes
+ fn = self.temptestfile
+ f = file(fn, 'w')
+ def nasty():
+ for i in range(5):
+ if i == 3:
+ # should not raise because of acquired lock
+ f.close()
+ yield str(i)
+ exc = raises(ValueError, f.writelines, nasty())
+ assert exc.value.message == "I/O operation on closed file"
+ f.close()
+
def test_rw_bin(self):
import random
flags = 'w+b'
More information about the Pypy-commit
mailing list