mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	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()
This commit is contained in:
		
							parent
							
								
									3d85a6fa04
								
							
						
					
					
						commit
						1a4d12d746
					
				
					 2 changed files with 68 additions and 41 deletions
				
			
		|  | @ -306,11 +306,24 @@ def cleanup(): | |||
|                          os.sep.join(('.', 'pep3147', '__init__.py'))) | ||||
| 
 | ||||
| 
 | ||||
| class NullImporterTests(unittest.TestCase): | ||||
|     @unittest.skipIf(support.TESTFN_UNENCODEABLE is None, | ||||
|                      "Need an undecodeable filename") | ||||
|     def test_unencodeable(self): | ||||
|         name = support.TESTFN_UNENCODEABLE | ||||
|         os.mkdir(name) | ||||
|         try: | ||||
|             self.assertRaises(ImportError, imp.NullImporter, name) | ||||
|         finally: | ||||
|             os.rmdir(name) | ||||
| 
 | ||||
| 
 | ||||
| def test_main(): | ||||
|     tests = [ | ||||
|         ImportTests, | ||||
|         PEP3147Tests, | ||||
|         ReloadTests, | ||||
|         NullImporterTests, | ||||
|         ] | ||||
|     try: | ||||
|         import _thread | ||||
|  |  | |||
|  | @ -3623,56 +3623,70 @@ typedef struct { | |||
| static int | ||||
| NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds) | ||||
| { | ||||
|     char *path; | ||||
|     Py_ssize_t pathlen; | ||||
| #ifndef MS_WINDOWS | ||||
|     PyObject *path; | ||||
|     struct stat statbuf; | ||||
|     int rv; | ||||
| 
 | ||||
|     if (!_PyArg_NoKeywords("NullImporter()", kwds)) | ||||
|         return -1; | ||||
| 
 | ||||
|     if (!PyArg_ParseTuple(args, "es:NullImporter", | ||||
|                           Py_FileSystemDefaultEncoding, &path)) | ||||
|     if (!PyArg_ParseTuple(args, "O&:NullImporter", | ||||
|                           PyUnicode_FSConverter, &path)) | ||||
|         return -1; | ||||
| 
 | ||||
|     pathlen = strlen(path); | ||||
|     if (pathlen == 0) { | ||||
|         PyMem_Free(path); | ||||
|     if (PyBytes_GET_SIZE(path) == 0) { | ||||
|         Py_DECREF(path); | ||||
|         PyErr_SetString(PyExc_ImportError, "empty pathname"); | ||||
|         return -1; | ||||
|     } else { | ||||
| #ifndef MS_WINDOWS | ||||
|         struct stat statbuf; | ||||
|         int rv; | ||||
| 
 | ||||
|         rv = stat(path, &statbuf); | ||||
|         PyMem_Free(path); | ||||
|         if (rv == 0) { | ||||
|             /* it exists */ | ||||
|             if (S_ISDIR(statbuf.st_mode)) { | ||||
|                 /* it's a directory */ | ||||
|                 PyErr_SetString(PyExc_ImportError, | ||||
|                                 "existing directory"); | ||||
|                 return -1; | ||||
|             } | ||||
|         } | ||||
| #else /* MS_WINDOWS */ | ||||
|         DWORD rv; | ||||
|         /* see issue1293 and issue3677:
 | ||||
|          * stat() on Windows doesn't recognise paths like | ||||
|          * "e:\\shared\\" and "\\\\whiterab-c2znlh\\shared" as dirs. | ||||
|          */ | ||||
|         rv = GetFileAttributesA(path); | ||||
|         PyMem_Free(path); | ||||
|         if (rv != INVALID_FILE_ATTRIBUTES) { | ||||
|             /* it exists */ | ||||
|             if (rv & FILE_ATTRIBUTE_DIRECTORY) { | ||||
|                 /* it's a directory */ | ||||
|                 PyErr_SetString(PyExc_ImportError, | ||||
|                                 "existing directory"); | ||||
|                 return -1; | ||||
|             } | ||||
|         } | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
|     rv = stat(PyBytes_AS_STRING(path), &statbuf); | ||||
|     Py_DECREF(path); | ||||
|     if (rv == 0) { | ||||
|         /* it exists */ | ||||
|         if (S_ISDIR(statbuf.st_mode)) { | ||||
|             /* it's a directory */ | ||||
|             PyErr_SetString(PyExc_ImportError, "existing directory"); | ||||
|             return -1; | ||||
|         } | ||||
|     } | ||||
| #else /* MS_WINDOWS */ | ||||
|     PyObject *pathobj; | ||||
|     DWORD rv; | ||||
|     wchar_t path[MAXPATHLEN+1]; | ||||
|     Py_ssize_t len; | ||||
| 
 | ||||
|     if (!_PyArg_NoKeywords("NullImporter()", kwds)) | ||||
|         return -1; | ||||
| 
 | ||||
|     if (!PyArg_ParseTuple(args, "U:NullImporter", | ||||
|                           &pathobj)) | ||||
|         return -1; | ||||
| 
 | ||||
|     if (PyUnicode_GET_SIZE(pathobj) == 0) { | ||||
|         PyErr_SetString(PyExc_ImportError, "empty pathname"); | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     len = PyUnicode_AsWideChar((PyUnicodeObject*)pathobj, | ||||
|                                path, sizeof(path) / sizeof(path[0])); | ||||
|     if (len == -1) | ||||
|         return -1; | ||||
|     /* see issue1293 and issue3677:
 | ||||
|      * stat() on Windows doesn't recognise paths like | ||||
|      * "e:\\shared\\" and "\\\\whiterab-c2znlh\\shared" as dirs. | ||||
|      */ | ||||
|     rv = GetFileAttributesW(path); | ||||
|     if (rv != INVALID_FILE_ATTRIBUTES) { | ||||
|         /* it exists */ | ||||
|         if (rv & FILE_ATTRIBUTE_DIRECTORY) { | ||||
|             /* it's a directory */ | ||||
|             PyErr_SetString(PyExc_ImportError, "existing directory"); | ||||
|             return -1; | ||||
|         } | ||||
|     } | ||||
| #endif | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner