diff --git a/Doc/deprecations/pending-removal-in-3.16.rst b/Doc/deprecations/pending-removal-in-3.16.rst index a64212e38e61cb..0c0806b1a2f0ef 100644 --- a/Doc/deprecations/pending-removal-in-3.16.rst +++ b/Doc/deprecations/pending-removal-in-3.16.rst @@ -89,7 +89,7 @@ Pending removal in Python 3.16 * :mod:`sys`: - * The :func:`~sys._enablelegacywindowsfsencoding` function + * The :func:`!sys._enablelegacywindowsfsencoding` function has been deprecated since Python 3.13. Use the :envvar:`PYTHONLEGACYWINDOWSFSENCODING` environment variable instead. diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 6946eb6eeaa5fa..21de31383d425b 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -879,7 +879,7 @@ always available. Unless explicitly noted otherwise, all variables are read-only .. versionchanged:: 3.6 Windows is no longer guaranteed to return ``'mbcs'``. See :pep:`529` - and :func:`_enablelegacywindowsfsencoding` for more information. + for more information. .. versionchanged:: 3.7 Return ``'utf-8'`` if the :ref:`Python UTF-8 Mode ` is @@ -2107,31 +2107,6 @@ always available. Unless explicitly noted otherwise, all variables are read-only See :pep:`768` for more details. -.. function:: _enablelegacywindowsfsencoding() - - Changes the :term:`filesystem encoding and error handler` to 'mbcs' and - 'replace' respectively, for consistency with versions of Python prior to - 3.6. - - This is equivalent to defining the :envvar:`PYTHONLEGACYWINDOWSFSENCODING` - environment variable before launching Python. - - See also :func:`sys.getfilesystemencoding` and - :func:`sys.getfilesystemencodeerrors`. - - .. availability:: Windows. - - .. note:: - Changing the filesystem encoding after Python startup is risky because - the old fsencoding or paths encoded by the old fsencoding may be cached - somewhere. Use :envvar:`PYTHONLEGACYWINDOWSFSENCODING` instead. - - .. versionadded:: 3.6 - See :pep:`529` for more details. - - .. deprecated-removed:: 3.13 3.16 - Use :envvar:`PYTHONLEGACYWINDOWSFSENCODING` instead. - .. data:: stdin stdout stderr diff --git a/Doc/tools/removed-ids.txt b/Doc/tools/removed-ids.txt index adac1b993047bc..ebcd1874e24b3f 100644 --- a/Doc/tools/removed-ids.txt +++ b/Doc/tools/removed-ids.txt @@ -7,4 +7,5 @@ c-api/file.html: deprecated-api library/asyncio-task.html: terminating-a-task-group # Removed APIs -library/symtable.html: symtable.Class.get_methods \ No newline at end of file +library/symtable.html: symtable.Class.get_methods +library/sys.html: sys._enablelegacywindowsfsencoding \ No newline at end of file diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 59e8f4f9f5a3e4..c4a431a471a546 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -1154,9 +1154,6 @@ conflict. 'replace', respectively. Otherwise, the new defaults 'utf-8' and 'surrogatepass' are used. - This may also be enabled at runtime with - :func:`sys._enablelegacywindowsfsencoding`. - .. availability:: Windows. .. versionadded:: 3.6 diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index f4489bfa1b74e8..6a6aa2468943b4 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -1958,7 +1958,7 @@ New Deprecations * :mod:`sys`: - * Deprecate the :func:`~sys._enablelegacywindowsfsencoding` function, + * Deprecate the :func:`!sys._enablelegacywindowsfsencoding` function, to be removed in Python 3.16. Use the :envvar:`PYTHONLEGACYWINDOWSFSENCODING` environment variable instead. (Contributed by Inada Naoki in :gh:`73427`.) diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index d9beda92aba6a3..563c19f97b2cec 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -126,6 +126,14 @@ symtable * The :meth:`!symtable.Class.get_methods` method which has been deprecated since Python 3.14. +sys +--- + +* The :func:`!sys._enablelegacywindowsfsencoding` function + which has been deprecated since Python 3.13. + Use the :envvar:`PYTHONLEGACYWINDOWSFSENCODING` environment variable instead. + (Contributed by Stan Ulbrych in :gh:`149595`.) + sysconfig --------- diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index bdd35d39e36194..b0382dd8215bc0 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -517,7 +517,7 @@ Applications that do not use str to represent paths should use :func:`os.fsencode` and :func:`os.fsdecode` to ensure their bytes are correctly encoded. To revert to the previous behaviour, set :envvar:`PYTHONLEGACYWINDOWSFSENCODING` or call -:func:`sys._enablelegacywindowsfsencoding`. +:func:`!sys._enablelegacywindowsfsencoding`. See :pep:`529` for more information and discussion of code modifications that may be required. diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index 8faf7a4d403f84..12e1e78526db35 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -18,9 +18,6 @@ extern int _Py_SetFileSystemEncoding( const char *errors); extern void _Py_ClearFileSystemEncoding(void); extern PyStatus _PyUnicode_InitEncodings(PyThreadState *tstate); -#ifdef MS_WINDOWS -extern int _PyUnicode_EnableLegacyWindowsFSEncoding(void); -#endif extern int _Py_IsLocaleCoercionTarget(const char *ctype_loc); diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 3002fa528eab17..02c70403185f60 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1283,16 +1283,6 @@ def check(tracebacklimit, expected): def test_no_duplicates_in_meta_path(self): self.assertEqual(len(sys.meta_path), len(set(sys.meta_path))) - @unittest.skipUnless(hasattr(sys, "_enablelegacywindowsfsencoding"), - 'needs sys._enablelegacywindowsfsencoding()') - def test__enablelegacywindowsfsencoding(self): - code = ('import sys', - 'sys._enablelegacywindowsfsencoding()', - 'print(sys.getfilesystemencoding(), sys.getfilesystemencodeerrors())') - rc, out, err = assert_python_ok('-c', '; '.join(code)) - out = out.decode('ascii', 'replace').rstrip() - self.assertEqual(out, 'mbcs replace') - @support.requires_subprocess() def test_orig_argv(self): code = textwrap.dedent(''' diff --git a/Misc/NEWS.d/3.13.0a3.rst b/Misc/NEWS.d/3.13.0a3.rst index 0f8dee261c6589..3d3b414c9d46af 100644 --- a/Misc/NEWS.d/3.13.0a3.rst +++ b/Misc/NEWS.d/3.13.0a3.rst @@ -2166,7 +2166,7 @@ current user has no permission to the WMI. .. nonce: WOpiNt .. section: Windows -Deprecate :func:`sys._enablelegacywindowsfsencoding`. Use +Deprecate :func:`!sys._enablelegacywindowsfsencoding`. Use :envvar:`PYTHONLEGACYWINDOWSFSENCODING` instead. Patch by Inada Naoki. .. diff --git a/Misc/NEWS.d/next/Library/2026-05-09-11-22-29.gh-issue-149595.1nuYXw.rst b/Misc/NEWS.d/next/Library/2026-05-09-11-22-29.gh-issue-149595.1nuYXw.rst new file mode 100644 index 00000000000000..f3971554de3748 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-05-09-11-22-29.gh-issue-149595.1nuYXw.rst @@ -0,0 +1,2 @@ +Remove the :func:`!sys._enablelegacywindowsfsencoding` function which has +been deprecated since Python 3.13. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 5c97efd6838ef3..b92743a884a708 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -14928,33 +14928,6 @@ _PyUnicode_FiniEncodings(struct _Py_unicode_fs_codec *fs_codec) } -#ifdef MS_WINDOWS -int -_PyUnicode_EnableLegacyWindowsFSEncoding(void) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - PyConfig *config = (PyConfig *)_PyInterpreterState_GetConfig(interp); - - /* Set the filesystem encoding to mbcs/replace (PEP 529) */ - wchar_t *encoding = _PyMem_RawWcsdup(L"mbcs"); - wchar_t *errors = _PyMem_RawWcsdup(L"replace"); - if (encoding == NULL || errors == NULL) { - PyMem_RawFree(encoding); - PyMem_RawFree(errors); - PyErr_NoMemory(); - return -1; - } - - PyMem_RawFree(config->filesystem_encoding); - config->filesystem_encoding = encoding; - PyMem_RawFree(config->filesystem_errors); - config->filesystem_errors = errors; - - return init_fs_codec(interp); -} -#endif - - #ifdef Py_DEBUG static inline int unicode_is_finalizing(void) diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index 86e942ec2b8afb..6609a88c1a9d58 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -761,34 +761,6 @@ sys_getwindowsversion(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* defined(MS_WINDOWS) */ -#if defined(MS_WINDOWS) - -PyDoc_STRVAR(sys__enablelegacywindowsfsencoding__doc__, -"_enablelegacywindowsfsencoding($module, /)\n" -"--\n" -"\n" -"Changes the default filesystem encoding to mbcs:replace.\n" -"\n" -"This is done for consistency with earlier versions of Python. See PEP\n" -"529 for more information.\n" -"\n" -"This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING\n" -"environment variable before launching Python."); - -#define SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF \ - {"_enablelegacywindowsfsencoding", (PyCFunction)sys__enablelegacywindowsfsencoding, METH_NOARGS, sys__enablelegacywindowsfsencoding__doc__}, - -static PyObject * -sys__enablelegacywindowsfsencoding_impl(PyObject *module); - -static PyObject * -sys__enablelegacywindowsfsencoding(PyObject *module, PyObject *Py_UNUSED(ignored)) -{ - return sys__enablelegacywindowsfsencoding_impl(module); -} - -#endif /* defined(MS_WINDOWS) */ - #if defined(HAVE_DLOPEN) PyDoc_STRVAR(sys_setdlopenflags__doc__, @@ -2082,10 +2054,6 @@ _jit_is_active(PyObject *module, PyObject *Py_UNUSED(ignored)) #define SYS_GETWINDOWSVERSION_METHODDEF #endif /* !defined(SYS_GETWINDOWSVERSION_METHODDEF) */ -#ifndef SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF - #define SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF -#endif /* !defined(SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF) */ - #ifndef SYS_SETDLOPENFLAGS_METHODDEF #define SYS_SETDLOPENFLAGS_METHODDEF #endif /* !defined(SYS_SETDLOPENFLAGS_METHODDEF) */ @@ -2121,4 +2089,4 @@ _jit_is_active(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=e8333fe10c01ae66 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ba849b6e4b9f1ba3 input=a9049054013a1b77]*/ diff --git a/Python/sysmodule.c b/Python/sysmodule.c index c6447d03369a94..b75d9e864a18dc 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1790,36 +1790,6 @@ sys_getwindowsversion_impl(PyObject *module) } #pragma warning(pop) - -/*[clinic input] -sys._enablelegacywindowsfsencoding - -Changes the default filesystem encoding to mbcs:replace. - -This is done for consistency with earlier versions of Python. See PEP -529 for more information. - -This is equivalent to defining the PYTHONLEGACYWINDOWSFSENCODING -environment variable before launching Python. -[clinic start generated code]*/ - -static PyObject * -sys__enablelegacywindowsfsencoding_impl(PyObject *module) -/*[clinic end generated code: output=f5c3855b45e24fe9 input=2bfa931a20704492]*/ -{ - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "sys._enablelegacywindowsfsencoding() is deprecated and will be " - "removed in Python 3.16. Use PYTHONLEGACYWINDOWSFSENCODING " - "instead.", 1)) - { - return NULL; - } - if (_PyUnicode_EnableLegacyWindowsFSEncoding() < 0) { - return NULL; - } - Py_RETURN_NONE; -} - #endif /* MS_WINDOWS */ #ifdef HAVE_DLOPEN @@ -2941,7 +2911,6 @@ static PyMethodDef sys_methods[] = { SYS__GETFRAME_METHODDEF SYS__GETFRAMEMODULENAME_METHODDEF SYS_GETWINDOWSVERSION_METHODDEF - SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF SYS__IS_IMMORTAL_METHODDEF SYS_INTERN_METHODDEF SYS__IS_INTERNED_METHODDEF @@ -3436,13 +3405,6 @@ winver -- [Windows only] version number of the Python DLL\n\ " ) #endif /* MS_COREDLL */ -#ifdef MS_WINDOWS -/* concatenating string here */ -PyDoc_STR( -"_enablelegacywindowsfsencoding -- [Windows only]\n\ -" -) -#endif PyDoc_STR( "__stdin__ -- the original stdin; don't touch!\n\ __stdout__ -- the original stdout; don't touch!\n\