[Python-checkins] r82722 - python/branches/import_unicode/Python/pythonrun.c
victor.stinner
python-checkins at python.org
Fri Jul 9 01:33:38 CEST 2010
Author: victor.stinner
Date: Fri Jul 9 01:33:37 2010
New Revision: 82722
Log:
initfsencoding() reencodes sys.path and sys.modules filenames
Modified:
python/branches/import_unicode/Python/pythonrun.c
Modified: python/branches/import_unicode/Python/pythonrun.c
==============================================================================
--- python/branches/import_unicode/Python/pythonrun.c (original)
+++ python/branches/import_unicode/Python/pythonrun.c Fri Jul 9 01:33:37 2010
@@ -696,6 +696,118 @@
}
}
+static PyObject*
+reencode_filename(PyObject *module, PyObject *file, const char *new_encoding)
+{
+ PyObject *file_bytes = NULL;
+ PyObject *new_file = NULL;
+
+ file_bytes = PyUnicode_AsEncodedString(
+ file,
+ Py_FileSystemDefaultEncoding,
+ "surrogateescape");
+ if (file_bytes == NULL)
+ return NULL;
+ new_file = PyUnicode_Decode(
+ PyBytes_AsString(file_bytes),
+ PyBytes_GET_SIZE(file_bytes),
+ new_encoding,
+ "surrogateescape");
+ Py_DECREF(file_bytes);
+ return new_file;
+}
+
+static int
+reencode_module_path(PyObject *module, PyObject *path, const char *new_encoding)
+{
+ PyObject *filename;
+ PyObject *new_filename;
+ Py_ssize_t i, size;
+
+ size = PyList_Size(path);
+ for (i=0; i<size; i++) {
+ filename = PyList_GetItem(path, i);
+ if (filename == NULL)
+ return 1;
+
+ new_filename = reencode_filename(module, filename, new_encoding);
+ if (new_filename == NULL)
+ return 1;
+ if (PyList_SetItem(path, i, new_filename))
+ return 1;
+ }
+ return 0;
+}
+
+static int
+reencode_modules_path(const char *new_encoding)
+{
+ PyInterpreterState *interp = PyThreadState_GET()->interp;
+ PyObject *modules = interp->modules;
+ PyObject *values;
+ PyObject *iter = NULL;
+ PyObject *module = NULL;
+ PyObject *module_dict = NULL;
+ PyObject *file;
+ PyObject *path;
+ int ret = 1;
+
+ /* FIXME: Re-encode PySys_GetObject("path_importer_cache") keys? */
+ /* FIXME: Re-encode co_filename of all code objects! */
+
+ if (strcmp(new_encoding, PyUnicode_GetDefaultEncoding()) == 0)
+ return 0;
+
+
+ values = PyObject_CallMethod(modules, "values", "");
+ if (values == NULL)
+ return 1;
+
+ iter = PyObject_GetIter(values);
+ Py_DECREF(values);
+ if (iter == NULL)
+ return 1;
+
+ for (module = PyIter_Next(iter); module != NULL; module = PyIter_Next(iter)) {
+ file = PyModule_GetFilenameObject(module);
+ if (file != NULL) {
+ PyObject *new_file = reencode_filename(module, file, new_encoding);
+ if (new_file == NULL)
+ goto error;
+ if (PyObject_SetAttrString(module, "__file__", new_file)) {
+ Py_DECREF(new_file);
+ goto error;
+ }
+ Py_DECREF(new_file);
+ } else {
+ PyErr_Clear();
+ }
+
+ module_dict = PyModule_GetDict(module);
+ if (module_dict == NULL)
+ goto error;
+ path = PyDict_GetItemString(module_dict, "__path__");
+ if (path != NULL) {
+ if (reencode_module_path(module, path, new_encoding))
+ goto error;
+ } else {
+ PyErr_Clear();
+ }
+
+ Py_CLEAR(module);
+ }
+
+ ret = 0;
+ goto finally;
+
+error:
+ ret = 1;
+finally:
+ Py_XDECREF(iter);
+ Py_XDECREF(module);
+ return ret;
+}
+
static void
initfsencoding(void)
{
@@ -711,6 +823,10 @@
stdin and stdout if these are terminals. */
codeset = get_codeset();
if (codeset != NULL) {
+ if (reencode_modules_path(codeset))
+ Py_FatalError(
+ "Py_Initialize: can't reencode paths");
+
Py_FileSystemDefaultEncoding = codeset;
Py_HasFileSystemDefaultEncoding = 0;
return;
More information about the Python-checkins
mailing list