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'))) |                          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(): | def test_main(): | ||||||
|     tests = [ |     tests = [ | ||||||
|         ImportTests, |         ImportTests, | ||||||
|         PEP3147Tests, |         PEP3147Tests, | ||||||
|         ReloadTests, |         ReloadTests, | ||||||
|  |         NullImporterTests, | ||||||
|         ] |         ] | ||||||
|     try: |     try: | ||||||
|         import _thread |         import _thread | ||||||
|  |  | ||||||
|  | @ -3623,56 +3623,70 @@ typedef struct { | ||||||
| static int | static int | ||||||
| NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds) | NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds) | ||||||
| { | { | ||||||
|     char *path; | #ifndef MS_WINDOWS | ||||||
|     Py_ssize_t pathlen; |     PyObject *path; | ||||||
|  |     struct stat statbuf; | ||||||
|  |     int rv; | ||||||
| 
 | 
 | ||||||
|     if (!_PyArg_NoKeywords("NullImporter()", kwds)) |     if (!_PyArg_NoKeywords("NullImporter()", kwds)) | ||||||
|         return -1; |         return -1; | ||||||
| 
 | 
 | ||||||
|     if (!PyArg_ParseTuple(args, "es:NullImporter", |     if (!PyArg_ParseTuple(args, "O&:NullImporter", | ||||||
|                           Py_FileSystemDefaultEncoding, &path)) |                           PyUnicode_FSConverter, &path)) | ||||||
|         return -1; |         return -1; | ||||||
| 
 | 
 | ||||||
|     pathlen = strlen(path); |     if (PyBytes_GET_SIZE(path) == 0) { | ||||||
|     if (pathlen == 0) { |         Py_DECREF(path); | ||||||
|         PyMem_Free(path); |  | ||||||
|         PyErr_SetString(PyExc_ImportError, "empty pathname"); |         PyErr_SetString(PyExc_ImportError, "empty pathname"); | ||||||
|         return -1; |         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; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner