diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 84e28986c31599..675afb65a1f7da 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -1092,6 +1092,13 @@ Text I/O The return value of :meth:`!tell` can be given as input to :meth:`seek`, to restore a previous stream position. + Example usage:: + + # decoding newlines in universal newlines mode + >>> import io + >>> io.TextIOWrapper(io.BytesIO(b'1\r\n2\r3\n4')).read() + '1\n2\n3\n4' + .. class:: StringIO(initial_value='', newline='\n') @@ -1139,15 +1146,53 @@ Text I/O # .getvalue() will now raise an exception. output.close() + # decoding newlines in universal newlines mode + io.StringIO('1\r\n2\r3\n4', newline=None).getvalue() + # '1\n2\n3\n4' + .. index:: single: universal newlines; io.IncrementalNewlineDecoder class -.. class:: IncrementalNewlineDecoder +.. class:: IncrementalNewlineDecoder(decoder, translate, errors='strict') A helper codec that decodes newlines for :term:`universal newlines` mode. - It inherits from :class:`codecs.IncrementalDecoder`. + It inherits from :class:`codecs.IncrementalDecoder`. It also records the types + of newlines encountered. When used with ``translate=False``, it ensures + that the newline sequence is returned in one piece. If an incremental + decoder is not required, :class:`TextIOWrapper` or :class:`StringIO` + should be used. + + *decoder* is an incremental decoder or ``None``. If set to ``None`` it + decodes strings. + + If *translate* is set to true, translate ``'\r\n'`` and ``'\r'`` into + ``'\n'``. + + The *errors* argument works like that of + :class:`codecs.IncrementalDecoder`. + + .. attribute:: newlines + + a tuple of types of newlines encountered, or the newline if only + one type of newline is found. The possible values are + ``None``, ``'\n'``, ``'\r'``, ``('\r', '\n')``, ``'\r\n'``, + ``('\n', '\r\n')``, ``('\r', '\r\n')`` and + ``('\r', '\n', '\r\n')``. + + + Example usage:: + >>> import codecs + >>> import io + >>> idec = codecs.getincrementaldecoder("utf-8")() + >>> inld = io.IncrementalNewlineDecoder(idec, translate=True) + >>> inld.decode(b'1\r') + '1' + >>> inld.decode(b'\n2\n') + '\n2\n' + >>> inld.decode(b'3\r', final=True) + '3\n' Static Typing ------------- diff --git a/Misc/NEWS.d/next/Documentation/2025-10-31-15-03-52.gh-issue-90367.mvD8JX.rst b/Misc/NEWS.d/next/Documentation/2025-10-31-15-03-52.gh-issue-90367.mvD8JX.rst new file mode 100644 index 00000000000000..17cec7be297bd8 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2025-10-31-15-03-52.gh-issue-90367.mvD8JX.rst @@ -0,0 +1 @@ +Added documentation for various ways to decode newlines in :mod:`io`