Skip to content

Commit a1ed4b2

Browse files
authored
DEPR: line_terminator->lineterminator GH#9569 (#45302)
1 parent ba24738 commit a1ed4b2

File tree

10 files changed

+42
-30
lines changed

10 files changed

+42
-30
lines changed

doc/source/user_guide/io.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1851,7 +1851,7 @@ function takes a number of arguments. Only the first is required.
18511851
* ``mode`` : Python write mode, default 'w'
18521852
* ``encoding``: a string representing the encoding to use if the contents are
18531853
non-ASCII, for Python versions prior to 3
1854-
* ``line_terminator``: Character sequence denoting line end (default ``os.linesep``)
1854+
* ``lineterminator``: Character sequence denoting line end (default ``os.linesep``)
18551855
* ``quoting``: Set quoting rules as in csv module (default csv.QUOTE_MINIMAL). Note that if you have set a ``float_format`` then floats are converted to strings and csv.QUOTE_NONNUMERIC will treat them as non-numeric
18561856
* ``quotechar``: Character used to quote fields (default '"')
18571857
* ``doublequote``: Control quoting of ``quotechar`` in fields (default True)

doc/source/whatsnew/v1.5.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ Other API changes
9494

9595
Deprecations
9696
~~~~~~~~~~~~
97-
-
97+
- Deprecated the keyword ``line_terminator`` in :meth:`DataFrame.to_csv` and :meth:`Series.to_csv`, use ``lineterminator`` instead; this is for consistency with :func:`read_csv` and the standard library 'csv' module (:issue:`9568`)
9898
-
9999

100100
.. ---------------------------------------------------------------------------

