cpython: Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
http://hg.python.org/cpython/rev/c80d9a0bd5a0 changeset: 75353:c80d9a0bd5a0 user: Brett Cannon <brett@python.org> date: Wed Feb 29 18:31:31 2012 -0500 summary: Issue #14153 Create _Py_device_encoding() to prevent _io from having to import the os module. files: Include/fileutils.h | 2 + Lib/test/test_os.py | 19 ++++++++++++++++ Modules/_io/_iomodule.c | 14 ++--------- Modules/_io/_iomodule.h | 5 +-- Modules/_io/textio.c | 11 +++++--- Modules/posixmodule.c | 30 ++----------------------- Python/fileutils.c | 34 +++++++++++++++++++++++++++++ 7 files changed, 70 insertions(+), 45 deletions(-) diff --git a/Include/fileutils.h b/Include/fileutils.h --- a/Include/fileutils.h +++ b/Include/fileutils.h @@ -5,6 +5,8 @@ extern "C" { #endif +PyAPI_FUNC(PyObject *) _Py_device_encoding(int); + PyAPI_FUNC(wchar_t *) _Py_char2wchar( const char *arg, size_t *size); diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -22,6 +22,8 @@ import socket import itertools import stat +import locale +import codecs try: import threading except ImportError: @@ -1424,6 +1426,22 @@ self.assertEqual(os.fsdecode(bytesfn), fn) + +class DeviceEncodingTests(unittest.TestCase): + + def test_bad_fd(self): + # Return None when an fd doesn't actually exist. + self.assertIsNone(os.device_encoding(123456)) + + @unittest.skipUnless(sys.platform.startswith('win') or + (hasattr(locale, 'nl_langinfo') and hasattr(locale, 'CODESET')), + 'test requires either Windows or nl_langinfo(CODESET)') + def test_device_encoding(self): + encoding = os.device_encoding(0) + self.assertIsNotNone(encoding) + self.assertTrue(codecs.lookup(encoding)) + + class PidTests(unittest.TestCase): @unittest.skipUnless(hasattr(os, 'getppid'), "test needs os.getppid") def test_getppid(self): @@ -1923,6 +1941,7 @@ Win32KillTests, Win32SymlinkTests, FSEncodingTests, + DeviceEncodingTests, PidTests, LoginTests, LinkTests, diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -1,9 +1,9 @@ /* An implementation of the new I/O lib as defined by PEP 3116 - "New I/O" - + Classes defined here: UnsupportedOperation, BlockingIOError. Functions defined here: open(). - + Mostly written by Amaury Forgeot d'Arc */ @@ -510,7 +510,7 @@ /* Basically the "n" format code with the ability to turn None into -1. */ -int +int _PyIO_ConvertSsize_t(PyObject *obj, void *result) { Py_ssize_t limit; if (obj == Py_None) { @@ -537,7 +537,6 @@ _PyIO_State *state = IO_MOD_STATE(mod); if (!state->initialized) return 0; - Py_VISIT(state->os_module); if (state->locale_module != NULL) { Py_VISIT(state->locale_module); } @@ -551,7 +550,6 @@ _PyIO_State *state = IO_MOD_STATE(mod); if (!state->initialized) return 0; - Py_CLEAR(state->os_module); if (state->locale_module != NULL) Py_CLEAR(state->locale_module); Py_CLEAR(state->unsupported_operation); @@ -595,11 +593,6 @@ state = IO_MOD_STATE(m); state->initialized = 0; - /* put os in the module state */ - state->os_module = PyImport_ImportModule("os"); - if (state->os_module == NULL) - goto fail; - #define ADD_TYPE(type, name) \ if (PyType_Ready(type) < 0) \ goto fail; \ @@ -725,7 +718,6 @@ return m; fail: - Py_XDECREF(state->os_module); Py_XDECREF(state->unsupported_operation); Py_DECREF(m); return NULL; diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -50,8 +50,8 @@ `*consumed`. If not found, returns -1 and sets `*consumed` to the number of characters which can be safely put aside until another search. - - NOTE: for performance reasons, `end` must point to a NUL character ('\0'). + + NOTE: for performance reasons, `end` must point to a NUL character ('\0'). Otherwise, the function will scan further and return garbage. */ extern Py_ssize_t _PyIO_find_line_ending( int translated, int universal, PyObject *readnl, @@ -124,7 +124,6 @@ typedef struct { int initialized; - PyObject *os_module; PyObject *locale_module; PyObject *unsupported_operation; diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -14,7 +14,6 @@ _Py_IDENTIFIER(close); _Py_IDENTIFIER(_dealloc_warn); _Py_IDENTIFIER(decode); -_Py_IDENTIFIER(device_encoding); _Py_IDENTIFIER(fileno); _Py_IDENTIFIER(flush); _Py_IDENTIFIER(getpreferredencoding); @@ -875,9 +874,13 @@ } } else { - self->encoding = _PyObject_CallMethodId(state->os_module, - &PyId_device_encoding, - "N", fileno); + int fd = (int) PyLong_AsLong(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)) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -9326,35 +9326,11 @@ device_encoding(PyObject *self, PyObject *args) { int fd; -#if defined(MS_WINDOWS) || defined(MS_WIN64) - UINT cp; -#endif + if (!PyArg_ParseTuple(args, "i:device_encoding", &fd)) return NULL; - if (!_PyVerify_fd(fd) || !isatty(fd)) { - Py_INCREF(Py_None); - return Py_None; - } -#if defined(MS_WINDOWS) || defined(MS_WIN64) - if (fd == 0) - cp = GetConsoleCP(); - else if (fd == 1 || fd == 2) - cp = GetConsoleOutputCP(); - else - cp = 0; - /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application - has no console */ - if (cp != 0) - return PyUnicode_FromFormat("cp%u", (unsigned int)cp); -#elif defined(CODESET) - { - char *codeset = nl_langinfo(CODESET); - if (codeset != NULL && codeset[0] != 0) - return PyUnicode_FromString(codeset); - } -#endif - Py_INCREF(Py_None); - return Py_None; + + return _Py_device_encoding(fd); } #ifdef __VMS diff --git a/Python/fileutils.c b/Python/fileutils.c --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -3,6 +3,40 @@ # include <windows.h> #endif +#ifdef HAVE_LANGINFO_H +#include <langinfo.h> +#endif + +PyObject * +_Py_device_encoding(int fd) +{ +#if defined(MS_WINDOWS) || defined(MS_WIN64) + UINT cp; +#endif + if (!_PyVerify_fd(fd) || !isatty(fd)) { + Py_RETURN_NONE; + } +#if defined(MS_WINDOWS) || defined(MS_WIN64) + if (fd == 0) + cp = GetConsoleCP(); + else if (fd == 1 || fd == 2) + cp = GetConsoleOutputCP(); + else + cp = 0; + /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application + has no console */ + if (cp != 0) + return PyUnicode_FromFormat("cp%u", (unsigned int)cp); +#elif defined(CODESET) + { + char *codeset = nl_langinfo(CODESET); + if (codeset != NULL && codeset[0] != 0) + return PyUnicode_FromString(codeset); + } +#endif + Py_RETURN_NONE; +} + #ifdef HAVE_STAT /* Decode a byte string from the locale encoding with the -- Repository URL: http://hg.python.org/cpython
participants (1)
-
brett.cannon