From 3430d70e03fa3f7d93feb965a33dd2d2311c566d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Walter=20D=C3=B6rwald?= Date: Mon, 17 Jun 2002 10:43:59 +0000 Subject: [PATCH] Apply diff2.txt from SF patch http://www.python.org/sf/566999 This patch enhances Python/import.c/find_module() so that unicode objects found in sys.path will be treated as legal directory names (The current code ignores anything that is not a str). The unicode name is converted to str using Py_FileSystemDefaultEncoding. --- Misc/NEWS | 3 +++ Python/import.c | 36 +++++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index ff1e44d4cf6..12c42b67c40 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -6,6 +6,9 @@ Type/class unification and new-style classes Core and builtins +- Unicode objects in sys.path are no longer ignored but treated + as directory names. + - The built-ins slice() and buffer() are now callable types. The types classobj (formerly class), code, function, instance, and instancemethod (formerly instance-method), which have no built-in diff --git a/Python/import.c b/Python/import.c index dabb7530771..9efd3eaf6ce 100644 --- a/Python/import.c +++ b/Python/import.c @@ -969,15 +969,30 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen, npath = PyList_Size(path); namelen = strlen(name); for (i = 0; i < npath; i++) { + PyObject *copy = NULL; PyObject *v = PyList_GetItem(path, i); +#ifdef Py_USING_UNICODE + if (PyUnicode_Check(v)) { + copy = PyUnicode_Encode(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v), Py_FileSystemDefaultEncoding, NULL); + if (copy == NULL) + return NULL; + v = copy; + } + else +#endif if (!PyString_Check(v)) continue; len = PyString_Size(v); - if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen) + if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen) { + Py_XDECREF(copy); continue; /* Too long */ + } strcpy(buf, PyString_AsString(v)); - if (strlen(buf) != len) + if (strlen(buf) != len) { + Py_XDECREF(copy); continue; /* v contains '\0' */ + } #ifdef macintosh /* ** Speedup: each sys.path item is interned, and @@ -991,12 +1006,14 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen, static struct filedescr resfiledescr = {"", "", PY_RESOURCE}; + Py_XDECREF(copy); return &resfiledescr; } if (PyMac_FindCodeResourceModule((PyStringObject *)v, name, buf)) { static struct filedescr resfiledescr = {"", "", PY_CODERESOURCE}; + Py_XDECREF(copy); return &resfiledescr; } #endif @@ -1012,18 +1029,22 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen, /* Check for package import (buf holds a directory name, and there's an __init__ module in that directory */ #ifdef HAVE_STAT - if (stat(buf, &statbuf) == 0 && /* it exists */ - S_ISDIR(statbuf.st_mode) && /* it's a directory */ - find_init_module(buf) && /* it has __init__.py */ - case_ok(buf, len, namelen, name)) /* and case matches */ + if (stat(buf, &statbuf) == 0 && /* it exists */ + S_ISDIR(statbuf.st_mode) && /* it's a directory */ + find_init_module(buf) && /* it has __init__.py */ + case_ok(buf, len, namelen, name)) { /* and case matches */ + Py_XDECREF(copy); return &fd_package; + } #else /* XXX How are you going to test for directories? */ #ifdef RISCOS if (isdir(buf) && find_init_module(buf) && - case_ok(buf, len, namelen, name)) + case_ok(buf, len, namelen, name)) { + Py_XDECREF(copy); return &fd_package; + } #endif #endif #ifdef macintosh @@ -1095,6 +1116,7 @@ find_module(char *realname, PyObject *path, char *buf, size_t buflen, saved_buf = NULL; } #endif + Py_XDECREF(copy); if (fp != NULL) break; }