Skip to content

Commit 6ccd6bc

Browse files
authored
PEP 686: Update (#2470)
1 parent 4d8bc00 commit 6ccd6bc

File tree

1 file changed

+59
-21
lines changed

1 file changed

+59
-21
lines changed

pep-0686.rst

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,37 @@ Users can still disable UTF-8 mode by setting ``PYTHONUTF8=0`` or
5454
``-X utf8=0``.
5555

5656

57-
``locale.get_encoding()``
58-
-------------------------
57+
``locale.getencoding()``
58+
------------------------
5959

60-
Currently, ``TextIOWrapper`` uses ``locale.getpreferredencoding(False)``
61-
when ``encoding="locale"`` option is specified. It is ``"UTF-8"`` in UTF-8 mode.
60+
Since UTF-8 mode affects ``locale.getpreferredencoding(False)``,
61+
we need an API to get locale encoding regardless of UTF-8 mode.
6262

63-
This behavior is inconsistent with the :pep:`597` motivation.
64-
``TextIOWrapper`` should use locale encoding when ``encoding="locale"`` is
65-
passed before/after the default encoding is changed to UTF-8.
63+
``locale.getencoding()`` will be added for this purpose.
64+
It returns locale encoding too, but ignores UTF-8 mode.
65+
66+
When ``warn_default_encoding`` option is specified,
67+
``locale.getpreferredencoding()`` will emit ``EncodingWarning`` like
68+
``open()`` (see also :pep:`597`).
69+
70+
71+
Fixing ``encoding="locale"`` option
72+
-----------------------------------
6673

67-
To fix this inconsistency, we will add ``locale.get_encoding()``.
68-
It is the same as ``locale.getpreferredencoding(False)`` but it ignores
69-
the UTF-8 mode.
74+
:pep:`597` added the ``encoding="locale"`` option to the ``TextIOWrapper``.
75+
This option is used to specify the locale encoding explicitly.
76+
``TextIOWrapper`` should use locale encoding when the option is specified,
77+
regardless of default text encoding.
7078

71-
This change will be released in Python 3.11 so that users can use UTF-8 mode
72-
that is the same as Python 3.13.
79+
But ``TextIOWrapper`` uses ``"UTF-8"`` in UTF-8 mode even if
80+
``encoding="locale"`` is specified for now.
81+
This behavior is inconsistent with the :pep:`597` motivation.
82+
It is because we didn't expect making UTF-8 mode default when Python
83+
changes its default text encoding.
84+
85+
This inconsistency should be fixed before making UTF-8 mode default.
86+
``TextIOWrapper`` should use locale encoding when ``encoding="locale"`` is
87+
passed even in UTF-8 mode.
7388

7489

7590
Backward Compatibility
@@ -83,16 +98,18 @@ When a Python program depends on the default encoding, this change may cause
8398
``UnicodeError``, mojibake, or even silent data corruption.
8499
So this change should be announced loudly.
85100

86-
To resolve this backward incompatibility, users can do:
101+
This is the guideline to fix this backward compatibility issue:
102+
103+
1. Disable UTF-8 mode.
104+
2. Use ``EncodingWarning`` (:pep:`597`) to find every places UTF-8 mode
105+
affects.
106+
107+
* If ``encoding`` option is omitted, consider using ``encoding="utf-8"``
108+
or ``encoding="locale"``.
109+
* If ``locale.getpreferredencoding()`` is used, consider using
110+
``"utf-8"`` or ``locale.getencoding()``.
87111

88-
* Disable UTF-8 mode.
89-
* Use ``EncodingWarning`` to find where the default encoding is used and use
90-
``encoding="locale"`` option if locale encoding should be used
91-
(as defined in :pep:`597`).
92-
* Find every occurrence of ``locale.getpreferredencoding(False)`` in the
93-
application, and replace it with ``locale.get_locale_encoding()`` if
94-
locale encoding should be used.
95-
* Test the application with UTF-8 mode.
112+
3. Test the application with UTF-8 mode.
96113

97114

98115
Preceding examples
@@ -122,10 +139,31 @@ Additionally, such warnings are not useful for non-cross platform applications
122139
run on Unix.
123140

124141
So forcing users to specify the ``encoding`` everywhere is too painful.
142+
Emitting a lot of ``DeprecationWarning`` will lead users ignore warnings.
143+
144+
:pep:`387` requires adding a warning for backward incompatible changes.
145+
But it doesn't require using ``DeprecationWarning``.
146+
So using optional ``EncodingWarning`` doesn't violate the :pep:`387`.
125147

126148
Java also rejected this idea in `JEP 400`_.
127149

128150

151+
Use ``PYTHONIOENCODING`` for PIPEs
152+
----------------------------------
153+
154+
To ease backward compatibility issue, using ``PYTHONIOENCODING`` as the
155+
default encoding of PIPEs in the ``subprocess`` module is considered.
156+
157+
With this idea, users can use legacy encoding for
158+
``subprocess.Popen(text=True)`` even in UTF-8 mode.
159+
160+
But this idea makes "default encoding" complicated.
161+
And this idea is also backward incompatible.
162+
163+
So this idea is rejected. Users can disable UTF-8 mode until they replace
164+
``text=True`` with ``encoding="utf-8"`` or ``encoding="locale"``.
165+
166+
129167
How to teach this
130168
=================
131169

0 commit comments

Comments
 (0)