Make os.confstr() return a bytes object, attributing the change to Python 3.2 diff --git a/Doc/library/os.rst b/Doc/library/os.rst --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -2101,7 +2101,8 @@ Miscellaneous System Information .. function:: confstr(name) - Return string-valued system configuration values. *name* specifies the + Return a string-valued system configuration value as a :class:`bytes` + object. *name* specifies the configuration value to retrieve; it may be a string which is the name of a defined system value; these names are specified in a number of standards (POSIX, Unix 95, Unix 98, and others). Some platforms define additional names as well. @@ -2119,6 +2120,11 @@ Miscellaneous System Information Availability: Unix + .. versionchanged:: 3.2 + Return type changed to :class:`bytes`; previously, the function + attempted to decode the value as UTF-8 and return it as a + string. + .. data:: confstr_names diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -123,6 +123,9 @@ New, Improved, and Deprecated Modules (Contributed by Tarek Ziadé.) +* The :mod:`os` module's :func:`~os.confstr` function now returns the + configuration value as a bytes object (:issue:`9580`). + * Socket objects now have a :meth:`~socket.socket.detach()` method which puts the socket into closed state without actually closing the underlying file descriptor. The latter can then be reused for other purposes. @@ -254,6 +257,8 @@ that may require changes to your code: * bytearray objects cannot be used anymore as filenames: convert them to bytes +* :func:`os.confstr` now returns a bytes object instead of a string. + * PyArg_Parse*() functions: * "t#" format has been removed: use "s#" or "s*" instead 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 @@ -21,7 +21,7 @@ import contextlib if (hasattr(os, "confstr_names") and "CS_GNU_LIBPTHREAD_VERSION" in os.confstr_names): libpthread = os.confstr("CS_GNU_LIBPTHREAD_VERSION") - USING_LINUXTHREADS= libpthread.startswith("linuxthreads") + USING_LINUXTHREADS= libpthread.startswith(b"linuxthreads") else: USING_LINUXTHREADS= False diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -154,7 +154,9 @@ class PosixTester(unittest.TestCase): def test_confstr(self): if hasattr(posix, 'confstr'): self.assertRaises(ValueError, posix.confstr, "CS_garbage") - self.assertEqual(len(posix.confstr("CS_PATH")) > 0, True) + path = posix.confstr("CS_PATH") + self.assertIsInstance(path, bytes) + self.assertGreater(len(path), 0) def test_dup2(self): if hasattr(posix, 'dup2'): diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6633,8 +6633,8 @@ conv_confstr_confname(PyObject *arg, int } PyDoc_STRVAR(posix_confstr__doc__, -"confstr(name) -> string\n\n\ -Return a string-valued system configuration variable."); +"confstr(name) -> bytes\n\n\ +Return a string-valued system configuration variable as a bytes object."); static PyObject * posix_confstr(PyObject *self, PyObject *args) @@ -6659,12 +6659,12 @@ posix_confstr(PyObject *self, PyObject * } else { if ((unsigned int)len >= sizeof(buffer)) { - result = PyUnicode_FromStringAndSize(NULL, len-1); + result = PyBytes_FromStringAndSize(NULL, len-1); if (result != NULL) - confstr(name, _PyUnicode_AsString(result), len); + confstr(name, PyBytes_AS_STRING(result), len); } else - result = PyUnicode_FromStringAndSize(buffer, len-1); + result = PyBytes_FromStringAndSize(buffer, len-1); } } return result;