summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2008-10-03 16:09:28 (GMT)
committerMartin v. Löwis <martin@v.loewis.de>2008-10-03 16:09:28 (GMT)
commit04dc25c53728f5c2fe66d9e66af67da0c9b8959d (patch)
tree89a6a5bfc7567d3f5deba78bd96fedd2e167e2ce
parentefb14a8857c57e446477ecb964b301b041527c50 (diff)
downloadcpython-04dc25c53728f5c2fe66d9e66af67da0c9b8959d.zip
cpython-04dc25c53728f5c2fe66d9e66af67da0c9b8959d.tar.gz
cpython-04dc25c53728f5c2fe66d9e66af67da0c9b8959d.tar.bz2
Issue #3187: Add sys.setfilesystemencoding.
-rw-r--r--Doc/library/sys.rst8
-rw-r--r--Include/fileobject.h3
-rw-r--r--Lib/test/test_sys.py5
-rw-r--r--Misc/NEWS2
-rw-r--r--Python/bltinmodule.c25
-rw-r--r--Python/sysmodule.c19
6 files changed, 58 insertions, 4 deletions
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index 47217f4..568b06d 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -578,6 +578,14 @@ always available.
:file:`/usr/include/dlfcn.h` using the :program:`h2py` script. Availability:
Unix.
+.. function:: setfilesystemencoding(enc)
+
+ Set the encoding used when converting Python strings to file names to *enc*.
+ By default, Python tries to determine the encoding it should use automatically
+ on Unix; on Windows, it avoids such conversion completely. This function can
+ be used when Python's determination of the encoding needs to be overwritten,
+ e.g. when not all file names on disk can be decoded using the encoding that
+ Python had chosen.
.. function:: setprofile(profilefunc)
diff --git a/Include/fileobject.h b/Include/fileobject.h
index 00ec9be..1570890 100644
--- a/Include/fileobject.h
+++ b/Include/fileobject.h
@@ -20,7 +20,8 @@ PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *);
If non-NULL, this is different than the default encoding for strings
*/
PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
-PyAPI_DATA(const int) Py_HasFileSystemDefaultEncoding;
+PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding;
+PyAPI_FUNC(int) _Py_SetFileSystemEncoding(PyObject *);
/* Internal API
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index b5b5077..5c1a8e9 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -658,6 +658,11 @@ class SizeofTest(unittest.TestCase):
# sys.flags
check(sys.flags, size(vh) + self.P * len(sys.flags))
+ def test_setfilesystemencoding(self):
+ old = sys.getfilesystemencoding()
+ sys.setfilesystemencoding("iso-8859-1")
+ self.assertEqual(sys.getfilesystemencoding(), "iso-8859-1")
+ sys.setfilesystemencoding(old)
def test_main():
test.support.run_unittest(SysModuleTest, SizeofTest)
diff --git a/Misc/NEWS b/Misc/NEWS
index 9e04767..5318315 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -25,6 +25,8 @@ Core and Builtins
Library
-------
+- Issue #3187: Add sys.setfilesystemencoding.
+
- Issue #3187: Better support for "undecodable" filenames. Code by Victor
Stinner, with small tweaks by GvR.
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 0b96dc1..8159fe8 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -17,15 +17,34 @@
*/
#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
const char *Py_FileSystemDefaultEncoding = "mbcs";
-const int Py_HasFileSystemDefaultEncoding = 1;
+int Py_HasFileSystemDefaultEncoding = 1;
#elif defined(__APPLE__)
const char *Py_FileSystemDefaultEncoding = "utf-8";
-const int Py_HasFileSystemDefaultEncoding = 1;
+int Py_HasFileSystemDefaultEncoding = 1;
#else
const char *Py_FileSystemDefaultEncoding = NULL; /* use default */
-const int Py_HasFileSystemDefaultEncoding = 0;
+int Py_HasFileSystemDefaultEncoding = 0;
#endif
+int
+_Py_SetFileSystemEncoding(PyObject *s)
+{
+ PyObject *defenc;
+ if (!PyUnicode_Check(s)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ defenc = _PyUnicode_AsDefaultEncodedString(s, NULL);
+ if (!defenc)
+ return -1;
+ if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding)
+ /* A file system encoding was set at run-time */
+ free((char*)Py_FileSystemDefaultEncoding);
+ Py_FileSystemDefaultEncoding = strdup(PyBytes_AsString(defenc));
+ Py_HasFileSystemDefaultEncoding = 0;
+ return 0;
+}
+
static PyObject *
builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
{
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index f4118d6..89f50b5 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -216,7 +216,24 @@ Return the encoding used to convert Unicode filenames in\n\
operating system filenames."
);
+static PyObject *
+sys_setfilesystemencoding(PyObject *self, PyObject *args)
+{
+ PyObject *new_encoding;
+ if (!PyArg_ParseTuple(args, "U:setfilesystemencoding", &new_encoding))
+ return NULL;
+ if (_Py_SetFileSystemEncoding(new_encoding))
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+PyDoc_STRVAR(setfilesystemencoding_doc,
+"setfilesystemencoding(string) -> None\n\
+\n\
+Set the encoding used to convert Unicode filenames in\n\
+operating system filenames."
+);
static PyObject *
sys_intern(PyObject *self, PyObject *args)
@@ -872,6 +889,8 @@ static PyMethodDef sys_methods[] = {
#endif
{"setdefaultencoding", sys_setdefaultencoding, METH_VARARGS,
setdefaultencoding_doc},
+ {"setfilesystemencoding", sys_setfilesystemencoding, METH_VARARGS,
+ setfilesystemencoding_doc},
{"setcheckinterval", sys_setcheckinterval, METH_VARARGS,
setcheckinterval_doc},
{"getcheckinterval", sys_getcheckinterval, METH_NOARGS,