@@ -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
7590Backward 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.
8499So 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
98115Preceding examples
@@ -122,10 +139,31 @@ Additionally, such warnings are not useful for non-cross platform applications
122139run on Unix.
123140
124141So 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
126148Java 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+
129167How to teach this
130168=================
131169
0 commit comments