comparison Python/import.c @ 63945:03e884fac4db

Issue #9425: NullImporter constructor is fully unicode compliant * On non-Windows OSes: the constructor accepts bytes filenames and use surrogateescape for unicode filenames * On Windows: use GetFileAttributesW() instead of GetFileAttributesA()
author Victor Stinner <victor.stinner@haypocalc.com>
date Fri, 13 Aug 2010 13:07:29 +0000
parents 10c95c0f34d3
children 953010c0b168
comparison
equal deleted inserted replaced
63944:87b2da840252 63945:03e884fac4db
3621 } NullImporter; 3621 } NullImporter;
3622 3622
3623 static int 3623 static int
3624 NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds) 3624 NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds)
3625 { 3625 {
3626 char *path; 3626 #ifndef MS_WINDOWS
3627 Py_ssize_t pathlen; 3627 PyObject *path;
3628 struct stat statbuf;
3629 int rv;
3628 3630
3629 if (!_PyArg_NoKeywords("NullImporter()", kwds)) 3631 if (!_PyArg_NoKeywords("NullImporter()", kwds))
3630 return -1; 3632 return -1;
3631 3633
3632 if (!PyArg_ParseTuple(args, "es:NullImporter", 3634 if (!PyArg_ParseTuple(args, "O&:NullImporter",
3633 Py_FileSystemDefaultEncoding, &path)) 3635 PyUnicode_FSConverter, &path))
3634 return -1; 3636 return -1;
3635 3637
3636 pathlen = strlen(path); 3638 if (PyBytes_GET_SIZE(path) == 0) {
3637 if (pathlen == 0) { 3639 Py_DECREF(path);
3638 PyMem_Free(path);
3639 PyErr_SetString(PyExc_ImportError, "empty pathname"); 3640 PyErr_SetString(PyExc_ImportError, "empty pathname");
3640 return -1; 3641 return -1;
3641 } else { 3642 }
3642 #ifndef MS_WINDOWS 3643
3643 struct stat statbuf; 3644 rv = stat(PyBytes_AS_STRING(path), &statbuf);
3644 int rv; 3645 Py_DECREF(path);
3645 3646 if (rv == 0) {
3646 rv = stat(path, &statbuf); 3647 /* it exists */
3647 PyMem_Free(path); 3648 if (S_ISDIR(statbuf.st_mode)) {
3648 if (rv == 0) { 3649 /* it's a directory */
3649 /* it exists */ 3650 PyErr_SetString(PyExc_ImportError, "existing directory");
3650 if (S_ISDIR(statbuf.st_mode)) { 3651 return -1;
3651 /* it's a directory */ 3652 }
3652 PyErr_SetString(PyExc_ImportError, 3653 }
3653 "existing directory");
3654 return -1;
3655 }
3656 }
3657 #else /* MS_WINDOWS */ 3654 #else /* MS_WINDOWS */
3658 DWORD rv; 3655 PyObject *pathobj;
3659 /* see issue1293 and issue3677: 3656 DWORD rv;
3660 * stat() on Windows doesn't recognise paths like 3657 wchar_t path[MAXPATHLEN+1];
3661 * "e:\\shared\\" and "\\\\whiterab-c2znlh\\shared" as dirs. 3658 Py_ssize_t len;
3662 */ 3659
3663 rv = GetFileAttributesA(path); 3660 if (!_PyArg_NoKeywords("NullImporter()", kwds))
3664 PyMem_Free(path); 3661 return -1;
3665 if (rv != INVALID_FILE_ATTRIBUTES) { 3662
3666 /* it exists */ 3663 if (!PyArg_ParseTuple(args, "U:NullImporter",
3667 if (rv & FILE_ATTRIBUTE_DIRECTORY) { 3664 &pathobj))
3668 /* it's a directory */ 3665 return -1;
3669 PyErr_SetString(PyExc_ImportError, 3666
3670 "existing directory"); 3667 if (PyUnicode_GET_SIZE(pathobj) == 0) {
3671 return -1; 3668 PyErr_SetString(PyExc_ImportError, "empty pathname");
3672 } 3669 return -1;
3673 } 3670 }
3671
3672 len = PyUnicode_AsWideChar((PyUnicodeObject*)pathobj,
3673 path, sizeof(path) / sizeof(path[0]));
3674 if (len == -1)
3675 return -1;
3676 /* see issue1293 and issue3677:
3677 * stat() on Windows doesn't recognise paths like
3678 * "e:\\shared\\" and "\\\\whiterab-c2znlh\\shared" as dirs.
3679 */
3680 rv = GetFileAttributesW(path);
3681 if (rv != INVALID_FILE_ATTRIBUTES) {
3682 /* it exists */
3683 if (rv & FILE_ATTRIBUTE_DIRECTORY) {
3684 /* it's a directory */
3685 PyErr_SetString(PyExc_ImportError, "existing directory");
3686 return -1;
3687 }
3688 }
3674 #endif 3689 #endif
3675 }
3676 return 0; 3690 return 0;
3677 } 3691 }
3678 3692
3679 static PyObject * 3693 static PyObject *
3680 NullImporter_find_module(NullImporter *self, PyObject *args) 3694 NullImporter_find_module(NullImporter *self, PyObject *args)