]> granicus.if.org Git - python/commitdiff
Issue #3187: Add sys.setfilesystemencoding.
authorMartin v. Löwis <martin@v.loewis.de>
Fri, 3 Oct 2008 16:09:28 +0000 (16:09 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Fri, 3 Oct 2008 16:09:28 +0000 (16:09 +0000)
Doc/library/sys.rst
Include/fileobject.h
Lib/test/test_sys.py
Misc/NEWS
Python/bltinmodule.c
Python/sysmodule.c

index 47217f4d67d0614e524d4cdf948d306191001a33..568b06df8c9599d2b607e37f17b6d2e51a6464ea 100644 (file)
@@ -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)
 
index 00ec9befed68114b1f283aa83aec5013e7ecb331..157089036fb0a5524259e14b0e9465ca5e5f40ae 100644 (file)
@@ -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
 
index b5b5077b7af9ee18aac95116895588b9020ed989..5c1a8e9cacba6741f2ed99b93b8a02dd2db952e5 100644 (file)
@@ -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)
index 9e047675decb05ed446ebeb50950f55d0cb3fd80..5318315c3ff39dfa7f780be80242b66f0f642668 100644 (file)
--- 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.
 
index 0b96dc1a1df41cdf5ba420768e31877d36ce7497..8159fe84d5851228de7dc2f2e9ebb4bce53154ce 100644 (file)
 */
 #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)
 {
index f4118d6899ed98751720e95a76bcde1947e5656d..89f50b536e87913e79f08766ed13dfc640a62bf5 100644 (file)
@@ -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,