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()
diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py
index 6dd1e21..233d3da 100644
--- a/Lib/test/test_imp.py
+++ b/Lib/test/test_imp.py
@@ -306,11 +306,24 @@
                          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
diff --git a/Python/import.c b/Python/import.c
index c06aa1c..4cdce74 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -3623,56 +3623,70 @@
 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;
 }