Issue #3187: Add sys.setfilesystemencoding.

This commit is contained in:
Martin v. Löwis 2008-10-03 16:09:28 +00:00
parent efb14a8857
commit 04dc25c537
6 changed files with 58 additions and 4 deletions

View File

@ -578,6 +578,14 @@ always available.
:file:`/usr/include/dlfcn.h` using the :program:`h2py` script. Availability: :file:`/usr/include/dlfcn.h` using the :program:`h2py` script. Availability:
Unix. 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) .. function:: setprofile(profilefunc)

View 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 If non-NULL, this is different than the default encoding for strings
*/ */
PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; 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 /* Internal API

View File

@ -658,6 +658,11 @@ class SizeofTest(unittest.TestCase):
# sys.flags # sys.flags
check(sys.flags, size(vh) + self.P * len(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(): def test_main():
test.support.run_unittest(SysModuleTest, SizeofTest) test.support.run_unittest(SysModuleTest, SizeofTest)

View File

@ -25,6 +25,8 @@ Core and Builtins
Library Library
------- -------
- Issue #3187: Add sys.setfilesystemencoding.
- Issue #3187: Better support for "undecodable" filenames. Code by Victor - Issue #3187: Better support for "undecodable" filenames. Code by Victor
Stinner, with small tweaks by GvR. Stinner, with small tweaks by GvR.

View File

@ -17,15 +17,34 @@
*/ */
#if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T) #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
const char *Py_FileSystemDefaultEncoding = "mbcs"; const char *Py_FileSystemDefaultEncoding = "mbcs";
const int Py_HasFileSystemDefaultEncoding = 1; int Py_HasFileSystemDefaultEncoding = 1;
#elif defined(__APPLE__) #elif defined(__APPLE__)
const char *Py_FileSystemDefaultEncoding = "utf-8"; const char *Py_FileSystemDefaultEncoding = "utf-8";
const int Py_HasFileSystemDefaultEncoding = 1; int Py_HasFileSystemDefaultEncoding = 1;
#else #else
const char *Py_FileSystemDefaultEncoding = NULL; /* use default */ const char *Py_FileSystemDefaultEncoding = NULL; /* use default */
const int Py_HasFileSystemDefaultEncoding = 0; int Py_HasFileSystemDefaultEncoding = 0;
#endif #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 * static PyObject *
builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
{ {

View File

@ -216,7 +216,24 @@ Return the encoding used to convert Unicode filenames in\n\
operating system filenames." 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 * static PyObject *
sys_intern(PyObject *self, PyObject *args) sys_intern(PyObject *self, PyObject *args)
@ -872,6 +889,8 @@ static PyMethodDef sys_methods[] = {
#endif #endif
{"setdefaultencoding", sys_setdefaultencoding, METH_VARARGS, {"setdefaultencoding", sys_setdefaultencoding, METH_VARARGS,
setdefaultencoding_doc}, setdefaultencoding_doc},
{"setfilesystemencoding", sys_setfilesystemencoding, METH_VARARGS,
setfilesystemencoding_doc},
{"setcheckinterval", sys_setcheckinterval, METH_VARARGS, {"setcheckinterval", sys_setcheckinterval, METH_VARARGS,
setcheckinterval_doc}, setcheckinterval_doc},
{"getcheckinterval", sys_getcheckinterval, METH_NOARGS, {"getcheckinterval", sys_getcheckinterval, METH_NOARGS,