Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
2c9aa5ea
Commit
2c9aa5ea
authored
Sep 23, 2001
by
Tim Peters
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Generalize file.writelines() to allow iterable objects.
parent
d31db7e9
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
91 additions
and
35 deletions
+91
-35
Doc/lib/libstdtypes.tex
Doc/lib/libstdtypes.tex
+4
-2
Lib/test/test_iter.py
Lib/test/test_iter.py
+53
-0
Misc/NEWS
Misc/NEWS
+2
-0
Objects/fileobject.c
Objects/fileobject.c
+31
-31
Tools/scripts/ndiff.py
Tools/scripts/ndiff.py
+1
-2
No files found.
Doc/lib/libstdtypes.tex
View file @
2c9aa5ea
...
@@ -1312,8 +1312,10 @@ Files have the following methods:
...
@@ -1312,8 +1312,10 @@ Files have the following methods:
the
\method
{
flush()
}
or
\method
{
close()
}
method is called.
the
\method
{
flush()
}
or
\method
{
close()
}
method is called.
\end{methoddesc}
\end{methoddesc}
\begin{methoddesc}
[file]
{
writelines
}{
list
}
\begin{methoddesc}
[file]
{
writelines
}{
sequence
}
Write a list of strings to the file. There is no return value.
Write a sequence of strings to the file. The sequence can be any
iterable object producing strings, typically a list of strings.
There is no return value.
(The name is intended to match
\method
{
readlines()
}
;
(The name is intended to match
\method
{
readlines()
}
;
\method
{
writelines()
}
does not add line separators.)
\method
{
writelines()
}
does not add line separators.)
\end{methoddesc}
\end{methoddesc}
...
...
Lib/test/test_iter.py
View file @
2c9aa5ea
...
@@ -641,6 +641,59 @@ class TestCase(unittest.TestCase):
...
@@ -641,6 +641,59 @@ class TestCase(unittest.TestCase):
self
.
assertEqual
(
indexOf
(
iclass
,
i
),
i
)
self
.
assertEqual
(
indexOf
(
iclass
,
i
),
i
)
self
.
assertRaises
(
ValueError
,
indexOf
,
iclass
,
-
1
)
self
.
assertRaises
(
ValueError
,
indexOf
,
iclass
,
-
1
)
# Test iterators with file.writelines().
def
test_writelines
(
self
):
f
=
file
(
TESTFN
,
"w"
)
try
:
self
.
assertRaises
(
TypeError
,
f
.
writelines
,
None
)
self
.
assertRaises
(
TypeError
,
f
.
writelines
,
42
)
f
.
writelines
([
"1
\
n
"
,
"2
\
n
"
])
f
.
writelines
((
"3
\
n
"
,
"4
\
n
"
))
f
.
writelines
({
'5
\
n
'
:
None
})
f
.
writelines
({})
# Try a big chunk too.
class
Iterator
:
def
__init__
(
self
,
start
,
finish
):
self
.
start
=
start
self
.
finish
=
finish
self
.
i
=
self
.
start
def
next
(
self
):
if
self
.
i
>=
self
.
finish
:
raise
StopIteration
result
=
str
(
self
.
i
)
+
'
\
n
'
self
.
i
+=
1
return
result
def
__iter__
(
self
):
return
self
class
Whatever
:
def
__init__
(
self
,
start
,
finish
):
self
.
start
=
start
self
.
finish
=
finish
def
__iter__
(
self
):
return
Iterator
(
self
.
start
,
self
.
finish
)
f
.
writelines
(
Whatever
(
6
,
6
+
2000
))
f
.
close
()
f
=
file
(
TESTFN
)
expected
=
[
str
(
i
)
+
"
\
n
"
for
i
in
range
(
1
,
2006
)]
self
.
assertEqual
(
list
(
f
),
expected
)
finally
:
f
.
close
()
try
:
unlink
(
TESTFN
)
except
OSError
:
pass
# Test iterators on RHS of unpacking assignments.
# Test iterators on RHS of unpacking assignments.
def
test_unpack_iter
(
self
):
def
test_unpack_iter
(
self
):
a
,
b
=
1
,
2
a
,
b
=
1
,
2
...
...
Misc/NEWS
View file @
2c9aa5ea
...
@@ -3,6 +3,8 @@ What's New in Python 2.2a4?
...
@@ -3,6 +3,8 @@ What's New in Python 2.2a4?
Core
Core
- file.writelines() now accepts any iterable object producing strings.
- PyUnicode_FromEncodedObject() now works very much like
- PyUnicode_FromEncodedObject() now works very much like
PyObject_Str(obj) in that it tries to use __str__/tp_str
PyObject_Str(obj) in that it tries to use __str__/tp_str
on the object if the object is not a string or buffer. This
on the object if the object is not a string or buffer. This
...
...
Objects/fileobject.c
View file @
2c9aa5ea
...
@@ -1164,55 +1164,54 @@ file_write(PyFileObject *f, PyObject *args)
...
@@ -1164,55 +1164,54 @@ file_write(PyFileObject *f, PyObject *args)
}
}
static
PyObject
*
static
PyObject
*
file_writelines
(
PyFileObject
*
f
,
PyObject
*
args
)
file_writelines
(
PyFileObject
*
f
,
PyObject
*
seq
)
{
{
#define CHUNKSIZE 1000
#define CHUNKSIZE 1000
PyObject
*
list
,
*
line
;
PyObject
*
list
,
*
line
;
PyObject
*
it
;
/* iter(seq) */
PyObject
*
result
;
PyObject
*
result
;
int
i
,
j
,
index
,
len
,
nwritten
,
islist
;
int
i
,
j
,
index
,
len
,
nwritten
,
islist
;
assert
(
seq
!=
NULL
);
if
(
f
->
f_fp
==
NULL
)
if
(
f
->
f_fp
==
NULL
)
return
err_closed
();
return
err_closed
();
if
(
args
==
NULL
||
!
PySequence_Check
(
args
))
{
PyErr_SetString
(
PyExc_TypeError
,
"writelines() argument must be a sequence of strings"
);
return
NULL
;
}
islist
=
PyList_Check
(
args
);
/* Strategy: slurp CHUNKSIZE lines into a private list,
result
=
NULL
;
checking that they are all strings, then write that list
list
=
NULL
;
without holding the interpreter lock, then come back for more. */
islist
=
PyList_Check
(
seq
);
index
=
0
;
if
(
islist
)
if
(
islist
)
it
=
NULL
;
list
=
NULL
;
else
{
else
{
it
=
PyObject_GetIter
(
seq
);
if
(
it
==
NULL
)
{
PyErr_SetString
(
PyExc_TypeError
,
"writelines() requires an iterable argument"
);
return
NULL
;
}
/* From here on, fail by going to error, to reclaim "it". */
list
=
PyList_New
(
CHUNKSIZE
);
list
=
PyList_New
(
CHUNKSIZE
);
if
(
list
==
NULL
)
if
(
list
==
NULL
)
return
NULL
;
goto
error
;
}
}
result
=
NULL
;
for
(;;)
{
/* Strategy: slurp CHUNKSIZE lines into a private list,
checking that they are all strings, then write that list
without holding the interpreter lock, then come back for more. */
for
(
index
=
0
;
;
index
+=
CHUNKSIZE
)
{
if
(
islist
)
{
if
(
islist
)
{
Py_XDECREF
(
list
);
Py_XDECREF
(
list
);
list
=
PyList_GetSlice
(
args
,
index
,
index
+
CHUNKSIZE
);
list
=
PyList_GetSlice
(
seq
,
index
,
index
+
CHUNKSIZE
);
if
(
list
==
NULL
)
if
(
list
==
NULL
)
return
NULL
;
goto
error
;
j
=
PyList_GET_SIZE
(
list
);
j
=
PyList_GET_SIZE
(
list
);
}
}
else
{
else
{
for
(
j
=
0
;
j
<
CHUNKSIZE
;
j
++
)
{
for
(
j
=
0
;
j
<
CHUNKSIZE
;
j
++
)
{
line
=
Py
Sequence_GetItem
(
args
,
index
+
j
);
line
=
Py
Iter_Next
(
it
);
if
(
line
==
NULL
)
{
if
(
line
==
NULL
)
{
if
(
PyErr_ExceptionMatches
(
if
(
PyErr_Occurred
())
PyExc_IndexError
))
{
goto
error
;
PyErr_Clear
();
break
;
break
;
}
/* Some other error occurred.
XXX We may lose some output. */
goto
error
;
}
}
PyList_SetItem
(
list
,
j
,
line
);
PyList_SetItem
(
list
,
j
,
line
);
}
}
...
@@ -1271,14 +1270,15 @@ file_writelines(PyFileObject *f, PyObject *args)
...
@@ -1271,14 +1270,15 @@ file_writelines(PyFileObject *f, PyObject *args)
if
(
j
<
CHUNKSIZE
)
if
(
j
<
CHUNKSIZE
)
break
;
break
;
index
+=
CHUNKSIZE
;
}
}
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
result
=
Py_None
;
result
=
Py_None
;
error:
error:
Py_XDECREF
(
list
);
Py_XDECREF
(
list
);
Py_XDECREF
(
it
);
return
result
;
return
result
;
#undef CHUNKSIZE
}
}
static
char
readline_doc
[]
=
static
char
readline_doc
[]
=
...
@@ -1342,10 +1342,10 @@ static char xreadlines_doc[] =
...
@@ -1342,10 +1342,10 @@ static char xreadlines_doc[] =
"often quicker, due to reading ahead internally."
;
"often quicker, due to reading ahead internally."
;
static
char
writelines_doc
[]
=
static
char
writelines_doc
[]
=
"writelines(
list of
strings) -> None. Write the strings to the file.
\n
"
"writelines(
sequence_of_
strings) -> None. Write the strings to the file.
\n
"
"
\n
"
"
\n
"
"Note that newlines are not added. Th
is is equivalent to calling write()
\n
"
"Note that newlines are not added. Th
e sequence can be any iterable object
\n
"
"
for each string in the list
."
;
"
producing strings. This is equivalent to calling write() for each string
."
;
static
char
flush_doc
[]
=
static
char
flush_doc
[]
=
"flush() -> None. Flush the internal I/O buffer."
;
"flush() -> None. Flush the internal I/O buffer."
;
...
...
Tools/scripts/ndiff.py
View file @
2c9aa5ea
...
@@ -118,8 +118,7 @@ def main(args):
...
@@ -118,8 +118,7 @@ def main(args):
def
restore
(
which
):
def
restore
(
which
):
restored
=
difflib
.
restore
(
sys
.
stdin
.
readlines
(),
which
)
restored
=
difflib
.
restore
(
sys
.
stdin
.
readlines
(),
which
)
for
line
in
restored
:
sys
.
stdout
.
writelines
(
restored
)
print
line
,
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
args
=
sys
.
argv
[
1
:]
args
=
sys
.
argv
[
1
:]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment