Kaydet (Commit) 04dc25c5 authored tarafından Martin v. Löwis's avatar Martin v. Löwis

Issue #3187: Add sys.setfilesystemencoding.

üst efb14a88
...@@ -578,6 +578,14 @@ always available. ...@@ -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)
......
...@@ -20,7 +20,8 @@ PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); ...@@ -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
......
...@@ -658,6 +658,11 @@ class SizeofTest(unittest.TestCase): ...@@ -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)
......
...@@ -25,6 +25,8 @@ Core and Builtins ...@@ -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.
......
...@@ -17,15 +17,34 @@ ...@@ -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)
{ {
......
...@@ -216,7 +216,24 @@ Return the encoding used to convert Unicode filenames in\n\ ...@@ -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[] = { ...@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment