mirror of https://github.com/python/cpython
gh-91526: io: Remove device encoding support from TextIOWrapper (GH-91529)
`TextIOWrapper.__init__()` called `os.device_encoding(file.fileno())` if fileno is 0-2 and encoding=None. But it is very rarely works, and never documented behavior.
This commit is contained in:
parent
39a54ba638
commit
6fdb62b1fa
|
@ -2021,14 +2021,6 @@ class TextIOWrapper(TextIOBase):
|
|||
self._check_newline(newline)
|
||||
encoding = text_encoding(encoding)
|
||||
|
||||
if encoding == "locale" and sys.platform == "win32":
|
||||
# On Unix, os.device_encoding() returns "utf-8" instead of locale encoding
|
||||
# in the UTF-8 mode. So we use os.device_encoding() only on Windows.
|
||||
try:
|
||||
encoding = os.device_encoding(buffer.fileno()) or "locale"
|
||||
except (AttributeError, UnsupportedOperation):
|
||||
pass
|
||||
|
||||
if encoding == "locale":
|
||||
try:
|
||||
import locale
|
||||
|
|
|
@ -2736,18 +2736,6 @@ class TextIOWrapperTest(unittest.TestCase):
|
|||
os.environ.clear()
|
||||
os.environ.update(old_environ)
|
||||
|
||||
@support.cpython_only
|
||||
@unittest.skipIf(sys.platform != "win32", "Windows-only test")
|
||||
@unittest.skipIf(sys.flags.utf8_mode, "utf-8 mode is enabled")
|
||||
def test_device_encoding(self):
|
||||
# Issue 15989
|
||||
import _testcapi
|
||||
b = self.BytesIO()
|
||||
b.fileno = lambda: _testcapi.INT_MAX + 1
|
||||
self.assertRaises(OverflowError, self.TextIOWrapper, b, encoding="locale")
|
||||
b.fileno = lambda: _testcapi.UINT_MAX + 1
|
||||
self.assertRaises(OverflowError, self.TextIOWrapper, b, encoding="locale")
|
||||
|
||||
def test_encoding(self):
|
||||
# Check the encoding attribute is always set, and valid
|
||||
b = self.BytesIO()
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Stop calling ``os.device_encoding(file.fileno())`` in
|
||||
:class:`TextIOWrapper`. It was complex, never documented, and didn't work
|
||||
for most cases. (Patch by Inada Naoki.)
|
|
@ -1060,7 +1060,6 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
|
|||
PyObject *raw, *codec_info = NULL;
|
||||
PyObject *res;
|
||||
int r;
|
||||
int use_locale_encoding = 0; // Use locale encoding even in UTF-8 mode.
|
||||
|
||||
self->ok = 0;
|
||||
self->detached = 0;
|
||||
|
@ -1074,10 +1073,6 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (strcmp(encoding, "locale") == 0) {
|
||||
encoding = NULL;
|
||||
use_locale_encoding = 1;
|
||||
}
|
||||
|
||||
if (errors == Py_None) {
|
||||
errors = &_Py_ID(strict);
|
||||
|
@ -1114,57 +1109,18 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
|
|||
self->encodefunc = NULL;
|
||||
self->b2cratio = 0.0;
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
// os.device_encoding() on Unix is the locale encoding or UTF-8
|
||||
// according to UTF-8 Mode.
|
||||
// Since UTF-8 mode shouldn't affect `encoding="locale"`, we call
|
||||
// os.device_encoding() only on Windows.
|
||||
if (encoding == NULL) {
|
||||
/* Try os.device_encoding(fileno) */
|
||||
PyObject *fileno;
|
||||
_PyIO_State *state = IO_STATE();
|
||||
if (state == NULL)
|
||||
goto error;
|
||||
fileno = PyObject_CallMethodNoArgs(buffer, &_Py_ID(fileno));
|
||||
/* Ignore only AttributeError and UnsupportedOperation */
|
||||
if (fileno == NULL) {
|
||||
if (PyErr_ExceptionMatches(PyExc_AttributeError) ||
|
||||
PyErr_ExceptionMatches(state->unsupported_operation)) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
else {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int fd = _PyLong_AsInt(fileno);
|
||||
Py_DECREF(fileno);
|
||||
if (fd == -1 && PyErr_Occurred()) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
self->encoding = _Py_device_encoding(fd);
|
||||
if (self->encoding == NULL)
|
||||
goto error;
|
||||
else if (!PyUnicode_Check(self->encoding))
|
||||
Py_CLEAR(self->encoding);
|
||||
}
|
||||
if (encoding == NULL && _PyRuntime.preconfig.utf8_mode) {
|
||||
_Py_DECLARE_STR(utf_8, "utf-8");
|
||||
self->encoding = Py_NewRef(&_Py_STR(utf_8));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (encoding == NULL && self->encoding == NULL) {
|
||||
if (_PyRuntime.preconfig.utf8_mode && !use_locale_encoding) {
|
||||
_Py_DECLARE_STR(utf_8, "utf-8");
|
||||
self->encoding = Py_NewRef(&_Py_STR(utf_8));
|
||||
}
|
||||
else {
|
||||
self->encoding = _Py_GetLocaleEncodingObject();
|
||||
}
|
||||
else if (encoding == NULL || (strcmp(encoding, "locale") == 0)) {
|
||||
self->encoding = _Py_GetLocaleEncodingObject();
|
||||
if (self->encoding == NULL) {
|
||||
goto error;
|
||||
}
|
||||
assert(PyUnicode_Check(self->encoding));
|
||||
}
|
||||
|
||||
if (self->encoding != NULL) {
|
||||
encoding = PyUnicode_AsUTF8(self->encoding);
|
||||
if (encoding == NULL)
|
||||
|
|
Loading…
Reference in New Issue