pandas/_libs/src/parser/tokenizer.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ static int parser_buffer_bytes(parser_t *self, size_t nbytes,
649649
#define END_LINE() END_LINE_STATE(START_RECORD)
650650

651651
#define IS_TERMINATOR(c) \
652-
(c == line_terminator)
652+
(c == lineterminator)
653653

654654
#define IS_QUOTE(c) ((c == self->quotechar && self->quoting != QUOTE_NONE))
655655

@@ -718,7 +718,7 @@ int tokenize_bytes(parser_t *self,
718718
char *stream;
719719
char *buf = self->data + self->datapos;
720720

721-
const char line_terminator = (self->lineterminator == '\0') ?
721+
const char lineterminator = (self->lineterminator == '\0') ?
722722
'\n' : self->lineterminator;
723723

724724
// 1000 is something that couldn't fit in "char"

pandas/core/generic.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
InvalidIndexError,
6868
)
6969
from pandas.util._decorators import (
70+
deprecate_kwarg,
7071
doc,
7172
rewrite_axis_style_signature,
7273
)
@@ -3355,6 +3356,7 @@ def to_latex(
33553356
storage_options=_shared_docs["storage_options"],
33563357
compression_options=_shared_docs["compression_options"],
33573358
)
3359+
@deprecate_kwarg(old_arg_name="line_terminator", new_arg_name="lineterminator")
33583360
def to_csv(
33593361
self,
33603362
path_or_buf: FilePath | WriteBuffer[bytes] | WriteBuffer[str] | None = None,
@@ -3370,7 +3372,7 @@ def to_csv(
33703372
compression: CompressionOptions = "infer",
33713373
quoting: int | None = None,
33723374
quotechar: str = '"',
3373-
line_terminator: str | None = None,
3375+
lineterminator: str | None = None,
33743376
chunksize: int | None = None,
33753377
date_format: str | None = None,
33763378
doublequote: bool_t = True,
@@ -3449,10 +3451,16 @@ def to_csv(
34493451
will treat them as non-numeric.
34503452
quotechar : str, default '\"'
34513453
String of length 1. Character used to quote fields.
3452-
line_terminator : str, optional
3454+
lineterminator : str, optional
34533455
The newline character or character sequence to use in the output
34543456
file. Defaults to `os.linesep`, which depends on the OS in which
34553457
this method is called ('\\n' for linux, '\\r\\n' for Windows, i.e.).
3458+
3459+
.. versionchanged:: 1.5.0
3460+
3461+
Previously was line_terminator, changed for consistency with
3462+
read_csv and the standard library 'csv' module.
3463+
34563464
chunksize : int or None
34573465
Rows to write at a time.
34583466
date_format : str, default None
@@ -3527,7 +3535,7 @@ def to_csv(
35273535

35283536
return DataFrameRenderer(formatter).to_csv(
35293537
path_or_buf,
3530-
line_terminator=line_terminator,
3538+
lineterminator=lineterminator,
35313539
sep=sep,
35323540
encoding=encoding,
35333541
errors=errors,

pandas/io/formats/csvs.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def __init__(
5959
errors: str = "strict",
6060
compression: CompressionOptions = "infer",
6161
quoting: int | None = None,
62-
line_terminator: str | None = "\n",
62+
lineterminator: str | None = "\n",
6363
chunksize: int | None = None,
6464
quotechar: str | None = '"',
6565
date_format: str | None = None,
@@ -84,7 +84,7 @@ def __init__(
8484
self.quotechar = self._initialize_quotechar(quotechar)
8585
self.doublequote = doublequote
8686
self.escapechar = escapechar
87-
self.line_terminator = line_terminator or os.linesep
87+
self.lineterminator = lineterminator or os.linesep
8888
self.date_format = date_format
8989
self.cols = self._initialize_columns(cols)
9090
self.chunksize = self._initialize_chunksize(chunksize)
@@ -250,7 +250,7 @@ def save(self) -> None:
250250
# Note: self.encoding is irrelevant here
251251
self.writer = csvlib.writer(
252252
handles.handle,
253-
lineterminator=self.line_terminator,
253+
lineterminator=self.lineterminator,
254254
delimiter=self.sep,
255255
quoting=self.quoting,
256256
doublequote=self.doublequote,

pandas/io/formats/format.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
StorageOptions,
5858
WriteBuffer,
5959
)
60+
from pandas.util._decorators import deprecate_kwarg
6061

6162
from pandas.core.dtypes.common import (
6263
is_categorical_dtype,
@@ -1128,6 +1129,7 @@ def to_string(
11281129
string = string_formatter.to_string()
11291130
return save_to_buffer(string, buf=buf, encoding=encoding)
11301131

1132+
@deprecate_kwarg(old_arg_name="line_terminator", new_arg_name="lineterminator")
11311133
def to_csv(
11321134
self,
11331135
path_or_buf: FilePath | WriteBuffer[bytes] | WriteBuffer[str] | None = None,
@@ -1139,7 +1141,7 @@ def to_csv(
11391141
compression: CompressionOptions = "infer",
11401142
quoting: int | None = None,
11411143
quotechar: str = '"',
1142-
line_terminator: str | None = None,
1144+
lineterminator: str | None = None,
11431145
chunksize: int | None = None,
11441146
date_format: str | None = None,
11451147
doublequote: bool = True,
@@ -1160,7 +1162,7 @@ def to_csv(
11601162

11611163
csv_formatter = CSVFormatter(
11621164
path_or_buf=path_or_buf,
1163-
line_terminator=line_terminator,
1165+
lineterminator=lineterminator,
11641166
sep=sep,
11651167
encoding=encoding,
11661168
errors=errors,

pandas/tests/frame/methods/test_to_csv.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -866,21 +866,21 @@ def test_to_csv_index_no_leading_comma(self):
866866
expected = tm.convert_rows_list_to_csv_str(expected_rows)
867867
assert buf.getvalue() == expected
868868

869-
def test_to_csv_line_terminators(self):
869+
def test_to_csv_lineterminators(self):
870870
# see gh-20353
871871
df = DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}, index=["one", "two", "three"])
872872

873873
with tm.ensure_clean() as path:
874874
# case 1: CRLF as line terminator
875-
df.to_csv(path, line_terminator="\r\n")
875+
df.to_csv(path, lineterminator="\r\n")
876876
expected = b",A,B\r\none,1,4\r\ntwo,2,5\r\nthree,3,6\r\n"
877877

878878
with open(path, mode="rb") as f:
879879
assert f.read() == expected
880880

881881
with tm.ensure_clean() as path:
882882
# case 2: LF as line terminator
883-
df.to_csv(path, line_terminator="\n")
883+
df.to_csv(path, lineterminator="\n")
884884
expected = b",A,B\none,1,4\ntwo,2,5\nthree,3,6\n"
885885

886886
with open(path, mode="rb") as f:
@@ -1251,7 +1251,7 @@ def test_to_csv_single_level_multi_index(self):
12511251
df = DataFrame([[1, 2, 3]], columns=index)
12521252
df = df.reindex(columns=[(1,), (3,)])
12531253
expected = ",1,3\n0,1,3\n"
1254-
result = df.to_csv(line_terminator="\n")
1254+
result = df.to_csv(lineterminator="\n")
12551255
tm.assert_almost_equal(result, expected)
12561256

12571257
def test_gz_lineend(self):

pandas/tests/io/formats/test_to_csv.py

+11-9
Original file line numberDiff line numberDiff line change
@@ -369,9 +369,11 @@ def test_to_csv_multi_index(self):
369369
@pytest.mark.parametrize("klass", [DataFrame, pd.Series])
370370
def test_to_csv_single_level_multi_index(self, ind, expected, klass):
371371
# see gh-19589
372-
result = klass(pd.Series([1], ind, name="data")).to_csv(
373-
line_terminator="\n", header=True
374-
)
372+
obj = klass(pd.Series([1], ind, name="data"))
373+
374+
with tm.assert_produces_warning(FutureWarning, match="lineterminator"):
375+
# GH#9568 standardize on lineterminator matching stdlib
376+
result = obj.to_csv(line_terminator="\n", header=True)
375377
assert result == expected
376378

377379
def test_to_csv_string_array_ascii(self):
@@ -425,14 +427,14 @@ def test_to_csv_string_with_lf(self):
425427
with tm.ensure_clean("lf_test.csv") as path:
426428
# case 2: LF as line terminator
427429
expected_lf = b'int,str_lf\n1,abc\n2,"d\nef"\n3,"g\nh\n\ni"\n'
428-
df.to_csv(path, line_terminator="\n", index=False)
430+
df.to_csv(path, lineterminator="\n", index=False)
429431
with open(path, "rb") as f:
430432
assert f.read() == expected_lf
431433
with tm.ensure_clean("lf_test.csv") as path:
432434
# case 3: CRLF as line terminator
433-
# 'line_terminator' should not change inner element
435+
# 'lineterminator' should not change inner element
434436
expected_crlf = b'int,str_lf\r\n1,abc\r\n2,"d\nef"\r\n3,"g\nh\n\ni"\r\n'
435-
df.to_csv(path, line_terminator="\r\n", index=False)
437+
df.to_csv(path, lineterminator="\r\n", index=False)
436438
with open(path, "rb") as f:
437439
assert f.read() == expected_crlf
438440

@@ -459,19 +461,19 @@ def test_to_csv_string_with_crlf(self):
459461
with tm.ensure_clean("crlf_test.csv") as path:
460462
# case 2: LF as line terminator
461463
expected_lf = b'int,str_crlf\n1,abc\n2,"d\r\nef"\n3,"g\r\nh\r\n\r\ni"\n'
462-
df.to_csv(path, line_terminator="\n", index=False)
464+
df.to_csv(path, lineterminator="\n", index=False)
463465
with open(path, "rb") as f:
464466
assert f.read() == expected_lf
465467
with tm.ensure_clean("crlf_test.csv") as path:
466468
# case 3: CRLF as line terminator
467-
# 'line_terminator' should not change inner element
469+
# 'lineterminator' should not change inner element
468470
expected_crlf = (
469471
b"int,str_crlf\r\n"
470472
b"1,abc\r\n"
471473
b'2,"d\r\nef"\r\n'
472474
b'3,"g\r\nh\r\n\r\ni"\r\n'
473475
)
474-
df.to_csv(path, line_terminator="\r\n", index=False)
476+
df.to_csv(path, lineterminator="\r\n", index=False)
475477
with open(path, "rb") as f:
476478
assert f.read() == expected_crlf
477479

pandas/tests/io/parser/test_skiprows.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,9 @@ def test_skip_row_with_newline_and_quote(all_parsers, data, exp_data):
180180

181181

182182
@pytest.mark.parametrize(
183-
"line_terminator", ["\n", "\r\n", "\r"] # "LF" # "CRLF" # "CR"
183+
"lineterminator", ["\n", "\r\n", "\r"] # "LF" # "CRLF" # "CR"
184184
)
185-
def test_skiprows_lineterminator(all_parsers, line_terminator, request):
185+
def test_skiprows_lineterminator(all_parsers, lineterminator, request):
186186
# see gh-9079
187187
parser = all_parsers
188188
data = "\n".join(
@@ -202,11 +202,11 @@ def test_skiprows_lineterminator(all_parsers, line_terminator, request):
202202
columns=["date", "time", "var", "flag", "oflag"],
203203
)
204204

205-
if parser.engine == "python" and line_terminator == "\r":
205+
if parser.engine == "python" and lineterminator == "\r":
206206
mark = pytest.mark.xfail(reason="'CR' not respect with the Python parser yet")
207207
request.node.add_marker(mark)
208208

209-
data = data.replace("\n", line_terminator)
209+
data = data.replace("\n", lineterminator)
210210
result = parser.read_csv(
211211
StringIO(data),
212212
skiprows=1,

pandas/tests/io/xml/test_to_xml.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ def test_style_to_csv():
11601160
</xsl:template>
11611161
</xsl:stylesheet>"""
11621162

1163-
out_csv = geom_df.to_csv(line_terminator="\n")
1163+
out_csv = geom_df.to_csv(lineterminator="\n")
11641164

11651165
if out_csv is not None:
11661166
out_csv = out_csv.strip()

0 commit comments

Comments
 (0)