[issue1293] Trailing slash in sys.path cause import failure
Changes by Guido van Rossum: -- resolution: - fixed status: open - closed __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Christian Heimes added the comment: I've checked in a fix in r58903 (py3k branch). __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Guido van Rossum added the comment: Works for me! On Nov 7, 2007 6:08 AM, Christian Heimes [EMAIL PROTECTED] wrote: Christian Heimes added the comment: Brett Cannon wrote: Modules/getpath.c:joinpath() I think does what you want in C. I don't see how it is going to help us. I've a final offer before I declare the bug as SEP (someone else's problem): pseudo code #ifdef MS_WINDOWS rv = stat(...) if (rv == error) check for *one* trailign / or \ and remove it rv = stat(...) if (rv == error) give up #endif It should fix the case when somebody adds a directory with a trailing / or \ on Windows. More complex cases are still broken but that's really not my concern. ;) Christian __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Christian Heimes added the comment: Brett Cannon wrote: Modules/getpath.c:joinpath() I think does what you want in C. I don't see how it is going to help us. I've a final offer before I declare the bug as SEP (someone else's problem): pseudo code #ifdef MS_WINDOWS rv = stat(...) if (rv == error) check for *one* trailign / or \ and remove it rv = stat(...) if (rv == error) give up #endif It should fix the case when somebody adds a directory with a trailing / or \ on Windows. More complex cases are still broken but that's really not my concern. ;) Christian __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Guido van Rossum added the comment: I see several problems with this, but there's light at the end of the tunnel. (1) Don't use s#; it will allow null bytes in the string, which we don't want. (2) Put the entire trailing slash removal inside #ifdef MS_WINDOWS. (3) Careful! It seems the code you wrote would transform C:/ into C: which isn't the same thing (the latter refers to the current directory on the C drive, while the former is the root of the C drive). -- nosy: +gvanrossum __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Changes by Guido van Rossum: -- resolution: accepted - __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Guido van Rossum added the comment: How do you like #ifdef MS_WINDOWS /* Remove trailing / and \ - Windows' stat doesn't like them - but * keep the trailing slash of C:/ */ Py_ssize_t i; char mangled[MAXPATHLEN+1]; if (pathlen MAXPATHLEN) { PyErr_SetString(PyExc_OverflowError, path is too long); return -1; } strcpy(mangled, path); for (i = pathlen-1; i 3; i--) { if (mangled[i] != '/' mangled[i] != '\\') { break; } mangled[i] = '\0'; } rv = stat(mangled, statbuf); #else rv = stat(path, statbuf); #endif i 3 should take care of C:/ and C:\ But the C: is optional. You will need to do more parsing. Some more examples (all with slashes; but backslashes work the same): //share/ - //share/ //share/x/ - //share/x /x/ - /x / - / // - // (probably illegal but doesn't matter) C:/ - C:/ x/ - x C:x/ - C:x Isn't it easier to handle this at the Python level? There probably already is code for parsing Windows paths. (Hm, maybe we have it in C too somewhere?) __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Brett Cannon added the comment: On 11/6/07, Guido van Rossum [EMAIL PROTECTED] wrote: Guido van Rossum added the comment: Another patch that uses os.path.normpath. Sorry, I really don't like to be importing os.path in order to be able to process the path used for an import. Modules/getpath.c:joinpath() I think does what you want in C. __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Guido van Rossum added the comment: Another patch that uses os.path.normpath. Sorry, I really don't like to be importing os.path in order to be able to process the path used for an import. __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Christian Heimes added the comment: Another patch that uses os.path.normpath. Added file: http://bugs.python.org/file8704/trailing_slash3.patch __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __Index: Python/import.c === --- Python/import.c (revision 58883) +++ Python/import.c (working copy) @@ -2918,6 +2918,11 @@ PyObject_HEAD } NullImporter; +#ifdef MS_WINDOWS +/* Cached os.path import for NullImporter_init() */ +static PyObject *nullimporter_ospath = NULL; +#endif + static int NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds) { @@ -2936,8 +2941,36 @@ } else { struct stat statbuf; int rv; +#ifdef MS_WINDOWS + /* normalize the path on Windows. Windows's stat doesn't like trailing + * slashes and backslashes. I'm leaking one reference of os.path to + * avoid an import dead lock. + */ + PyObject *r; + char *mangled; + if (nullimporter_ospath == NULL) { + nullimporter_ospath = PyImport_ImportModule(os.path); + if (nullimporter_ospath == NULL) { +return -1; + } + } + + r = PyObject_CallMethod(nullimporter_ospath, normpath, s, path); + if (r == NULL) { + return -1; + } + + mangled = PyString_AsString(r); + if (mangled == NULL) { + return -1; + } + + rv = stat(mangled, statbuf); + Py_DECREF(r); +#else rv = stat(path, statbuf); +#endif if (rv == 0) { /* it exists */ if (S_ISDIR(statbuf.st_mode)) { ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Facundo Batista added the comment: Only in win32, in Linux it behaves ok (I put a /tmp/w.py that prints 'w'): Python 2.5.1 (r251:54863, May 2 2007, 16:56:35) [GCC 4.1.2 (Ubuntu 4.1.2-0ubuntu4)] on linux2 Type help, copyright, credits or license for more information. import sys sys.path.append(/tmp/) import w w -- nosy: +facundobatista __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Christian Heimes added the comment: I was able to reproduce the bug on Windows with Python 2.6 and 3.0. I've added an unit test to both versions. -- nosy: +tiran priority: - low resolution: - accepted versions: +Python 2.6, Python 3.0 __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Christian Heimes added the comment: Here is a patch that solves the problem. However the patch is against the py3k sources and I like somebody to review and test it. I don't have enough disk space in my VMWare box to test it against the trunk or 2.5. Reason for the problem: Windows' stat doesn't like trailing slashes. -- keywords: +patch nosy: +georg.brandl Added file: http://bugs.python.org/file8674/trailing_slash.patch __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __Index: Python/import.c === --- Python/import.c (revision 58747) +++ Python/import.c (working copy) @@ -2921,6 +2921,7 @@ NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds) { char *path; + Py_ssize_t len, i; if (!_PyArg_NoKeywords(NullImporter(), kwds)) return -1; @@ -2929,13 +2930,26 @@ path)) return -1; - if (strlen(path) == 0) { + len = strlen(path); + if (len == 0) { PyErr_SetString(PyExc_ImportError, empty pathname); return -1; } else { struct stat statbuf; int rv; + /* Remove trailing / and \. Windows' stat doesn't like them */ + for (i=len-1; i 0; i--) { +#ifdef MS_WINDOWS + if (path[i] != '/' path[i] != '\\') { +#else + if (path[i] != '/') { +#endif +break; + } + path[i] = '\0'; + } + rv = stat(path, statbuf); if (rv == 0) { /* it exists */ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Christian Heimes added the comment: Fixed patch. Georg pointed out that PyArg_ParseTuple(s) returns a reference to the internal data of the PyString object. The new version copies the path to a fixed width buffer before it mangles the trailing slashes. The new patch applies against the trunk. Brett, you are the import master. Can you review the patch, please? -- assignee: - brett.cannon nosy: +brett.cannon Added file: http://bugs.python.org/file8675/trailing_slash2.patch __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __Index: Python/import.c === --- Python/import.c (Revision 58750) +++ Python/import.c (Arbeitskopie) @@ -2978,23 +2978,45 @@ NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds) { char *path; + Py_ssize_t pathlen; if (!_PyArg_NoKeywords(NullImporter(), kwds)) return -1; - if (!PyArg_ParseTuple(args, s:NullImporter, - path)) + if (!PyArg_ParseTuple(args, s#:NullImporter, + path, pathlen)) return -1; - if (strlen(path) == 0) { + if (pathlen == 0) { PyErr_SetString(PyExc_ImportError, empty pathname); return -1; } else { #ifndef RISCOS struct stat statbuf; int rv; + char mangled[MAXPATHLEN+1]; + Py_ssize_t i; - rv = stat(path, statbuf); + if (pathlen MAXPATHLEN) { + PyErr_SetString(PyExc_OverflowError, + path is too long); + return -1; + } + strcpy(mangled, path); + + /* Remove trailing / and \. Windows' stat doesn't like them */ + for (i = pathlen-1; i 0; i--) { +#ifdef MS_WINDOWS + if (mangled[i] != '/' mangled[i] != '\\') { +#else + if (mangled[i] != '/') { +#endif +break; + } + mangled[i] = '\0'; + } + + rv = stat(mangled, statbuf); if (rv == 0) { /* it exists */ if (S_ISDIR(statbuf.st_mode)) { ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
Brett Cannon added the comment: I will have a look when I can. __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com
[issue1293] Trailing slash in sys.path cause import failure
New submission from Guillaume Girard: On win32, the following code: import sys sys.path.append('../bar/') import bar where the file bar.py is present in ../bar/ will return an import error No module named bar. Remove the trailing slash and the bar.py is imported correctly. The problem is identical with backslash. This code works in Python 2.4. Not a very serious bug, but it breaks programs working with Python 2.4. -- components: Interpreter Core messages: 56523 nosy: guillaumegirard severity: minor status: open title: Trailing slash in sys.path cause import failure type: behavior versions: Python 2.5 __ Tracker [EMAIL PROTECTED] http://bugs.python.org/issue1293 __ ___ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com