|  | 
 | /* Module definition and import implementation */ | 
 |  | 
 | #include "Python.h" | 
 |  | 
 | #include "Python-ast.h" | 
 | #undef Yield /* undefine macro conflicting with winbase.h */ | 
 | #include "errcode.h" | 
 | #include "marshal.h" | 
 | #include "code.h" | 
 | #include "osdefs.h" | 
 | #include "importdl.h" | 
 |  | 
 | #ifdef HAVE_FCNTL_H | 
 | #include <fcntl.h> | 
 | #endif | 
 | #ifdef __cplusplus | 
 | extern "C" { | 
 | #endif | 
 |  | 
 | #ifdef MS_WINDOWS | 
 | /* for stat.st_mode */ | 
 | typedef unsigned short mode_t; | 
 | /* for _mkdir */ | 
 | #include <direct.h> | 
 | #endif | 
 |  | 
 |  | 
 | /* Magic word to reject .pyc files generated by other Python versions. | 
 |    It should change for each incompatible change to the bytecode. | 
 |  | 
 |    The value of CR and LF is incorporated so if you ever read or write | 
 |    a .pyc file in text mode the magic number will be wrong; also, the | 
 |    Apple MPW compiler swaps their values, botching string constants. | 
 |  | 
 |    The magic numbers must be spaced apart at least 2 values, as the | 
 |    -U interpeter flag will cause MAGIC+1 being used. They have been | 
 |    odd numbers for some time now. | 
 |  | 
 |    There were a variety of old schemes for setting the magic number. | 
 |    The current working scheme is to increment the previous value by | 
 |    10. | 
 |  | 
 |    Starting with the adoption of PEP 3147 in Python 3.2, every bump in magic | 
 |    number also includes a new "magic tag", i.e. a human readable string used | 
 |    to represent the magic number in __pycache__ directories.  When you change | 
 |    the magic number, you must also set a new unique magic tag.  Generally this | 
 |    can be named after the Python major version of the magic number bump, but | 
 |    it can really be anything, as long as it's different than anything else | 
 |    that's come before.  The tags are included in the following table, starting | 
 |    with Python 3.2a0. | 
 |  | 
 |    Known values: | 
 |        Python 1.5:   20121 | 
 |        Python 1.5.1: 20121 | 
 |        Python 1.5.2: 20121 | 
 |        Python 1.6:   50428 | 
 |        Python 2.0:   50823 | 
 |        Python 2.0.1: 50823 | 
 |        Python 2.1:   60202 | 
 |        Python 2.1.1: 60202 | 
 |        Python 2.1.2: 60202 | 
 |        Python 2.2:   60717 | 
 |        Python 2.3a0: 62011 | 
 |        Python 2.3a0: 62021 | 
 |        Python 2.3a0: 62011 (!) | 
 |        Python 2.4a0: 62041 | 
 |        Python 2.4a3: 62051 | 
 |        Python 2.4b1: 62061 | 
 |        Python 2.5a0: 62071 | 
 |        Python 2.5a0: 62081 (ast-branch) | 
 |        Python 2.5a0: 62091 (with) | 
 |        Python 2.5a0: 62092 (changed WITH_CLEANUP opcode) | 
 |        Python 2.5b3: 62101 (fix wrong code: for x, in ...) | 
 |        Python 2.5b3: 62111 (fix wrong code: x += yield) | 
 |        Python 2.5c1: 62121 (fix wrong lnotab with for loops and | 
 |                             storing constants that should have been removed) | 
 |        Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp) | 
 |        Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode) | 
 |        Python 2.6a1: 62161 (WITH_CLEANUP optimization) | 
 |        Python 3000:   3000 | 
 |                       3010 (removed UNARY_CONVERT) | 
 |                       3020 (added BUILD_SET) | 
 |                       3030 (added keyword-only parameters) | 
 |                       3040 (added signature annotations) | 
 |                       3050 (print becomes a function) | 
 |                       3060 (PEP 3115 metaclass syntax) | 
 |                       3061 (string literals become unicode) | 
 |                       3071 (PEP 3109 raise changes) | 
 |                       3081 (PEP 3137 make __file__ and __name__ unicode) | 
 |                       3091 (kill str8 interning) | 
 |                       3101 (merge from 2.6a0, see 62151) | 
 |                       3103 (__file__ points to source file) | 
 |        Python 3.0a4: 3111 (WITH_CLEANUP optimization). | 
 |        Python 3.0a5: 3131 (lexical exception stacking, including POP_EXCEPT) | 
 |        Python 3.1a0: 3141 (optimize list, set and dict comprehensions: | 
 |                change LIST_APPEND and SET_ADD, add MAP_ADD) | 
 |        Python 3.1a0: 3151 (optimize conditional branches: | 
 |                introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE) | 
 |        Python 3.2a0: 3160 (add SETUP_WITH) | 
 |                      tag: cpython-32 | 
 |        Python 3.2a1: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR) | 
 |                      tag: cpython-32 | 
 |        Python 3.2a2  3180 (add DELETE_DEREF) | 
 | */ | 
 |  | 
 | /* MAGIC must change whenever the bytecode emitted by the compiler may no | 
 |    longer be understood by older implementations of the eval loop (usually | 
 |    due to the addition of new opcodes) | 
 |    TAG and PYC_TAG_UNICODE must change for each major Python release. The magic | 
 |    number will take care of any bytecode changes that occur during development. | 
 | */ | 
 | #define MAGIC (3180 | ((long)'\r'<<16) | ((long)'\n'<<24)) | 
 | #define TAG "cpython-32" | 
 | #define CACHEDIR "__pycache__" | 
 | static const Py_UNICODE CACHEDIR_UNICODE[] = { | 
 |     '_', '_', 'p', 'y', 'c', 'a', 'c', 'h', 'e', '_', '_', '\0'}; | 
 | /* Current magic word and string tag as globals. */ | 
 | static long pyc_magic = MAGIC; | 
 | static const char *pyc_tag = TAG; | 
 | static const Py_UNICODE PYC_TAG_UNICODE[] = { | 
 |     'c', 'p', 'y', 't', 'h', 'o', 'n', '-', '3', '2', '\0'}; | 
 |  | 
 | /* See _PyImport_FixupExtensionObject() below */ | 
 | static PyObject *extensions = NULL; | 
 |  | 
 | /* This table is defined in config.c: */ | 
 | extern struct _inittab _PyImport_Inittab[]; | 
 |  | 
 | /* Method from Parser/tokenizer.c */ | 
 | extern char * PyTokenizer_FindEncoding(int); | 
 |  | 
 | struct _inittab *PyImport_Inittab = _PyImport_Inittab; | 
 |  | 
 | /* these tables define the module suffixes that Python recognizes */ | 
 | struct filedescr * _PyImport_Filetab = NULL; | 
 |  | 
 | static const struct filedescr _PyImport_StandardFiletab[] = { | 
 |     {".py", "U", PY_SOURCE}, | 
 | #ifdef MS_WINDOWS | 
 |     {".pyw", "U", PY_SOURCE}, | 
 | #endif | 
 |     {".pyc", "rb", PY_COMPILED}, | 
 |     {0, 0} | 
 | }; | 
 |  | 
 | static PyObject *initstr = NULL; | 
 |  | 
 |  | 
 | /* Initialize things */ | 
 |  | 
 | void | 
 | _PyImport_Init(void) | 
 | { | 
 |     const struct filedescr *scan; | 
 |     struct filedescr *filetab; | 
 |     int countD = 0; | 
 |     int countS = 0; | 
 |  | 
 |     initstr = PyUnicode_InternFromString("__init__"); | 
 |     if (initstr == NULL) | 
 |         Py_FatalError("Can't initialize import variables"); | 
 |  | 
 |     /* prepare _PyImport_Filetab: copy entries from | 
 |        _PyImport_DynLoadFiletab and _PyImport_StandardFiletab. | 
 |      */ | 
 | #ifdef HAVE_DYNAMIC_LOADING | 
 |     for (scan = _PyImport_DynLoadFiletab; scan->suffix != NULL; ++scan) | 
 |         ++countD; | 
 | #endif | 
 |     for (scan = _PyImport_StandardFiletab; scan->suffix != NULL; ++scan) | 
 |         ++countS; | 
 |     filetab = PyMem_NEW(struct filedescr, countD + countS + 1); | 
 |     if (filetab == NULL) | 
 |         Py_FatalError("Can't initialize import file table."); | 
 | #ifdef HAVE_DYNAMIC_LOADING | 
 |     memcpy(filetab, _PyImport_DynLoadFiletab, | 
 |            countD * sizeof(struct filedescr)); | 
 | #endif | 
 |     memcpy(filetab + countD, _PyImport_StandardFiletab, | 
 |            countS * sizeof(struct filedescr)); | 
 |     filetab[countD + countS].suffix = NULL; | 
 |  | 
 |     _PyImport_Filetab = filetab; | 
 |  | 
 |     if (Py_OptimizeFlag) { | 
 |         /* Replace ".pyc" with ".pyo" in _PyImport_Filetab */ | 
 |         for (; filetab->suffix != NULL; filetab++) { | 
 |             if (strcmp(filetab->suffix, ".pyc") == 0) | 
 |                 filetab->suffix = ".pyo"; | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | void | 
 | _PyImportHooks_Init(void) | 
 | { | 
 |     PyObject *v, *path_hooks = NULL, *zimpimport; | 
 |     int err = 0; | 
 |  | 
 |     /* adding sys.path_hooks and sys.path_importer_cache, setting up | 
 |        zipimport */ | 
 |     if (PyType_Ready(&PyNullImporter_Type) < 0) | 
 |         goto error; | 
 |  | 
 |     if (Py_VerboseFlag) | 
 |         PySys_WriteStderr("# installing zipimport hook\n"); | 
 |  | 
 |     v = PyList_New(0); | 
 |     if (v == NULL) | 
 |         goto error; | 
 |     err = PySys_SetObject("meta_path", v); | 
 |     Py_DECREF(v); | 
 |     if (err) | 
 |         goto error; | 
 |     v = PyDict_New(); | 
 |     if (v == NULL) | 
 |         goto error; | 
 |     err = PySys_SetObject("path_importer_cache", v); | 
 |     Py_DECREF(v); | 
 |     if (err) | 
 |         goto error; | 
 |     path_hooks = PyList_New(0); | 
 |     if (path_hooks == NULL) | 
 |         goto error; | 
 |     err = PySys_SetObject("path_hooks", path_hooks); | 
 |     if (err) { | 
 |   error: | 
 |         PyErr_Print(); | 
 |         Py_FatalError("initializing sys.meta_path, sys.path_hooks, " | 
 |                       "path_importer_cache, or NullImporter failed" | 
 |                       ); | 
 |     } | 
 |  | 
 |     zimpimport = PyImport_ImportModule("zipimport"); | 
 |     if (zimpimport == NULL) { | 
 |         PyErr_Clear(); /* No zip import module -- okay */ | 
 |         if (Py_VerboseFlag) | 
 |             PySys_WriteStderr("# can't import zipimport\n"); | 
 |     } | 
 |     else { | 
 |         PyObject *zipimporter = PyObject_GetAttrString(zimpimport, | 
 |                                                        "zipimporter"); | 
 |         Py_DECREF(zimpimport); | 
 |         if (zipimporter == NULL) { | 
 |             PyErr_Clear(); /* No zipimporter object -- okay */ | 
 |             if (Py_VerboseFlag) | 
 |                 PySys_WriteStderr( | 
 |                     "# can't import zipimport.zipimporter\n"); | 
 |         } | 
 |         else { | 
 |             /* sys.path_hooks.append(zipimporter) */ | 
 |             err = PyList_Append(path_hooks, zipimporter); | 
 |             Py_DECREF(zipimporter); | 
 |             if (err) | 
 |                 goto error; | 
 |             if (Py_VerboseFlag) | 
 |                 PySys_WriteStderr( | 
 |                     "# installed zipimport hook\n"); | 
 |         } | 
 |     } | 
 |     Py_DECREF(path_hooks); | 
 | } | 
 |  | 
 | void | 
 | _PyImport_Fini(void) | 
 | { | 
 |     Py_XDECREF(extensions); | 
 |     extensions = NULL; | 
 |     PyMem_DEL(_PyImport_Filetab); | 
 |     _PyImport_Filetab = NULL; | 
 | } | 
 |  | 
 |  | 
 | /* Locking primitives to prevent parallel imports of the same module | 
 |    in different threads to return with a partially loaded module. | 
 |    These calls are serialized by the global interpreter lock. */ | 
 |  | 
 | #ifdef WITH_THREAD | 
 |  | 
 | #include "pythread.h" | 
 |  | 
 | static PyThread_type_lock import_lock = 0; | 
 | static long import_lock_thread = -1; | 
 | static int import_lock_level = 0; | 
 |  | 
 | void | 
 | _PyImport_AcquireLock(void) | 
 | { | 
 |     long me = PyThread_get_thread_ident(); | 
 |     if (me == -1) | 
 |         return; /* Too bad */ | 
 |     if (import_lock == NULL) { | 
 |         import_lock = PyThread_allocate_lock(); | 
 |         if (import_lock == NULL) | 
 |             return;  /* Nothing much we can do. */ | 
 |     } | 
 |     if (import_lock_thread == me) { | 
 |         import_lock_level++; | 
 |         return; | 
 |     } | 
 |     if (import_lock_thread != -1 || !PyThread_acquire_lock(import_lock, 0)) | 
 |     { | 
 |         PyThreadState *tstate = PyEval_SaveThread(); | 
 |         PyThread_acquire_lock(import_lock, 1); | 
 |         PyEval_RestoreThread(tstate); | 
 |     } | 
 |     import_lock_thread = me; | 
 |     import_lock_level = 1; | 
 | } | 
 |  | 
 | int | 
 | _PyImport_ReleaseLock(void) | 
 | { | 
 |     long me = PyThread_get_thread_ident(); | 
 |     if (me == -1 || import_lock == NULL) | 
 |         return 0; /* Too bad */ | 
 |     if (import_lock_thread != me) | 
 |         return -1; | 
 |     import_lock_level--; | 
 |     if (import_lock_level == 0) { | 
 |         import_lock_thread = -1; | 
 |         PyThread_release_lock(import_lock); | 
 |     } | 
 |     return 1; | 
 | } | 
 |  | 
 | /* This function is called from PyOS_AfterFork to ensure that newly | 
 |    created child processes do not share locks with the parent. | 
 |    We now acquire the import lock around fork() calls but on some platforms | 
 |    (Solaris 9 and earlier? see isue7242) that still left us with problems. */ | 
 |  | 
 | void | 
 | _PyImport_ReInitLock(void) | 
 | { | 
 |     if (import_lock != NULL) | 
 |         import_lock = PyThread_allocate_lock(); | 
 |     if (import_lock_level > 1) { | 
 |         /* Forked as a side effect of import */ | 
 |         long me = PyThread_get_thread_ident(); | 
 |         PyThread_acquire_lock(import_lock, 0); | 
 |         /* XXX: can the previous line fail? */ | 
 |         import_lock_thread = me; | 
 |         import_lock_level--; | 
 |     } else { | 
 |         import_lock_thread = -1; | 
 |         import_lock_level = 0; | 
 |     } | 
 | } | 
 |  | 
 | #endif | 
 |  | 
 | static PyObject * | 
 | imp_lock_held(PyObject *self, PyObject *noargs) | 
 | { | 
 | #ifdef WITH_THREAD | 
 |     return PyBool_FromLong(import_lock_thread != -1); | 
 | #else | 
 |     return PyBool_FromLong(0); | 
 | #endif | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_acquire_lock(PyObject *self, PyObject *noargs) | 
 | { | 
 | #ifdef WITH_THREAD | 
 |     _PyImport_AcquireLock(); | 
 | #endif | 
 |     Py_INCREF(Py_None); | 
 |     return Py_None; | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_release_lock(PyObject *self, PyObject *noargs) | 
 | { | 
 | #ifdef WITH_THREAD | 
 |     if (_PyImport_ReleaseLock() < 0) { | 
 |         PyErr_SetString(PyExc_RuntimeError, | 
 |                         "not holding the import lock"); | 
 |         return NULL; | 
 |     } | 
 | #endif | 
 |     Py_INCREF(Py_None); | 
 |     return Py_None; | 
 | } | 
 |  | 
 | static void | 
 | imp_modules_reloading_clear(void) | 
 | { | 
 |     PyInterpreterState *interp = PyThreadState_Get()->interp; | 
 |     if (interp->modules_reloading != NULL) | 
 |         PyDict_Clear(interp->modules_reloading); | 
 | } | 
 |  | 
 | /* Helper for sys */ | 
 |  | 
 | PyObject * | 
 | PyImport_GetModuleDict(void) | 
 | { | 
 |     PyInterpreterState *interp = PyThreadState_GET()->interp; | 
 |     if (interp->modules == NULL) | 
 |         Py_FatalError("PyImport_GetModuleDict: no module dictionary!"); | 
 |     return interp->modules; | 
 | } | 
 |  | 
 |  | 
 | /* List of names to clear in sys */ | 
 | static char* sys_deletes[] = { | 
 |     "path", "argv", "ps1", "ps2", | 
 |     "last_type", "last_value", "last_traceback", | 
 |     "path_hooks", "path_importer_cache", "meta_path", | 
 |     /* misc stuff */ | 
 |     "flags", "float_info", | 
 |     NULL | 
 | }; | 
 |  | 
 | static char* sys_files[] = { | 
 |     "stdin", "__stdin__", | 
 |     "stdout", "__stdout__", | 
 |     "stderr", "__stderr__", | 
 |     NULL | 
 | }; | 
 |  | 
 |  | 
 | /* Un-initialize things, as good as we can */ | 
 |  | 
 | void | 
 | PyImport_Cleanup(void) | 
 | { | 
 |     Py_ssize_t pos, ndone; | 
 |     PyObject *key, *value, *dict; | 
 |     PyInterpreterState *interp = PyThreadState_GET()->interp; | 
 |     PyObject *modules = interp->modules; | 
 |  | 
 |     if (modules == NULL) | 
 |         return; /* Already done */ | 
 |  | 
 |     /* Delete some special variables first.  These are common | 
 |        places where user values hide and people complain when their | 
 |        destructors fail.  Since the modules containing them are | 
 |        deleted *last* of all, they would come too late in the normal | 
 |        destruction order.  Sigh. */ | 
 |  | 
 |     value = PyDict_GetItemString(modules, "builtins"); | 
 |     if (value != NULL && PyModule_Check(value)) { | 
 |         dict = PyModule_GetDict(value); | 
 |         if (Py_VerboseFlag) | 
 |             PySys_WriteStderr("# clear builtins._\n"); | 
 |         PyDict_SetItemString(dict, "_", Py_None); | 
 |     } | 
 |     value = PyDict_GetItemString(modules, "sys"); | 
 |     if (value != NULL && PyModule_Check(value)) { | 
 |         char **p; | 
 |         PyObject *v; | 
 |         dict = PyModule_GetDict(value); | 
 |         for (p = sys_deletes; *p != NULL; p++) { | 
 |             if (Py_VerboseFlag) | 
 |                 PySys_WriteStderr("# clear sys.%s\n", *p); | 
 |             PyDict_SetItemString(dict, *p, Py_None); | 
 |         } | 
 |         for (p = sys_files; *p != NULL; p+=2) { | 
 |             if (Py_VerboseFlag) | 
 |                 PySys_WriteStderr("# restore sys.%s\n", *p); | 
 |             v = PyDict_GetItemString(dict, *(p+1)); | 
 |             if (v == NULL) | 
 |                 v = Py_None; | 
 |             PyDict_SetItemString(dict, *p, v); | 
 |         } | 
 |     } | 
 |  | 
 |     /* First, delete __main__ */ | 
 |     value = PyDict_GetItemString(modules, "__main__"); | 
 |     if (value != NULL && PyModule_Check(value)) { | 
 |         if (Py_VerboseFlag) | 
 |             PySys_WriteStderr("# cleanup __main__\n"); | 
 |         _PyModule_Clear(value); | 
 |         PyDict_SetItemString(modules, "__main__", Py_None); | 
 |     } | 
 |  | 
 |     /* The special treatment of "builtins" here is because even | 
 |        when it's not referenced as a module, its dictionary is | 
 |        referenced by almost every module's __builtins__.  Since | 
 |        deleting a module clears its dictionary (even if there are | 
 |        references left to it), we need to delete the "builtins" | 
 |        module last.  Likewise, we don't delete sys until the very | 
 |        end because it is implicitly referenced (e.g. by print). | 
 |  | 
 |        Also note that we 'delete' modules by replacing their entry | 
 |        in the modules dict with None, rather than really deleting | 
 |        them; this avoids a rehash of the modules dictionary and | 
 |        also marks them as "non existent" so they won't be | 
 |        re-imported. */ | 
 |  | 
 |     /* Next, repeatedly delete modules with a reference count of | 
 |        one (skipping builtins and sys) and delete them */ | 
 |     do { | 
 |         ndone = 0; | 
 |         pos = 0; | 
 |         while (PyDict_Next(modules, &pos, &key, &value)) { | 
 |             if (value->ob_refcnt != 1) | 
 |                 continue; | 
 |             if (PyUnicode_Check(key) && PyModule_Check(value)) { | 
 |                 if (PyUnicode_CompareWithASCIIString(key, "builtins") == 0) | 
 |                     continue; | 
 |                 if (PyUnicode_CompareWithASCIIString(key, "sys") == 0) | 
 |                     continue; | 
 |                 if (Py_VerboseFlag) | 
 |                     PySys_FormatStderr( | 
 |                         "# cleanup[1] %U\n", key); | 
 |                 _PyModule_Clear(value); | 
 |                 PyDict_SetItem(modules, key, Py_None); | 
 |                 ndone++; | 
 |             } | 
 |         } | 
 |     } while (ndone > 0); | 
 |  | 
 |     /* Next, delete all modules (still skipping builtins and sys) */ | 
 |     pos = 0; | 
 |     while (PyDict_Next(modules, &pos, &key, &value)) { | 
 |         if (PyUnicode_Check(key) && PyModule_Check(value)) { | 
 |             if (PyUnicode_CompareWithASCIIString(key, "builtins") == 0) | 
 |                 continue; | 
 |             if (PyUnicode_CompareWithASCIIString(key, "sys") == 0) | 
 |                 continue; | 
 |             if (Py_VerboseFlag) | 
 |                 PySys_FormatStderr("# cleanup[2] %U\n", key); | 
 |             _PyModule_Clear(value); | 
 |             PyDict_SetItem(modules, key, Py_None); | 
 |         } | 
 |     } | 
 |  | 
 |     /* Next, delete sys and builtins (in that order) */ | 
 |     value = PyDict_GetItemString(modules, "sys"); | 
 |     if (value != NULL && PyModule_Check(value)) { | 
 |         if (Py_VerboseFlag) | 
 |             PySys_WriteStderr("# cleanup sys\n"); | 
 |         _PyModule_Clear(value); | 
 |         PyDict_SetItemString(modules, "sys", Py_None); | 
 |     } | 
 |     value = PyDict_GetItemString(modules, "builtins"); | 
 |     if (value != NULL && PyModule_Check(value)) { | 
 |         if (Py_VerboseFlag) | 
 |             PySys_WriteStderr("# cleanup builtins\n"); | 
 |         _PyModule_Clear(value); | 
 |         PyDict_SetItemString(modules, "builtins", Py_None); | 
 |     } | 
 |  | 
 |     /* Finally, clear and delete the modules directory */ | 
 |     PyDict_Clear(modules); | 
 |     interp->modules = NULL; | 
 |     Py_DECREF(modules); | 
 |     Py_CLEAR(interp->modules_reloading); | 
 | } | 
 |  | 
 |  | 
 | /* Helper for pythonrun.c -- return magic number and tag. */ | 
 |  | 
 | long | 
 | PyImport_GetMagicNumber(void) | 
 | { | 
 |     return pyc_magic; | 
 | } | 
 |  | 
 |  | 
 | const char * | 
 | PyImport_GetMagicTag(void) | 
 | { | 
 |     return pyc_tag; | 
 | } | 
 |  | 
 | /* Magic for extension modules (built-in as well as dynamically | 
 |    loaded).  To prevent initializing an extension module more than | 
 |    once, we keep a static dictionary 'extensions' keyed by module name | 
 |    (for built-in modules) or by filename (for dynamically loaded | 
 |    modules), containing these modules.  A copy of the module's | 
 |    dictionary is stored by calling _PyImport_FixupExtensionObject() | 
 |    immediately after the module initialization function succeeds.  A | 
 |    copy can be retrieved from there by calling | 
 |    _PyImport_FindExtensionObject(). | 
 |  | 
 |    Modules which do support multiple initialization set their m_size | 
 |    field to a non-negative number (indicating the size of the | 
 |    module-specific state). They are still recorded in the extensions | 
 |    dictionary, to avoid loading shared libraries twice. | 
 | */ | 
 |  | 
 | int | 
 | _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, | 
 |                                PyObject *filename) | 
 | { | 
 |     PyObject *modules, *dict; | 
 |     struct PyModuleDef *def; | 
 |     if (extensions == NULL) { | 
 |         extensions = PyDict_New(); | 
 |         if (extensions == NULL) | 
 |             return -1; | 
 |     } | 
 |     if (mod == NULL || !PyModule_Check(mod)) { | 
 |         PyErr_BadInternalCall(); | 
 |         return -1; | 
 |     } | 
 |     def = PyModule_GetDef(mod); | 
 |     if (!def) { | 
 |         PyErr_BadInternalCall(); | 
 |         return -1; | 
 |     } | 
 |     modules = PyImport_GetModuleDict(); | 
 |     if (PyDict_SetItem(modules, name, mod) < 0) | 
 |         return -1; | 
 |     if (_PyState_AddModule(mod, def) < 0) { | 
 |         PyDict_DelItem(modules, name); | 
 |         return -1; | 
 |     } | 
 |     if (def->m_size == -1) { | 
 |         if (def->m_base.m_copy) { | 
 |             /* Somebody already imported the module, | 
 |                likely under a different name. | 
 |                XXX this should really not happen. */ | 
 |             Py_DECREF(def->m_base.m_copy); | 
 |             def->m_base.m_copy = NULL; | 
 |         } | 
 |         dict = PyModule_GetDict(mod); | 
 |         if (dict == NULL) | 
 |             return -1; | 
 |         def->m_base.m_copy = PyDict_Copy(dict); | 
 |         if (def->m_base.m_copy == NULL) | 
 |             return -1; | 
 |     } | 
 |     PyDict_SetItem(extensions, filename, (PyObject*)def); | 
 |     return 0; | 
 | } | 
 |  | 
 | int | 
 | _PyImport_FixupBuiltin(PyObject *mod, char *name) | 
 | { | 
 |     int res; | 
 |     PyObject *nameobj; | 
 |     nameobj = PyUnicode_InternFromString(name); | 
 |     if (nameobj == NULL) | 
 |         return -1; | 
 |     res = _PyImport_FixupExtensionObject(mod, nameobj, nameobj); | 
 |     Py_DECREF(nameobj); | 
 |     return res; | 
 | } | 
 |  | 
 | PyObject * | 
 | _PyImport_FindExtensionObject(PyObject *name, PyObject *filename) | 
 | { | 
 |     PyObject *mod, *mdict; | 
 |     PyModuleDef* def; | 
 |     if (extensions == NULL) | 
 |         return NULL; | 
 |     def = (PyModuleDef*)PyDict_GetItem(extensions, filename); | 
 |     if (def == NULL) | 
 |         return NULL; | 
 |     if (def->m_size == -1) { | 
 |         /* Module does not support repeated initialization */ | 
 |         if (def->m_base.m_copy == NULL) | 
 |             return NULL; | 
 |         mod = PyImport_AddModuleObject(name); | 
 |         if (mod == NULL) | 
 |             return NULL; | 
 |         mdict = PyModule_GetDict(mod); | 
 |         if (mdict == NULL) | 
 |             return NULL; | 
 |         if (PyDict_Update(mdict, def->m_base.m_copy)) | 
 |             return NULL; | 
 |     } | 
 |     else { | 
 |         if (def->m_base.m_init == NULL) | 
 |             return NULL; | 
 |         mod = def->m_base.m_init(); | 
 |         if (mod == NULL) | 
 |             return NULL; | 
 |         PyDict_SetItem(PyImport_GetModuleDict(), name, mod); | 
 |         Py_DECREF(mod); | 
 |     } | 
 |     if (_PyState_AddModule(mod, def) < 0) { | 
 |         PyDict_DelItem(PyImport_GetModuleDict(), name); | 
 |         Py_DECREF(mod); | 
 |         return NULL; | 
 |     } | 
 |     if (Py_VerboseFlag) | 
 |         PySys_FormatStderr("import %U # previously loaded (%R)\n", | 
 |                           name, filename); | 
 |     return mod; | 
 |  | 
 | } | 
 |  | 
 | PyObject * | 
 | _PyImport_FindBuiltin(const char *name) | 
 | { | 
 |     PyObject *res, *nameobj; | 
 |     nameobj = PyUnicode_InternFromString(name); | 
 |     if (nameobj == NULL) | 
 |         return NULL; | 
 |     res = _PyImport_FindExtensionObject(nameobj, nameobj); | 
 |     Py_DECREF(nameobj); | 
 |     return res; | 
 | } | 
 |  | 
 | /* Get the module object corresponding to a module name. | 
 |    First check the modules dictionary if there's one there, | 
 |    if not, create a new one and insert it in the modules dictionary. | 
 |    Because the former action is most common, THIS DOES NOT RETURN A | 
 |    'NEW' REFERENCE! */ | 
 |  | 
 | PyObject * | 
 | PyImport_AddModuleObject(PyObject *name) | 
 | { | 
 |     PyObject *modules = PyImport_GetModuleDict(); | 
 |     PyObject *m; | 
 |  | 
 |     if ((m = PyDict_GetItem(modules, name)) != NULL && | 
 |         PyModule_Check(m)) | 
 |         return m; | 
 |     m = PyModule_NewObject(name); | 
 |     if (m == NULL) | 
 |         return NULL; | 
 |     if (PyDict_SetItem(modules, name, m) != 0) { | 
 |         Py_DECREF(m); | 
 |         return NULL; | 
 |     } | 
 |     Py_DECREF(m); /* Yes, it still exists, in modules! */ | 
 |  | 
 |     return m; | 
 | } | 
 |  | 
 | PyObject * | 
 | PyImport_AddModule(const char *name) | 
 | { | 
 |     PyObject *nameobj, *module; | 
 |     nameobj = PyUnicode_FromString(name); | 
 |     if (nameobj == NULL) | 
 |         return NULL; | 
 |     module = PyImport_AddModuleObject(nameobj); | 
 |     Py_DECREF(nameobj); | 
 |     return module; | 
 | } | 
 |  | 
 |  | 
 | /* Remove name from sys.modules, if it's there. */ | 
 | static void | 
 | remove_module(PyObject *name) | 
 | { | 
 |     PyObject *modules = PyImport_GetModuleDict(); | 
 |     if (PyDict_GetItem(modules, name) == NULL) | 
 |         return; | 
 |     if (PyDict_DelItem(modules, name) < 0) | 
 |         Py_FatalError("import:  deleting existing key in" | 
 |                       "sys.modules failed"); | 
 | } | 
 |  | 
 | static PyObject * get_sourcefile(PyObject *filename); | 
 | static PyObject *make_source_pathname(PyObject *pathname); | 
 | static PyObject* make_compiled_pathname(Py_UNICODE *pathname, int debug); | 
 |  | 
 | /* Execute a code object in a module and return the module object | 
 |  * WITH INCREMENTED REFERENCE COUNT.  If an error occurs, name is | 
 |  * removed from sys.modules, to avoid leaving damaged module objects | 
 |  * in sys.modules.  The caller may wish to restore the original | 
 |  * module object (if any) in this case; PyImport_ReloadModule is an | 
 |  * example. | 
 |  * | 
 |  * Note that PyImport_ExecCodeModuleWithPathnames() is the preferred, richer | 
 |  * interface.  The other two exist primarily for backward compatibility. | 
 |  */ | 
 | PyObject * | 
 | PyImport_ExecCodeModule(char *name, PyObject *co) | 
 | { | 
 |     return PyImport_ExecCodeModuleWithPathnames( | 
 |         name, co, (char *)NULL, (char *)NULL); | 
 | } | 
 |  | 
 | PyObject * | 
 | PyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname) | 
 | { | 
 |     return PyImport_ExecCodeModuleWithPathnames( | 
 |         name, co, pathname, (char *)NULL); | 
 | } | 
 |  | 
 | PyObject * | 
 | PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname, | 
 |                                      char *cpathname) | 
 | { | 
 |     PyObject *m = NULL; | 
 |     PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL; | 
 |  | 
 |     nameobj = PyUnicode_FromString(name); | 
 |     if (nameobj == NULL) | 
 |         return NULL; | 
 |  | 
 |     if (pathname != NULL) { | 
 |         pathobj = PyUnicode_DecodeFSDefault(pathname); | 
 |         if (pathobj == NULL) | 
 |             goto error; | 
 |     } else | 
 |         pathobj = NULL; | 
 |     if (cpathname != NULL) { | 
 |         cpathobj = PyUnicode_DecodeFSDefault(cpathname); | 
 |         if (cpathobj == NULL) | 
 |             goto error; | 
 |     } else | 
 |         cpathobj = NULL; | 
 |     m = PyImport_ExecCodeModuleObject(nameobj, co, pathobj, cpathobj); | 
 | error: | 
 |     Py_DECREF(nameobj); | 
 |     Py_XDECREF(pathobj); | 
 |     Py_XDECREF(cpathobj); | 
 |     return m; | 
 | } | 
 |  | 
 | PyObject* | 
 | PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, | 
 |                               PyObject *cpathname) | 
 | { | 
 |     PyObject *modules = PyImport_GetModuleDict(); | 
 |     PyObject *m, *d, *v; | 
 |  | 
 |     m = PyImport_AddModuleObject(name); | 
 |     if (m == NULL) | 
 |         return NULL; | 
 |     /* If the module is being reloaded, we get the old module back | 
 |        and re-use its dict to exec the new code. */ | 
 |     d = PyModule_GetDict(m); | 
 |     if (PyDict_GetItemString(d, "__builtins__") == NULL) { | 
 |         if (PyDict_SetItemString(d, "__builtins__", | 
 |                                  PyEval_GetBuiltins()) != 0) | 
 |             goto error; | 
 |     } | 
 |     /* Remember the filename as the __file__ attribute */ | 
 |     if (pathname != NULL) { | 
 |         v = get_sourcefile(pathname); | 
 |         if (v == NULL) | 
 |             PyErr_Clear(); | 
 |     } | 
 |     else | 
 |         v = NULL; | 
 |     if (v == NULL) { | 
 |         v = ((PyCodeObject *)co)->co_filename; | 
 |         Py_INCREF(v); | 
 |     } | 
 |     if (PyDict_SetItemString(d, "__file__", v) != 0) | 
 |         PyErr_Clear(); /* Not important enough to report */ | 
 |     Py_DECREF(v); | 
 |  | 
 |     /* Remember the pyc path name as the __cached__ attribute. */ | 
 |     if (cpathname != NULL) | 
 |         v = cpathname; | 
 |     else | 
 |         v = Py_None; | 
 |     if (PyDict_SetItemString(d, "__cached__", v) != 0) | 
 |         PyErr_Clear(); /* Not important enough to report */ | 
 |  | 
 |     v = PyEval_EvalCode(co, d, d); | 
 |     if (v == NULL) | 
 |         goto error; | 
 |     Py_DECREF(v); | 
 |  | 
 |     if ((m = PyDict_GetItem(modules, name)) == NULL) { | 
 |         PyErr_Format(PyExc_ImportError, | 
 |                      "Loaded module %R not found in sys.modules", | 
 |                      name); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     Py_INCREF(m); | 
 |  | 
 |     return m; | 
 |  | 
 |   error: | 
 |     remove_module(name); | 
 |     return NULL; | 
 | } | 
 |  | 
 |  | 
 | /* Like strrchr(string, '/') but searches for the rightmost of either SEP | 
 |    or ALTSEP, if the latter is defined. | 
 | */ | 
 | static Py_UNICODE* | 
 | rightmost_sep(Py_UNICODE *s) | 
 | { | 
 |     Py_UNICODE *found, c; | 
 |     for (found = NULL; (c = *s); s++) { | 
 |         if (c == SEP | 
 | #ifdef ALTSEP | 
 |             || c == ALTSEP | 
 | #endif | 
 |             ) | 
 |         { | 
 |             found = s; | 
 |         } | 
 |     } | 
 |     return found; | 
 | } | 
 |  | 
 |  | 
 | /* Given a pathname for a Python source file, fill a buffer with the | 
 |    pathname for the corresponding compiled file.  Return the pathname | 
 |    for the compiled file, or NULL if there's no space in the buffer. | 
 |    Doesn't set an exception. | 
 |  | 
 |    foo.py -> __pycache__/foo.<tag>.pyc */ | 
 |  | 
 | static PyObject* | 
 | make_compiled_pathname(Py_UNICODE *pathname, int debug) | 
 | { | 
 |     Py_UNICODE buf[MAXPATHLEN]; | 
 |     size_t buflen = (size_t)MAXPATHLEN; | 
 |     size_t len = Py_UNICODE_strlen(pathname); | 
 |     size_t i, save; | 
 |     Py_UNICODE *pos; | 
 |     int sep = SEP; | 
 |  | 
 |     /* Sanity check that the buffer has roughly enough space to hold what | 
 |        will eventually be the full path to the compiled file.  The 5 extra | 
 |        bytes include the slash afer __pycache__, the two extra dots, the | 
 |        extra trailing character ('c' or 'o') and null.  This isn't exact | 
 |        because the contents of the buffer can affect how many actual | 
 |        characters of the string get into the buffer.  We'll do a final | 
 |        sanity check before writing the extension to ensure we do not | 
 |        overflow the buffer. | 
 |     */ | 
 |     if (len + Py_UNICODE_strlen(CACHEDIR_UNICODE) + Py_UNICODE_strlen(PYC_TAG_UNICODE) + 5 > buflen) | 
 |         return NULL; | 
 |  | 
 |     /* Find the last path separator and copy everything from the start of | 
 |        the source string up to and including the separator. | 
 |     */ | 
 |     pos = rightmost_sep(pathname); | 
 |     if (pos == NULL) { | 
 |         i = 0; | 
 |     } | 
 |     else { | 
 |         sep = *pos; | 
 |         i = pos - pathname + 1; | 
 |         Py_UNICODE_strncpy(buf, pathname, i); | 
 |     } | 
 |  | 
 |     save = i; | 
 |     buf[i++] = '\0'; | 
 |     /* Add __pycache__/ */ | 
 |     Py_UNICODE_strcat(buf, CACHEDIR_UNICODE); | 
 |     i += Py_UNICODE_strlen(CACHEDIR_UNICODE) - 1; | 
 |     buf[i++] = sep; | 
 |     buf[i] = '\0'; | 
 |     /* Add the base filename, but remove the .py or .pyw extension, since | 
 |        the tag name must go before the extension. | 
 |     */ | 
 |     Py_UNICODE_strcat(buf, pathname + save); | 
 |     pos = Py_UNICODE_strrchr(buf + i, '.'); | 
 |     if (pos != NULL) | 
 |         *++pos = '\0'; | 
 |     Py_UNICODE_strcat(buf, PYC_TAG_UNICODE); | 
 |     /* The length test above assumes that we're only adding one character | 
 |        to the end of what would normally be the extension.  What if there | 
 |        is no extension, or the string ends in '.' or '.p', and otherwise | 
 |        fills the buffer?  By appending 4 more characters onto the string | 
 |        here, we could overrun the buffer. | 
 |  | 
 |        As a simple example, let's say buflen=32 and the input string is | 
 |        'xxx.py'.  strlen() would be 6 and the test above would yield: | 
 |  | 
 |        (6 + 11 + 10 + 5 == 32) > 32 | 
 |  | 
 |        which is false and so the name mangling would continue.  This would | 
 |        be fine because we'd end up with this string in buf: | 
 |  | 
 |        __pycache__/xxx.cpython-32.pyc\0 | 
 |  | 
 |        strlen(of that) == 30 + the nul fits inside a 32 character buffer. | 
 |        We can even handle an input string of say 'xxxxx' above because | 
 |        that's (5 + 11 + 10 + 5 == 31) > 32 which is also false.  Name | 
 |        mangling that yields: | 
 |  | 
 |        __pycache__/xxxxxcpython-32.pyc\0 | 
 |  | 
 |        which is 32 characters including the nul, and thus fits in the | 
 |        buffer. However, an input string of 'xxxxxx' would yield a result | 
 |        string of: | 
 |  | 
 |        __pycache__/xxxxxxcpython-32.pyc\0 | 
 |  | 
 |        which is 33 characters long (including the nul), thus overflowing | 
 |        the buffer, even though the first test would fail, i.e.: the input | 
 |        string is also 6 characters long, so 32 > 32 is false. | 
 |  | 
 |        The reason the first test fails but we still overflow the buffer is | 
 |        that the test above only expects to add one extra character to be | 
 |        added to the extension, and here we're adding three (pyc).  We | 
 |        don't add the first dot, so that reclaims one of expected | 
 |        positions, leaving us overflowing by 1 byte (3 extra - 1 reclaimed | 
 |        dot - 1 expected extra == 1 overflowed). | 
 |  | 
 |        The best we can do is ensure that we still have enough room in the | 
 |        target buffer before we write the extension.  Because it's always | 
 |        only the extension that can cause the overflow, and never the other | 
 |        path bytes we've written, it's sufficient to just do one more test | 
 |        here.  Still, the assertion that follows can't hurt. | 
 |     */ | 
 | #if 0 | 
 |     printf("strlen(buf): %d; buflen: %d\n", (int)strlen(buf), (int)buflen); | 
 | #endif | 
 |     len = Py_UNICODE_strlen(buf); | 
 |     if (len + 5 > buflen) | 
 |         return NULL; | 
 |     buf[len] = '.'; len++; | 
 |     buf[len] = 'p'; len++; | 
 |     buf[len] = 'y'; len++; | 
 |     buf[len] = debug ? 'c' : 'o'; len++; | 
 |     assert(len <= buflen); | 
 |     return PyUnicode_FromUnicode(buf, len); | 
 | } | 
 |  | 
 |  | 
 | /* Given a pathname to a Python byte compiled file, return the path to the | 
 |    source file, if the path matches the PEP 3147 format.  This does not check | 
 |    for any file existence, however, if the pyc file name does not match PEP | 
 |    3147 style, NULL is returned.  buf must be at least as big as pathname; | 
 |    the resulting path will always be shorter. | 
 |  | 
 |    (...)/__pycache__/foo.<tag>.pyc -> (...)/foo.py */ | 
 |  | 
 | static PyObject* | 
 | make_source_pathname(PyObject *pathobj) | 
 | { | 
 |     Py_UNICODE buf[MAXPATHLEN]; | 
 |     Py_UNICODE *pathname; | 
 |     Py_UNICODE *left, *right, *dot0, *dot1, sep; | 
 |     size_t i, j; | 
 |  | 
 |     if (PyUnicode_GET_SIZE(pathobj) > MAXPATHLEN) | 
 |         return NULL; | 
 |     pathname = PyUnicode_AS_UNICODE(pathobj); | 
 |  | 
 |     /* Look back two slashes from the end.  In between these two slashes | 
 |        must be the string __pycache__ or this is not a PEP 3147 style | 
 |        path.  It's possible for there to be only one slash. | 
 |     */ | 
 |     right = rightmost_sep(pathname); | 
 |     if (right == NULL) | 
 |         return NULL; | 
 |     sep = *right; | 
 |     *right = '\0'; | 
 |     left = rightmost_sep(pathname); | 
 |     *right = sep; | 
 |     if (left == NULL) | 
 |         left = pathname; | 
 |     else | 
 |         left++; | 
 |     if (right-left != Py_UNICODE_strlen(CACHEDIR_UNICODE) || | 
 |         Py_UNICODE_strncmp(left, CACHEDIR_UNICODE, right-left) != 0) | 
 |         return NULL; | 
 |  | 
 |     /* Now verify that the path component to the right of the last slash | 
 |        has two dots in it. | 
 |     */ | 
 |     if ((dot0 = Py_UNICODE_strchr(right + 1, '.')) == NULL) | 
 |         return NULL; | 
 |     if ((dot1 = Py_UNICODE_strchr(dot0 + 1, '.')) == NULL) | 
 |         return NULL; | 
 |     /* Too many dots? */ | 
 |     if (Py_UNICODE_strchr(dot1 + 1, '.') != NULL) | 
 |         return NULL; | 
 |  | 
 |     /* This is a PEP 3147 path.  Start by copying everything from the | 
 |        start of pathname up to and including the leftmost slash.  Then | 
 |        copy the file's basename, removing the magic tag and adding a .py | 
 |        suffix. | 
 |     */ | 
 |     Py_UNICODE_strncpy(buf, pathname, (i=left-pathname)); | 
 |     Py_UNICODE_strncpy(buf+i, right+1, (j=dot0-right)); | 
 |     buf[i+j] = 'p'; | 
 |     buf[i+j+1] = 'y'; | 
 |     return PyUnicode_FromUnicode(buf, i+j+2); | 
 | } | 
 |  | 
 | /* Given a pathname for a Python source file, its time of last | 
 |    modification, and a pathname for a compiled file, check whether the | 
 |    compiled file represents the same version of the source.  If so, | 
 |    return a FILE pointer for the compiled file, positioned just after | 
 |    the header; if not, return NULL. | 
 |    Doesn't set an exception. */ | 
 |  | 
 | static FILE * | 
 | check_compiled_module(PyObject *pathname, time_t mtime, PyObject *cpathname) | 
 | { | 
 |     FILE *fp; | 
 |     long magic; | 
 |     long pyc_mtime; | 
 |  | 
 |     fp = _Py_fopen(cpathname, "rb"); | 
 |     if (fp == NULL) | 
 |         return NULL; | 
 |     magic = PyMarshal_ReadLongFromFile(fp); | 
 |     if (magic != pyc_magic) { | 
 |         if (Py_VerboseFlag) | 
 |             PySys_FormatStderr("# %R has bad magic\n", cpathname); | 
 |         fclose(fp); | 
 |         return NULL; | 
 |     } | 
 |     pyc_mtime = PyMarshal_ReadLongFromFile(fp); | 
 |     if (pyc_mtime != mtime) { | 
 |         if (Py_VerboseFlag) | 
 |             PySys_FormatStderr("# %R has bad mtime\n", cpathname); | 
 |         fclose(fp); | 
 |         return NULL; | 
 |     } | 
 |     if (Py_VerboseFlag) | 
 |         PySys_FormatStderr("# %R matches %R\n", cpathname, pathname); | 
 |     return fp; | 
 | } | 
 |  | 
 |  | 
 | /* Read a code object from a file and check it for validity */ | 
 |  | 
 | static PyCodeObject * | 
 | read_compiled_module(PyObject *cpathname, FILE *fp) | 
 | { | 
 |     PyObject *co; | 
 |  | 
 |     co = PyMarshal_ReadLastObjectFromFile(fp); | 
 |     if (co == NULL) | 
 |         return NULL; | 
 |     if (!PyCode_Check(co)) { | 
 |         PyErr_Format(PyExc_ImportError, | 
 |                      "Non-code object in %R", cpathname); | 
 |         Py_DECREF(co); | 
 |         return NULL; | 
 |     } | 
 |     return (PyCodeObject *)co; | 
 | } | 
 |  | 
 |  | 
 | /* Load a module from a compiled file, execute it, and return its | 
 |    module object WITH INCREMENTED REFERENCE COUNT */ | 
 |  | 
 | static PyObject * | 
 | load_compiled_module(PyObject *name, PyObject *cpathname, FILE *fp) | 
 | { | 
 |     long magic; | 
 |     PyCodeObject *co; | 
 |     PyObject *m; | 
 |  | 
 |     magic = PyMarshal_ReadLongFromFile(fp); | 
 |     if (magic != pyc_magic) { | 
 |         PyErr_Format(PyExc_ImportError, | 
 |                      "Bad magic number in %R", cpathname); | 
 |         return NULL; | 
 |     } | 
 |     (void) PyMarshal_ReadLongFromFile(fp); | 
 |     co = read_compiled_module(cpathname, fp); | 
 |     if (co == NULL) | 
 |         return NULL; | 
 |     if (Py_VerboseFlag) | 
 |         PySys_FormatStderr("import %U # precompiled from %R\n", | 
 |                            name, cpathname); | 
 |     m = PyImport_ExecCodeModuleObject(name, (PyObject *)co, | 
 |                                       cpathname, cpathname); | 
 |     Py_DECREF(co); | 
 |  | 
 |     return m; | 
 | } | 
 |  | 
 | /* Parse a source file and return the corresponding code object */ | 
 |  | 
 | static PyCodeObject * | 
 | parse_source_module(PyObject *pathname, FILE *fp) | 
 | { | 
 |     PyCodeObject *co; | 
 |     PyObject *pathbytes; | 
 |     mod_ty mod; | 
 |     PyCompilerFlags flags; | 
 |     PyArena *arena; | 
 |  | 
 |     pathbytes = PyUnicode_EncodeFSDefault(pathname); | 
 |     if (pathbytes == NULL) | 
 |         return NULL; | 
 |  | 
 |     arena = PyArena_New(); | 
 |     if (arena == NULL) { | 
 |         Py_DECREF(pathbytes); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     flags.cf_flags = 0; | 
 |     mod = PyParser_ASTFromFile(fp, PyBytes_AS_STRING(pathbytes), NULL, | 
 |                                Py_file_input, 0, 0, &flags, | 
 |                                NULL, arena); | 
 |     if (mod != NULL) | 
 |         co = PyAST_Compile(mod, PyBytes_AS_STRING(pathbytes), NULL, arena); | 
 |     else | 
 |         co = NULL; | 
 |     Py_DECREF(pathbytes); | 
 |     PyArena_Free(arena); | 
 |     return co; | 
 | } | 
 |  | 
 | /* Helper to open a bytecode file for writing in exclusive mode */ | 
 |  | 
 | static FILE * | 
 | open_exclusive(char *filename, mode_t mode) | 
 | { | 
 | #if defined(O_EXCL)&&defined(O_CREAT)&&defined(O_WRONLY)&&defined(O_TRUNC) | 
 |     /* Use O_EXCL to avoid a race condition when another process tries to | 
 |        write the same file.  When that happens, our open() call fails, | 
 |        which is just fine (since it's only a cache). | 
 |        XXX If the file exists and is writable but the directory is not | 
 |        writable, the file will never be written.  Oh well. | 
 |     */ | 
 |     int fd; | 
 |     (void) unlink(filename); | 
 |     fd = open(filename, O_EXCL|O_CREAT|O_WRONLY|O_TRUNC | 
 | #ifdef O_BINARY | 
 |                             |O_BINARY   /* necessary for Windows */ | 
 | #endif | 
 | #ifdef __VMS | 
 |             , mode, "ctxt=bin", "shr=nil" | 
 | #else | 
 |             , mode | 
 | #endif | 
 |           ); | 
 |     if (fd < 0) | 
 |         return NULL; | 
 |     return fdopen(fd, "wb"); | 
 | #else | 
 |     /* Best we can do -- on Windows this can't happen anyway */ | 
 |     return fopen(filename, "wb"); | 
 | #endif | 
 | } | 
 |  | 
 |  | 
 | /* Write a compiled module to a file, placing the time of last | 
 |    modification of its source into the header. | 
 |    Errors are ignored, if a write error occurs an attempt is made to | 
 |    remove the file. */ | 
 |  | 
 | static void | 
 | write_compiled_module(PyCodeObject *co, PyObject *cpathname, | 
 |                       struct stat *srcstat) | 
 | { | 
 |     FILE *fp; | 
 |     time_t mtime = srcstat->st_mtime; | 
 | #ifdef MS_WINDOWS   /* since Windows uses different permissions  */ | 
 |     mode_t mode = srcstat->st_mode & ~S_IEXEC; | 
 | #else | 
 |     mode_t mode = srcstat->st_mode & ~S_IXUSR & ~S_IXGRP & ~S_IXOTH; | 
 |     mode_t dirmode = (srcstat->st_mode | | 
 |                       S_IXUSR | S_IXGRP | S_IXOTH | | 
 |                       S_IWUSR | S_IWGRP | S_IWOTH); | 
 |     PyObject *dirbytes; | 
 | #endif | 
 |     PyObject *cpathbytes, *dirname; | 
 |     Py_UNICODE *dirsep; | 
 |     int res, ok; | 
 |  | 
 |     /* Ensure that the __pycache__ directory exists. */ | 
 |     dirsep = rightmost_sep(PyUnicode_AS_UNICODE(cpathname)); | 
 |     if (dirsep == NULL) { | 
 |         if (Py_VerboseFlag) | 
 |             PySys_FormatStderr("# no %s path found %R\n", CACHEDIR, cpathname); | 
 |         return; | 
 |     } | 
 |     dirname = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(cpathname), | 
 |                                     dirsep - PyUnicode_AS_UNICODE(cpathname)); | 
 |     if (dirname == NULL) { | 
 |         PyErr_Clear(); | 
 |         return; | 
 |     } | 
 |  | 
 | #ifdef MS_WINDOWS | 
 |     res = CreateDirectoryW(PyUnicode_AS_UNICODE(dirname), NULL); | 
 |     ok = (res != 0); | 
 |     if (!ok && GetLastError() == ERROR_ALREADY_EXISTS) | 
 |         ok = 1; | 
 | #else | 
 |     dirbytes = PyUnicode_EncodeFSDefault(dirname); | 
 |     if (dirbytes == NULL) { | 
 |         PyErr_Clear(); | 
 |         return; | 
 |     } | 
 |     res = mkdir(PyBytes_AS_STRING(dirbytes), dirmode); | 
 |     Py_DECREF(dirbytes); | 
 |     if (0 <= res) | 
 |         ok = 1; | 
 |     else | 
 |         ok = (errno == EEXIST); | 
 | #endif | 
 |     if (!ok) { | 
 |         if (Py_VerboseFlag) | 
 |             PySys_FormatStderr("# cannot create cache dir %R\n", dirname); | 
 |         Py_DECREF(dirname); | 
 |         return; | 
 |     } | 
 |     Py_DECREF(dirname); | 
 |  | 
 |     cpathbytes = PyUnicode_EncodeFSDefault(cpathname); | 
 |     if (cpathbytes == NULL) { | 
 |         PyErr_Clear(); | 
 |         return; | 
 |     } | 
 |  | 
 |     fp = open_exclusive(PyBytes_AS_STRING(cpathbytes), mode); | 
 |     if (fp == NULL) { | 
 |         if (Py_VerboseFlag) | 
 |             PySys_FormatStderr( | 
 |                 "# can't create %R\n", cpathname); | 
 |         Py_DECREF(cpathbytes); | 
 |         return; | 
 |     } | 
 |     PyMarshal_WriteLongToFile(pyc_magic, fp, Py_MARSHAL_VERSION); | 
 |     /* First write a 0 for mtime */ | 
 |     PyMarshal_WriteLongToFile(0L, fp, Py_MARSHAL_VERSION); | 
 |     PyMarshal_WriteObjectToFile((PyObject *)co, fp, Py_MARSHAL_VERSION); | 
 |     if (fflush(fp) != 0 || ferror(fp)) { | 
 |         if (Py_VerboseFlag) | 
 |             PySys_FormatStderr("# can't write %R\n", cpathname); | 
 |         /* Don't keep partial file */ | 
 |         fclose(fp); | 
 | #ifdef MS_WINDOWS | 
 |         (void)DeleteFileW(PyUnicode_AS_UNICODE(cpathname)); | 
 | #else | 
 |         (void) unlink(PyBytes_AS_STRING(cpathbytes)); | 
 | #endif | 
 |         Py_DECREF(cpathbytes); | 
 |         return; | 
 |     } | 
 |     Py_DECREF(cpathbytes); | 
 |     /* Now write the true mtime */ | 
 |     fseek(fp, 4L, 0); | 
 |     assert(mtime < LONG_MAX); | 
 |     PyMarshal_WriteLongToFile((long)mtime, fp, Py_MARSHAL_VERSION); | 
 |     fflush(fp); | 
 |     fclose(fp); | 
 |     if (Py_VerboseFlag) | 
 |         PySys_FormatStderr("# wrote %R\n", cpathname); | 
 | } | 
 |  | 
 | static void | 
 | update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname) | 
 | { | 
 |     PyObject *constants, *tmp; | 
 |     Py_ssize_t i, n; | 
 |  | 
 |     if (PyUnicode_Compare(co->co_filename, oldname)) | 
 |         return; | 
 |  | 
 |     tmp = co->co_filename; | 
 |     co->co_filename = newname; | 
 |     Py_INCREF(co->co_filename); | 
 |     Py_DECREF(tmp); | 
 |  | 
 |     constants = co->co_consts; | 
 |     n = PyTuple_GET_SIZE(constants); | 
 |     for (i = 0; i < n; i++) { | 
 |         tmp = PyTuple_GET_ITEM(constants, i); | 
 |         if (PyCode_Check(tmp)) | 
 |             update_code_filenames((PyCodeObject *)tmp, | 
 |                                   oldname, newname); | 
 |     } | 
 | } | 
 |  | 
 | static void | 
 | update_compiled_module(PyCodeObject *co, PyObject *newname) | 
 | { | 
 |     PyObject *oldname; | 
 |  | 
 |     if (PyUnicode_Compare(co->co_filename, newname) == 0) | 
 |         return; | 
 |  | 
 |     oldname = co->co_filename; | 
 |     Py_INCREF(oldname); | 
 |     update_code_filenames(co, oldname, newname); | 
 |     Py_DECREF(oldname); | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_fix_co_filename(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *co; | 
 |     PyObject *file_path; | 
 |  | 
 |     if (!PyArg_ParseTuple(args, "OO:_fix_co_filename", &co, &file_path)) | 
 |         return NULL; | 
 |  | 
 |     if (!PyCode_Check(co)) { | 
 |         PyErr_SetString(PyExc_TypeError, | 
 |                         "first argument must be a code object"); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     if (!PyUnicode_Check(file_path)) { | 
 |         PyErr_SetString(PyExc_TypeError, | 
 |                         "second argument must be a string"); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     update_compiled_module((PyCodeObject*)co, file_path); | 
 |  | 
 |     Py_RETURN_NONE; | 
 | } | 
 |  | 
 | /* Load a source module from a given file and return its module | 
 |    object WITH INCREMENTED REFERENCE COUNT.  If there's a matching | 
 |    byte-compiled file, use that instead. */ | 
 |  | 
 | static PyObject * | 
 | load_source_module(PyObject *name, PyObject *pathname, FILE *fp) | 
 | { | 
 |     struct stat st; | 
 |     FILE *fpc; | 
 |     PyObject *cpathname = NULL, *cpathbytes = NULL; | 
 |     PyCodeObject *co; | 
 |     PyObject *m = NULL; | 
 |  | 
 |     if (fstat(fileno(fp), &st) != 0) { | 
 |         PyErr_Format(PyExc_RuntimeError, | 
 |                      "unable to get file status from %R", | 
 |                      pathname); | 
 |         goto error; | 
 |     } | 
 | #if SIZEOF_TIME_T > 4 | 
 |     /* Python's .pyc timestamp handling presumes that the timestamp fits | 
 |        in 4 bytes. This will be fine until sometime in the year 2038, | 
 |        when a 4-byte signed time_t will overflow. | 
 |      */ | 
 |     if (st.st_mtime >> 32) { | 
 |         PyErr_SetString(PyExc_OverflowError, | 
 |             "modification time overflows a 4 byte field"); | 
 |         goto error; | 
 |     } | 
 | #endif | 
 |     cpathname = make_compiled_pathname( | 
 |         PyUnicode_AS_UNICODE(pathname), | 
 |         !Py_OptimizeFlag); | 
 |  | 
 |     if (cpathname != NULL) | 
 |         fpc = check_compiled_module(pathname, st.st_mtime, cpathname); | 
 |     else | 
 |         fpc = NULL; | 
 |  | 
 |     if (fpc) { | 
 |         co = read_compiled_module(cpathname, fpc); | 
 |         fclose(fpc); | 
 |         if (co == NULL) | 
 |             goto error; | 
 |         update_compiled_module(co, pathname); | 
 |         if (Py_VerboseFlag) | 
 |             PySys_FormatStderr("import %U # precompiled from %R\n", | 
 |                                name, cpathname); | 
 |         m = PyImport_ExecCodeModuleObject(name, (PyObject *)co, | 
 |                                           cpathname, cpathname); | 
 |     } | 
 |     else { | 
 |         co = parse_source_module(pathname, fp); | 
 |         if (co == NULL) | 
 |             goto error; | 
 |         if (Py_VerboseFlag) | 
 |             PySys_FormatStderr("import %U # from %R\n", | 
 |                                name, pathname); | 
 |         if (cpathname != NULL) { | 
 |             PyObject *ro = PySys_GetObject("dont_write_bytecode"); | 
 |             if (ro == NULL || !PyObject_IsTrue(ro)) | 
 |                 write_compiled_module(co, cpathname, &st); | 
 |         } | 
 |         m = PyImport_ExecCodeModuleObject(name, (PyObject *)co, | 
 |                                           pathname, cpathname); | 
 |     } | 
 |     Py_DECREF(co); | 
 |  | 
 | error: | 
 |     Py_XDECREF(cpathbytes); | 
 |     Py_XDECREF(cpathname); | 
 |     return m; | 
 | } | 
 |  | 
 | /* Get source file -> unicode or None | 
 |  * Returns the path to the py file if available, else the given path | 
 |  */ | 
 | static PyObject * | 
 | get_sourcefile(PyObject *filename) | 
 | { | 
 |     Py_ssize_t len; | 
 |     Py_UNICODE *fileuni; | 
 |     PyObject *py; | 
 |     struct stat statbuf; | 
 |  | 
 |     len = PyUnicode_GET_SIZE(filename); | 
 |     if (len == 0) | 
 |         Py_RETURN_NONE; | 
 |  | 
 |     /* don't match *.pyc or *.pyo? */ | 
 |     fileuni = PyUnicode_AS_UNICODE(filename); | 
 |     if (len < 5 | 
 |         || fileuni[len-4] != '.' | 
 |         || (fileuni[len-3] != 'p' && fileuni[len-3] != 'P') | 
 |         || (fileuni[len-2] != 'y' && fileuni[len-2] != 'Y')) | 
 |         goto unchanged; | 
 |  | 
 |     /* Start by trying to turn PEP 3147 path into source path.  If that | 
 |      * fails, just chop off the trailing character, i.e. legacy pyc path | 
 |      * to py. | 
 |      */ | 
 |     py = make_source_pathname(filename); | 
 |     if (py == NULL) { | 
 |         PyErr_Clear(); | 
 |         py = PyUnicode_FromUnicode(fileuni, len - 1); | 
 |     } | 
 |     if (py == NULL) | 
 |         goto error; | 
 |  | 
 |     if (_Py_stat(py, &statbuf) == 0 && S_ISREG(statbuf.st_mode)) | 
 |         return py; | 
 |     Py_DECREF(py); | 
 |     goto unchanged; | 
 |  | 
 | error: | 
 |     PyErr_Clear(); | 
 | unchanged: | 
 |     Py_INCREF(filename); | 
 |     return filename; | 
 | } | 
 |  | 
 | /* Forward */ | 
 | static PyObject *load_module(PyObject *, FILE *, PyObject *, int, PyObject *); | 
 | static struct filedescr *find_module(PyObject *, PyObject *, PyObject *, | 
 |                                      PyObject **, FILE **, PyObject **); | 
 | static struct _frozen * find_frozen(PyObject *); | 
 |  | 
 | /* Load a package and return its module object WITH INCREMENTED | 
 |    REFERENCE COUNT */ | 
 |  | 
 | static PyObject * | 
 | load_package(PyObject *name, PyObject *pathname) | 
 | { | 
 |     PyObject *m, *d, *bufobj; | 
 |     PyObject *file = NULL, *path_list = NULL; | 
 |     int err; | 
 |     FILE *fp = NULL; | 
 |     struct filedescr *fdp; | 
 |  | 
 |     m = PyImport_AddModuleObject(name); | 
 |     if (m == NULL) | 
 |         return NULL; | 
 |     if (Py_VerboseFlag) | 
 |         PySys_FormatStderr("import %U # directory %R\n", | 
 |                            name, pathname); | 
 |     file = get_sourcefile(pathname); | 
 |     if (file == NULL) | 
 |         return NULL; | 
 |     path_list = Py_BuildValue("[O]", file); | 
 |     if (path_list == NULL) { | 
 |         Py_DECREF(file); | 
 |         return NULL; | 
 |     } | 
 |     d = PyModule_GetDict(m); | 
 |     err = PyDict_SetItemString(d, "__file__", file); | 
 |     Py_DECREF(file); | 
 |     if (err == 0) | 
 |         err = PyDict_SetItemString(d, "__path__", path_list); | 
 |     if (err != 0) { | 
 |         Py_DECREF(path_list); | 
 |         return NULL; | 
 |     } | 
 |     fdp = find_module(name, initstr, path_list, | 
 |                       &bufobj, &fp, NULL); | 
 |     Py_DECREF(path_list); | 
 |     if (fdp == NULL) { | 
 |         if (PyErr_ExceptionMatches(PyExc_ImportError)) { | 
 |             PyErr_Clear(); | 
 |             Py_INCREF(m); | 
 |             return m; | 
 |         } | 
 |         else | 
 |             return NULL; | 
 |     } | 
 |     m = load_module(name, fp, bufobj, fdp->type, NULL); | 
 |     Py_XDECREF(bufobj); | 
 |     if (fp != NULL) | 
 |         fclose(fp); | 
 |     return m; | 
 | } | 
 |  | 
 |  | 
 | /* Helper to test for built-in module */ | 
 |  | 
 | static int | 
 | is_builtin(PyObject *name) | 
 | { | 
 |     int i, cmp; | 
 |     for (i = 0; PyImport_Inittab[i].name != NULL; i++) { | 
 |         cmp = PyUnicode_CompareWithASCIIString(name, PyImport_Inittab[i].name); | 
 |         if (cmp == 0) { | 
 |             if (PyImport_Inittab[i].initfunc == NULL) | 
 |                 return -1; | 
 |             else | 
 |                 return 1; | 
 |         } | 
 |     } | 
 |     return 0; | 
 | } | 
 |  | 
 |  | 
 | /* Return an importer object for a sys.path/pkg.__path__ item 'p', | 
 |    possibly by fetching it from the path_importer_cache dict. If it | 
 |    wasn't yet cached, traverse path_hooks until a hook is found | 
 |    that can handle the path item. Return None if no hook could; | 
 |    this tells our caller it should fall back to the builtin | 
 |    import mechanism. Cache the result in path_importer_cache. | 
 |    Returns a borrowed reference. */ | 
 |  | 
 | static PyObject * | 
 | get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks, | 
 |                   PyObject *p) | 
 | { | 
 |     PyObject *importer; | 
 |     Py_ssize_t j, nhooks; | 
 |  | 
 |     /* These conditions are the caller's responsibility: */ | 
 |     assert(PyList_Check(path_hooks)); | 
 |     assert(PyDict_Check(path_importer_cache)); | 
 |  | 
 |     nhooks = PyList_Size(path_hooks); | 
 |     if (nhooks < 0) | 
 |         return NULL; /* Shouldn't happen */ | 
 |  | 
 |     importer = PyDict_GetItem(path_importer_cache, p); | 
 |     if (importer != NULL) | 
 |         return importer; | 
 |  | 
 |     /* set path_importer_cache[p] to None to avoid recursion */ | 
 |     if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0) | 
 |         return NULL; | 
 |  | 
 |     for (j = 0; j < nhooks; j++) { | 
 |         PyObject *hook = PyList_GetItem(path_hooks, j); | 
 |         if (hook == NULL) | 
 |             return NULL; | 
 |         importer = PyObject_CallFunctionObjArgs(hook, p, NULL); | 
 |         if (importer != NULL) | 
 |             break; | 
 |  | 
 |         if (!PyErr_ExceptionMatches(PyExc_ImportError)) { | 
 |             return NULL; | 
 |         } | 
 |         PyErr_Clear(); | 
 |     } | 
 |     if (importer == NULL) { | 
 |         importer = PyObject_CallFunctionObjArgs( | 
 |             (PyObject *)&PyNullImporter_Type, p, NULL | 
 |         ); | 
 |         if (importer == NULL) { | 
 |             if (PyErr_ExceptionMatches(PyExc_ImportError)) { | 
 |                 PyErr_Clear(); | 
 |                 return Py_None; | 
 |             } | 
 |         } | 
 |     } | 
 |     if (importer != NULL) { | 
 |         int err = PyDict_SetItem(path_importer_cache, p, importer); | 
 |         Py_DECREF(importer); | 
 |         if (err != 0) | 
 |             return NULL; | 
 |     } | 
 |     return importer; | 
 | } | 
 |  | 
 | PyAPI_FUNC(PyObject *) | 
 | PyImport_GetImporter(PyObject *path) { | 
 |     PyObject *importer=NULL, *path_importer_cache=NULL, *path_hooks=NULL; | 
 |  | 
 |     if ((path_importer_cache = PySys_GetObject("path_importer_cache"))) { | 
 |         if ((path_hooks = PySys_GetObject("path_hooks"))) { | 
 |             importer = get_path_importer(path_importer_cache, | 
 |                                          path_hooks, path); | 
 |         } | 
 |     } | 
 |     Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */ | 
 |     return importer; | 
 | } | 
 |  | 
 | /* Search the path (default sys.path) for a module.  Return the | 
 |    corresponding filedescr struct, and (via return arguments) the | 
 |    pathname and an open file.  Return NULL if the module is not found. */ | 
 |  | 
 | #ifdef MS_COREDLL | 
 | extern FILE *_PyWin_FindRegisteredModule(PyObject *, struct filedescr **, | 
 |                                          PyObject **p_path); | 
 | #endif | 
 |  | 
 | /* Forward */ | 
 | static int case_ok(PyObject *, Py_ssize_t, PyObject *); | 
 | static int find_init_module(PyObject *); | 
 | static struct filedescr importhookdescr = {"", "", IMP_HOOK}; | 
 |  | 
 | /* Get the path of a module: get its importer and call importer.find_module() | 
 |    hook, or check if the module if a package (if path/__init__.py exists). | 
 |  | 
 |     -1: error: a Python error occurred | 
 |      0: ignore: an error occurred because of invalid data, but the error is not | 
 |         important enough to be reported. | 
 |      1: get path: module not found, but *buf contains its path | 
 |      2: found: *p_fd is the file descriptor (IMP_HOOK or PKG_DIRECTORY) | 
 |         and *buf is the path */ | 
 |  | 
 | static int | 
 | find_module_path(PyObject *fullname, PyObject *name, PyObject *path, | 
 |                  PyObject *path_hooks, PyObject *path_importer_cache, | 
 |                  PyObject **p_path, PyObject **p_loader, struct filedescr **p_fd) | 
 | { | 
 |     Py_UNICODE buf[MAXPATHLEN+1]; | 
 |     Py_ssize_t buflen = MAXPATHLEN+1; | 
 |     PyObject *path_unicode, *filename; | 
 |     const Py_UNICODE *base; | 
 |     Py_ssize_t len; | 
 |     struct stat statbuf; | 
 |     static struct filedescr fd_package = {"", "", PKG_DIRECTORY}; | 
 |  | 
 |     if (PyUnicode_Check(path)) { | 
 |         Py_INCREF(path); | 
 |         path_unicode = path; | 
 |     } | 
 |     else if (PyBytes_Check(path)) { | 
 |         path_unicode = PyUnicode_DecodeFSDefaultAndSize( | 
 |             PyBytes_AS_STRING(path), PyBytes_GET_SIZE(path)); | 
 |         if (path_unicode == NULL) | 
 |             return -1; | 
 |     } | 
 |     else | 
 |         return 0; | 
 |  | 
 |     base = PyUnicode_AS_UNICODE(path_unicode); | 
 |     len = PyUnicode_GET_SIZE(path_unicode); | 
 |     if (len + 2 + PyUnicode_GET_SIZE(name) + MAXSUFFIXSIZE >= buflen) { | 
 |         Py_DECREF(path_unicode); | 
 |         return 0; /* Too long */ | 
 |     } | 
 |     Py_UNICODE_strcpy(buf, PyUnicode_AS_UNICODE(path_unicode)); | 
 |     Py_DECREF(path_unicode); | 
 |  | 
 |     if (Py_UNICODE_strlen(buf) != len) | 
 |         return 0; /* path contains '\0' */ | 
 |  | 
 |     /* sys.path_hooks import hook */ | 
 |     if (p_loader != NULL) { | 
 |         PyObject *importer; | 
 |  | 
 |         importer = get_path_importer(path_importer_cache, | 
 |                                      path_hooks, path); | 
 |         if (importer == NULL) { | 
 |             return -1; | 
 |         } | 
 |         /* Note: importer is a borrowed reference */ | 
 |         if (importer != Py_None) { | 
 |             PyObject *loader; | 
 |             loader = PyObject_CallMethod(importer, | 
 |                                          "find_module", "O", fullname); | 
 |             if (loader == NULL) | 
 |                 return -1;  /* error */ | 
 |             if (loader != Py_None) { | 
 |                 /* a loader was found */ | 
 |                 *p_loader = loader; | 
 |                 *p_fd = &importhookdescr; | 
 |                 return 2; | 
 |             } | 
 |             Py_DECREF(loader); | 
 |             return 0; | 
 |         } | 
 |     } | 
 |     /* no hook was found, use builtin import */ | 
 |  | 
 |     if (len > 0 && buf[len-1] != SEP | 
 | #ifdef ALTSEP | 
 |         && buf[len-1] != ALTSEP | 
 | #endif | 
 |         ) | 
 |         buf[len++] = SEP; | 
 |     Py_UNICODE_strcpy(buf+len, PyUnicode_AS_UNICODE(name)); | 
 |     len += PyUnicode_GET_SIZE(name); | 
 |  | 
 |     filename = PyUnicode_FromUnicode(buf, len); | 
 |     if (filename == NULL) | 
 |         return -1; | 
 |  | 
 |     /* Check for package import (buf holds a directory name, | 
 |        and there's an __init__ module in that directory */ | 
 | #ifdef HAVE_STAT | 
 |     if (_Py_stat(filename, &statbuf) == 0 &&         /* it exists */ | 
 |         S_ISDIR(statbuf.st_mode))           /* it's a directory */ | 
 |     { | 
 |         int match; | 
 |  | 
 |         match = case_ok(filename, 0, name); | 
 |         if (match < 0) { | 
 |             Py_DECREF(filename); | 
 |             return -1; | 
 |         } | 
 |         if (match) { /* case matches */ | 
 |             if (find_init_module(filename)) { /* and has __init__.py */ | 
 |                 *p_path = filename; | 
 |                 *p_fd = &fd_package; | 
 |                 return 2; | 
 |             } | 
 |             else { | 
 |                 int err; | 
 |                 err = PyErr_WarnFormat(PyExc_ImportWarning, 1, | 
 |                     "Not importing directory %R: missing __init__.py", | 
 |                     filename); | 
 |                 if (err) { | 
 |                     Py_DECREF(filename); | 
 |                     return -1; | 
 |                 } | 
 |             } | 
 |         } | 
 |     } | 
 | #endif | 
 |     *p_path = filename; | 
 |     return 1; | 
 | } | 
 |  | 
 | /* Find a module in search_path_list. For each path, try | 
 |    find_module_path() or try each _PyImport_Filetab suffix. | 
 |  | 
 |    If the module is found, return a file descriptor, write the path in | 
 |    *p_filename, write the pointer to the file object into *p_fp, and (if | 
 |    p_loader is not NULL) the loader into *p_loader. | 
 |  | 
 |    Otherwise, raise an exception and return NULL. */ | 
 |  | 
 | static struct filedescr* | 
 | find_module_path_list(PyObject *fullname, PyObject *name, | 
 |                       PyObject *search_path_list, PyObject *path_hooks, | 
 |                       PyObject *path_importer_cache, | 
 |                       PyObject **p_path, FILE **p_fp, PyObject **p_loader) | 
 | { | 
 |     Py_ssize_t i, npath; | 
 |     struct filedescr *fdp = NULL; | 
 |     char *filemode; | 
 |     FILE *fp = NULL; | 
 |     PyObject *prefix, *filename; | 
 |     int match; | 
 |  | 
 |     npath = PyList_Size(search_path_list); | 
 |     for (i = 0; i < npath; i++) { | 
 |         PyObject *path; | 
 |         int ok; | 
 |  | 
 |         path = PyList_GetItem(search_path_list, i); | 
 |         if (path == NULL) | 
 |             return NULL; | 
 |  | 
 |         prefix = NULL; | 
 |         ok = find_module_path(fullname, name, path, | 
 |                               path_hooks, path_importer_cache, | 
 |                               &prefix, p_loader, &fdp); | 
 |         if (ok < 0) | 
 |             return NULL; | 
 |         if (ok == 0) | 
 |             continue; | 
 |         if (ok == 2) { | 
 |             *p_path = prefix; | 
 |             return fdp; | 
 |         } | 
 |  | 
 |         for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) { | 
 |             filemode = fdp->mode; | 
 |             if (filemode[0] == 'U') | 
 |                 filemode = "r" PY_STDIOTEXTMODE; | 
 |  | 
 |             filename = PyUnicode_FromFormat("%U%s", prefix, fdp->suffix); | 
 |             if (filename == NULL) { | 
 |                 Py_DECREF(prefix); | 
 |                 return NULL; | 
 |             } | 
 |  | 
 |             if (Py_VerboseFlag > 1) | 
 |                 PySys_FormatStderr("# trying %R\n", filename); | 
 |  | 
 |             fp = _Py_fopen(filename, filemode); | 
 |             if (fp == NULL) { | 
 |                 Py_DECREF(filename); | 
 |                 continue; | 
 |             } | 
 |             match = case_ok(filename, -(Py_ssize_t)strlen(fdp->suffix), name); | 
 |             if (match < 0) { | 
 |                 Py_DECREF(prefix); | 
 |                 Py_DECREF(filename); | 
 |                 return NULL; | 
 |             } | 
 |             if (match) { | 
 |                 Py_DECREF(prefix); | 
 |                 *p_path = filename; | 
 |                 *p_fp = fp; | 
 |                 return fdp; | 
 |             } | 
 |             Py_DECREF(filename); | 
 |  | 
 |             fclose(fp); | 
 |             fp = NULL; | 
 |         } | 
 |         Py_DECREF(prefix); | 
 |     } | 
 |     PyErr_Format(PyExc_ImportError, | 
 |                  "No module named %R", name); | 
 |     return NULL; | 
 | } | 
 |  | 
 | /* Find a module: | 
 |  | 
 |    - try find_module() of each sys.meta_path hook | 
 |    - try find_frozen() | 
 |    - try is_builtin() | 
 |    - try _PyWin_FindRegisteredModule() (Windows only) | 
 |    - otherwise, call find_module_path_list() with search_path_list (if not | 
 |      NULL) or sys.path | 
 |  | 
 |    fullname can be NULL, but only if p_loader is NULL. | 
 |  | 
 |    Return: | 
 |  | 
 |    - &fd_builtin (C_BUILTIN) if it is a builtin | 
 |    - &fd_frozen (PY_FROZEN) if it is frozen | 
 |    - &fd_package (PKG_DIRECTORY) and write the filename into *p_path | 
 |      if it is a package | 
 |    - &importhookdescr (IMP_HOOK) and write the loader into *p_loader if a | 
 |      importer loader was found | 
 |    - a file descriptor (PY_SOURCE, PY_COMPILED, C_EXTENSION, PY_RESOURCE or | 
 |      PY_CODERESOURCE: see _PyImport_Filetab), write the filename into | 
 |      *p_path and the pointer to the open file into *p_fp | 
 |    - NULL on error | 
 |  | 
 |    By default, *p_path, *p_fp and *p_loader (if set) are set to NULL. | 
 |    Eg. *p_path is set to NULL for a builtin package. | 
 | */ | 
 |  | 
 | static struct filedescr * | 
 | find_module(PyObject *fullname, PyObject *name, PyObject *search_path_list, | 
 |             PyObject **p_path, FILE **p_fp, PyObject **p_loader) | 
 | { | 
 |     Py_ssize_t i, npath; | 
 |     static struct filedescr fd_frozen = {"", "", PY_FROZEN}; | 
 |     static struct filedescr fd_builtin = {"", "", C_BUILTIN}; | 
 |     PyObject *path_hooks, *path_importer_cache; | 
 |  | 
 |     *p_path = NULL; | 
 |     *p_fp = NULL; | 
 |     if (p_loader != NULL) | 
 |         *p_loader = NULL; | 
 |  | 
 |     if (PyUnicode_GET_SIZE(name) > MAXPATHLEN) { | 
 |         PyErr_SetString(PyExc_OverflowError, | 
 |                         "module name is too long"); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     /* sys.meta_path import hook */ | 
 |     if (p_loader != NULL) { | 
 |         PyObject *meta_path; | 
 |  | 
 |         meta_path = PySys_GetObject("meta_path"); | 
 |         if (meta_path == NULL || !PyList_Check(meta_path)) { | 
 |             PyErr_SetString(PyExc_ImportError, | 
 |                             "sys.meta_path must be a list of " | 
 |                             "import hooks"); | 
 |             return NULL; | 
 |         } | 
 |         Py_INCREF(meta_path);  /* zap guard */ | 
 |         npath = PyList_Size(meta_path); | 
 |         for (i = 0; i < npath; i++) { | 
 |             PyObject *loader; | 
 |             PyObject *hook = PyList_GetItem(meta_path, i); | 
 |             loader = PyObject_CallMethod(hook, "find_module", | 
 |                                          "OO", fullname, | 
 |                                          search_path_list != NULL ? | 
 |                                          search_path_list : Py_None); | 
 |             if (loader == NULL) { | 
 |                 Py_DECREF(meta_path); | 
 |                 return NULL;  /* true error */ | 
 |             } | 
 |             if (loader != Py_None) { | 
 |                 /* a loader was found */ | 
 |                 *p_loader = loader; | 
 |                 Py_DECREF(meta_path); | 
 |                 return &importhookdescr; | 
 |             } | 
 |             Py_DECREF(loader); | 
 |         } | 
 |         Py_DECREF(meta_path); | 
 |     } | 
 |  | 
 |     if (find_frozen(fullname) != NULL) | 
 |         return &fd_frozen; | 
 |  | 
 |     if (search_path_list == NULL) { | 
 | #ifdef MS_COREDLL | 
 |         FILE *fp; | 
 |         struct filedescr *fdp; | 
 | #endif | 
 |         if (is_builtin(name)) | 
 |             return &fd_builtin; | 
 | #ifdef MS_COREDLL | 
 |         fp = _PyWin_FindRegisteredModule(name, &fdp, p_path); | 
 |         if (fp != NULL) { | 
 |             *p_fp = fp; | 
 |             return fdp; | 
 |         } | 
 |         else if (PyErr_Occurred()) | 
 |             return NULL; | 
 | #endif | 
 |         search_path_list = PySys_GetObject("path"); | 
 |     } | 
 |  | 
 |     if (search_path_list == NULL || !PyList_Check(search_path_list)) { | 
 |         PyErr_SetString(PyExc_ImportError, | 
 |                         "sys.path must be a list of directory names"); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     path_hooks = PySys_GetObject("path_hooks"); | 
 |     if (path_hooks == NULL || !PyList_Check(path_hooks)) { | 
 |         PyErr_SetString(PyExc_ImportError, | 
 |                         "sys.path_hooks must be a list of " | 
 |                         "import hooks"); | 
 |         return NULL; | 
 |     } | 
 |     path_importer_cache = PySys_GetObject("path_importer_cache"); | 
 |     if (path_importer_cache == NULL || | 
 |         !PyDict_Check(path_importer_cache)) { | 
 |         PyErr_SetString(PyExc_ImportError, | 
 |                         "sys.path_importer_cache must be a dict"); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     return find_module_path_list(fullname, name, | 
 |                                  search_path_list, path_hooks, | 
 |                                  path_importer_cache, | 
 |                                  p_path, p_fp, p_loader); | 
 | } | 
 |  | 
 | /* case_bytes(char* buf, Py_ssize_t len, Py_ssize_t namelen, char* name) | 
 |  * The arguments here are tricky, best shown by example: | 
 |  *    /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0 | 
 |  *    ^                      ^                   ^    ^ | 
 |  *    |--------------------- buf ---------------------| | 
 |  *    |------------------- len ------------------| | 
 |  *                           |------ name -------| | 
 |  *                           |----- namelen -----| | 
 |  * buf is the full path, but len only counts up to (& exclusive of) the | 
 |  * extension.  name is the module name, also exclusive of extension. | 
 |  * | 
 |  * We've already done a successful stat() or fopen() on buf, so know that | 
 |  * there's some match, possibly case-insensitive. | 
 |  * | 
 |  * case_bytes() is to return 1 if there's a case-sensitive match for | 
 |  * name, else 0.  case_bytes() is also to return 1 if envar PYTHONCASEOK | 
 |  * exists. | 
 |  * | 
 |  * case_bytes() is used to implement case-sensitive import semantics even | 
 |  * on platforms with case-insensitive filesystems.  It's trivial to implement | 
 |  * for case-sensitive filesystems.  It's pretty much a cross-platform | 
 |  * nightmare for systems with case-insensitive filesystems. | 
 |  */ | 
 |  | 
 | /* First we may need a pile of platform-specific header files; the sequence | 
 |  * of #if's here should match the sequence in the body of case_bytes(). | 
 |  */ | 
 | #if defined(MS_WINDOWS) | 
 | #include <windows.h> | 
 |  | 
 | #elif defined(DJGPP) | 
 | #include <dir.h> | 
 |  | 
 | #elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H) | 
 | #include <sys/types.h> | 
 | #include <dirent.h> | 
 |  | 
 | #elif defined(PYOS_OS2) | 
 | #define INCL_DOS | 
 | #define INCL_DOSERRORS | 
 | #define INCL_NOPMAPI | 
 | #include <os2.h> | 
 | #endif | 
 |  | 
 | #if defined(DJGPP) \ | 
 |     || ((defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) \ | 
 |         && defined(HAVE_DIRENT_H)) \ | 
 |     || defined(PYOS_OS2) | 
 | #  define USE_CASE_OK_BYTES | 
 | #endif | 
 |  | 
 |  | 
 | #ifdef USE_CASE_OK_BYTES | 
 | static int | 
 | case_bytes(char *buf, Py_ssize_t len, Py_ssize_t namelen, const char *name) | 
 | { | 
 | /* Pick a platform-specific implementation; the sequence of #if's here should | 
 |  * match the sequence just above. | 
 |  */ | 
 |  | 
 | /* DJGPP */ | 
 | #if defined(DJGPP) | 
 |     struct ffblk ffblk; | 
 |     int done; | 
 |  | 
 |     if (Py_GETENV("PYTHONCASEOK") != NULL) | 
 |         return 1; | 
 |  | 
 |     done = findfirst(buf, &ffblk, FA_ARCH|FA_RDONLY|FA_HIDDEN|FA_DIREC); | 
 |     if (done) { | 
 |         PyErr_Format(PyExc_NameError, | 
 |           "Can't find file for module %.100s\n(filename %.300s)", | 
 |           name, buf); | 
 |         return -1; | 
 |     } | 
 |     return strncmp(ffblk.ff_name, name, namelen) == 0; | 
 |  | 
 | /* new-fangled macintosh (macosx) or Cygwin */ | 
 | #elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H) | 
 |     DIR *dirp; | 
 |     struct dirent *dp; | 
 |     char dirname[MAXPATHLEN + 1]; | 
 |     const int dirlen = len - namelen - 1; /* don't want trailing SEP */ | 
 |  | 
 |     if (Py_GETENV("PYTHONCASEOK") != NULL) | 
 |         return 1; | 
 |  | 
 |     /* Copy the dir component into dirname; substitute "." if empty */ | 
 |     if (dirlen <= 0) { | 
 |         dirname[0] = '.'; | 
 |         dirname[1] = '\0'; | 
 |     } | 
 |     else { | 
 |         assert(dirlen <= MAXPATHLEN); | 
 |         memcpy(dirname, buf, dirlen); | 
 |         dirname[dirlen] = '\0'; | 
 |     } | 
 |     /* Open the directory and search the entries for an exact match. */ | 
 |     dirp = opendir(dirname); | 
 |     if (dirp) { | 
 |         char *nameWithExt = buf + len - namelen; | 
 |         while ((dp = readdir(dirp)) != NULL) { | 
 |             const int thislen = | 
 | #ifdef _DIRENT_HAVE_D_NAMELEN | 
 |                                     dp->d_namlen; | 
 | #else | 
 |                                     strlen(dp->d_name); | 
 | #endif | 
 |             if (thislen >= namelen && | 
 |                 strcmp(dp->d_name, nameWithExt) == 0) { | 
 |                 (void)closedir(dirp); | 
 |                 return 1; /* Found */ | 
 |             } | 
 |         } | 
 |         (void)closedir(dirp); | 
 |     } | 
 |     return 0 ; /* Not found */ | 
 |  | 
 | /* OS/2 */ | 
 | #elif defined(PYOS_OS2) | 
 |     HDIR hdir = 1; | 
 |     ULONG srchcnt = 1; | 
 |     FILEFINDBUF3 ffbuf; | 
 |     APIRET rc; | 
 |  | 
 |     if (Py_GETENV("PYTHONCASEOK") != NULL) | 
 |         return 1; | 
 |  | 
 |     rc = DosFindFirst(buf, | 
 |                       &hdir, | 
 |                       FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY, | 
 |                       &ffbuf, sizeof(ffbuf), | 
 |                       &srchcnt, | 
 |                       FIL_STANDARD); | 
 |     if (rc != NO_ERROR) | 
 |         return 0; | 
 |     return strncmp(ffbuf.achName, name, namelen) == 0; | 
 |  | 
 | /* assuming it's a case-sensitive filesystem, so there's nothing to do! */ | 
 | #else | 
 | #   error "USE_CASE_OK_BYTES is not correctly defined" | 
 | #endif | 
 | } | 
 | #endif | 
 |  | 
 | /* | 
 |  * Check if a filename case matchs the name case. We've already done a | 
 |  * successful stat() or fopen() on buf, so know that there's some match, | 
 |  * possibly case-insensitive. | 
 |  * | 
 |  * case_ok() is to return 1 if there's a case-sensitive match for name, 0 if it | 
 |  * the filename doesn't match, or -1 on error.  case_ok() is also to return 1 | 
 |  * if envar PYTHONCASEOK exists. | 
 |  * | 
 |  * case_ok() is used to implement case-sensitive import semantics even | 
 |  * on platforms with case-insensitive filesystems.  It's trivial to implement | 
 |  * for case-sensitive filesystems.  It's pretty much a cross-platform | 
 |  * nightmare for systems with case-insensitive filesystems. | 
 |  */ | 
 |  | 
 | static int | 
 | case_ok(PyObject *filename, Py_ssize_t prefix_delta, PyObject *name) | 
 | { | 
 | #ifdef MS_WINDOWS | 
 |     WIN32_FIND_DATAW data; | 
 |     HANDLE h; | 
 |     int cmp; | 
 |  | 
 |     if (Py_GETENV("PYTHONCASEOK") != NULL) | 
 |         return 1; | 
 |  | 
 |     h = FindFirstFileW(PyUnicode_AS_UNICODE(filename), &data); | 
 |     if (h == INVALID_HANDLE_VALUE) { | 
 |         PyErr_Format(PyExc_NameError, | 
 |           "Can't find file for module %R\n(filename %R)", | 
 |           name, filename); | 
 |         return 0; | 
 |     } | 
 |     FindClose(h); | 
 |     cmp = wcsncmp(data.cFileName, | 
 |                   PyUnicode_AS_UNICODE(name), | 
 |                   PyUnicode_GET_SIZE(name)); | 
 |     return cmp == 0; | 
 | #elif defined(USE_CASE_OK_BYTES) | 
 |     int match; | 
 |     PyObject *filebytes, *namebytes; | 
 |     filebytes = PyUnicode_EncodeFSDefault(filename); | 
 |     if (filebytes == NULL) | 
 |         return -1; | 
 |     namebytes = PyUnicode_EncodeFSDefault(name); | 
 |     if (namebytes == NULL) { | 
 |         Py_DECREF(filebytes); | 
 |         return -1; | 
 |     } | 
 |     match = case_bytes( | 
 |         PyBytes_AS_STRING(filebytes), | 
 |         PyBytes_GET_SIZE(filebytes) + prefix_delta, | 
 |         PyBytes_GET_SIZE(namebytes), | 
 |         PyBytes_AS_STRING(namebytes)); | 
 |     Py_DECREF(filebytes); | 
 |     Py_DECREF(namebytes); | 
 |     return match; | 
 | #else | 
 |     /* assuming it's a case-sensitive filesystem, so there's nothing to do! */ | 
 |     return 1; | 
 |  | 
 | #endif | 
 | } | 
 |  | 
 | #ifdef HAVE_STAT | 
 |  | 
 | /* Helper to look for __init__.py or __init__.py[co] in potential package. | 
 |    Return 1 if __init__ was found, 0 if not, or -1 on error. */ | 
 | static int | 
 | find_init_module(PyObject *directory) | 
 | { | 
 |     size_t len; | 
 |     struct stat statbuf; | 
 |     PyObject *filename; | 
 |     int match; | 
 |  | 
 |     len = PyUnicode_GET_SIZE(directory); | 
 |     filename = PyUnicode_FromFormat("%U%c__init__.py", directory, SEP); | 
 |     if (filename == NULL) | 
 |         return -1; | 
 |     if (_Py_stat(filename, &statbuf) == 0) { | 
 |         /* 3=len(".py") */ | 
 |         match = case_ok(filename, -3, initstr); | 
 |         if (match < 0) { | 
 |             Py_DECREF(filename); | 
 |             return -1; | 
 |         } | 
 |         if (match) { | 
 |             Py_DECREF(filename); | 
 |             return 1; | 
 |         } | 
 |     } | 
 |     Py_DECREF(filename); | 
 |  | 
 |     filename = PyUnicode_FromFormat("%U%c__init__.py%c", | 
 |         directory, SEP, Py_OptimizeFlag ? 'o' : 'c'); | 
 |     if (filename == NULL) | 
 |         return -1; | 
 |     if (_Py_stat(filename, &statbuf) == 0) { | 
 |         /* 4=len(".pyc") */ | 
 |         match = case_ok(filename, -4, initstr); | 
 |         if (match < 0) { | 
 |             Py_DECREF(filename); | 
 |             return -1; | 
 |         } | 
 |         if (match) { | 
 |             Py_DECREF(filename); | 
 |             return 1; | 
 |         } | 
 |     } | 
 |     Py_DECREF(filename); | 
 |     return 0; | 
 | } | 
 |  | 
 | #endif /* HAVE_STAT */ | 
 |  | 
 |  | 
 | static int init_builtin(PyObject *); /* Forward */ | 
 |  | 
 | static PyObject* | 
 | load_builtin(PyObject *name, int type) | 
 | { | 
 |     PyObject *m, *modules; | 
 |     int err; | 
 |  | 
 |     if (type == C_BUILTIN) | 
 |         err = init_builtin(name); | 
 |     else | 
 |         err = PyImport_ImportFrozenModuleObject(name); | 
 |     if (err < 0) | 
 |         return NULL; | 
 |     if (err == 0) { | 
 |         PyErr_Format(PyExc_ImportError, | 
 |                 "Purported %s module %R not found", | 
 |                 type == C_BUILTIN ? "builtin" : "frozen", | 
 |                 name); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     modules = PyImport_GetModuleDict(); | 
 |     m = PyDict_GetItem(modules, name); | 
 |     if (m == NULL) { | 
 |         PyErr_Format( | 
 |                 PyExc_ImportError, | 
 |                 "%s module %R not properly initialized", | 
 |                 type == C_BUILTIN ? "builtin" : "frozen", | 
 |                 name); | 
 |         return NULL; | 
 |     } | 
 |     Py_INCREF(m); | 
 |     return m; | 
 | } | 
 |  | 
 | /* Load an external module using the default search path and return | 
 |    its module object WITH INCREMENTED REFERENCE COUNT */ | 
 |  | 
 | static PyObject * | 
 | load_module(PyObject *name, FILE *fp, PyObject *pathname, int type, PyObject *loader) | 
 | { | 
 |     PyObject *m; | 
 |  | 
 |     /* First check that there's an open file (if we need one)  */ | 
 |     switch (type) { | 
 |     case PY_SOURCE: | 
 |     case PY_COMPILED: | 
 |         if (fp == NULL) { | 
 |             PyErr_Format(PyExc_ValueError, | 
 |                          "file object required for import (type code %d)", | 
 |                          type); | 
 |             return NULL; | 
 |         } | 
 |     } | 
 |  | 
 |     switch (type) { | 
 |  | 
 |     case PY_SOURCE: | 
 |         m = load_source_module(name, pathname, fp); | 
 |         break; | 
 |  | 
 |     case PY_COMPILED: | 
 |         m = load_compiled_module(name, pathname, fp); | 
 |         break; | 
 |  | 
 | #ifdef HAVE_DYNAMIC_LOADING | 
 |     case C_EXTENSION: | 
 |         m = _PyImport_LoadDynamicModule(name, pathname, fp); | 
 |         break; | 
 | #endif | 
 |  | 
 |     case PKG_DIRECTORY: | 
 |         m = load_package(name, pathname); | 
 |         break; | 
 |  | 
 |     case C_BUILTIN: | 
 |     case PY_FROZEN: | 
 |         m = load_builtin(name, type); | 
 |         break; | 
 |  | 
 |     case IMP_HOOK: { | 
 |         if (loader == NULL) { | 
 |             PyErr_SetString(PyExc_ImportError, | 
 |                             "import hook without loader"); | 
 |             return NULL; | 
 |         } | 
 |         m = PyObject_CallMethod(loader, "load_module", "O", name); | 
 |         break; | 
 |     } | 
 |  | 
 |     default: | 
 |         PyErr_Format(PyExc_ImportError, | 
 |                      "Don't know how to import %R (type code %d)", | 
 |                       name, type); | 
 |         m = NULL; | 
 |  | 
 |     } | 
 |  | 
 |     return m; | 
 | } | 
 |  | 
 |  | 
 | /* Initialize a built-in module. | 
 |    Return 1 for success, 0 if the module is not found, and -1 with | 
 |    an exception set if the initialization failed. */ | 
 |  | 
 | static int | 
 | init_builtin(PyObject *name) | 
 | { | 
 |     struct _inittab *p; | 
 |  | 
 |     if (_PyImport_FindExtensionObject(name, name) != NULL) | 
 |         return 1; | 
 |  | 
 |     for (p = PyImport_Inittab; p->name != NULL; p++) { | 
 |         PyObject *mod; | 
 |         if (PyUnicode_CompareWithASCIIString(name, p->name) == 0) { | 
 |             if (p->initfunc == NULL) { | 
 |                 PyErr_Format(PyExc_ImportError, | 
 |                     "Cannot re-init internal module %R", | 
 |                     name); | 
 |                 return -1; | 
 |             } | 
 |             if (Py_VerboseFlag) | 
 |                 PySys_FormatStderr("import %U # builtin\n", name); | 
 |             mod = (*p->initfunc)(); | 
 |             if (mod == 0) | 
 |                 return -1; | 
 |             if (_PyImport_FixupExtensionObject(mod, name, name) < 0) | 
 |                 return -1; | 
 |             /* FixupExtension has put the module into sys.modules, | 
 |                so we can release our own reference. */ | 
 |             Py_DECREF(mod); | 
 |             return 1; | 
 |         } | 
 |     } | 
 |     return 0; | 
 | } | 
 |  | 
 |  | 
 | /* Frozen modules */ | 
 |  | 
 | static struct _frozen * | 
 | find_frozen(PyObject *name) | 
 | { | 
 |     struct _frozen *p; | 
 |  | 
 |     if (name == NULL) | 
 |         return NULL; | 
 |  | 
 |     for (p = PyImport_FrozenModules; ; p++) { | 
 |         if (p->name == NULL) | 
 |             return NULL; | 
 |         if (PyUnicode_CompareWithASCIIString(name, p->name) == 0) | 
 |             break; | 
 |     } | 
 |     return p; | 
 | } | 
 |  | 
 | static PyObject * | 
 | get_frozen_object(PyObject *name) | 
 | { | 
 |     struct _frozen *p = find_frozen(name); | 
 |     int size; | 
 |  | 
 |     if (p == NULL) { | 
 |         PyErr_Format(PyExc_ImportError, | 
 |                      "No such frozen object named %R", | 
 |                      name); | 
 |         return NULL; | 
 |     } | 
 |     if (p->code == NULL) { | 
 |         PyErr_Format(PyExc_ImportError, | 
 |                      "Excluded frozen object named %R", | 
 |                      name); | 
 |         return NULL; | 
 |     } | 
 |     size = p->size; | 
 |     if (size < 0) | 
 |         size = -size; | 
 |     return PyMarshal_ReadObjectFromString((char *)p->code, size); | 
 | } | 
 |  | 
 | static PyObject * | 
 | is_frozen_package(PyObject *name) | 
 | { | 
 |     struct _frozen *p = find_frozen(name); | 
 |     int size; | 
 |  | 
 |     if (p == NULL) { | 
 |         PyErr_Format(PyExc_ImportError, | 
 |                      "No such frozen object named %R", | 
 |                      name); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     size = p->size; | 
 |  | 
 |     if (size < 0) | 
 |         Py_RETURN_TRUE; | 
 |     else | 
 |         Py_RETURN_FALSE; | 
 | } | 
 |  | 
 |  | 
 | /* Initialize a frozen module. | 
 |    Return 1 for success, 0 if the module is not found, and -1 with | 
 |    an exception set if the initialization failed. | 
 |    This function is also used from frozenmain.c */ | 
 |  | 
 | int | 
 | PyImport_ImportFrozenModuleObject(PyObject *name) | 
 | { | 
 |     struct _frozen *p; | 
 |     PyObject *co, *m, *path; | 
 |     int ispackage; | 
 |     int size; | 
 |  | 
 |     p = find_frozen(name); | 
 |  | 
 |     if (p == NULL) | 
 |         return 0; | 
 |     if (p->code == NULL) { | 
 |         PyErr_Format(PyExc_ImportError, | 
 |                      "Excluded frozen object named %R", | 
 |                      name); | 
 |         return -1; | 
 |     } | 
 |     size = p->size; | 
 |     ispackage = (size < 0); | 
 |     if (ispackage) | 
 |         size = -size; | 
 |     if (Py_VerboseFlag) | 
 |         PySys_FormatStderr("import %U # frozen%s\n", | 
 |             name, ispackage ? " package" : ""); | 
 |     co = PyMarshal_ReadObjectFromString((char *)p->code, size); | 
 |     if (co == NULL) | 
 |         return -1; | 
 |     if (!PyCode_Check(co)) { | 
 |         PyErr_Format(PyExc_TypeError, | 
 |                      "frozen object %R is not a code object", | 
 |                      name); | 
 |         goto err_return; | 
 |     } | 
 |     if (ispackage) { | 
 |         /* Set __path__ to the package name */ | 
 |         PyObject *d, *l; | 
 |         int err; | 
 |         m = PyImport_AddModuleObject(name); | 
 |         if (m == NULL) | 
 |             goto err_return; | 
 |         d = PyModule_GetDict(m); | 
 |         l = PyList_New(1); | 
 |         if (l == NULL) { | 
 |             goto err_return; | 
 |         } | 
 |         Py_INCREF(name); | 
 |         PyList_SET_ITEM(l, 0, name); | 
 |         err = PyDict_SetItemString(d, "__path__", l); | 
 |         Py_DECREF(l); | 
 |         if (err != 0) | 
 |             goto err_return; | 
 |     } | 
 |     path = PyUnicode_FromString("<frozen>"); | 
 |     if (path == NULL) | 
 |         goto err_return; | 
 |     m = PyImport_ExecCodeModuleObject(name, co, path, NULL); | 
 |     Py_DECREF(path); | 
 |     if (m == NULL) | 
 |         goto err_return; | 
 |     Py_DECREF(co); | 
 |     Py_DECREF(m); | 
 |     return 1; | 
 | err_return: | 
 |     Py_DECREF(co); | 
 |     return -1; | 
 | } | 
 |  | 
 | int | 
 | PyImport_ImportFrozenModule(char *name) | 
 | { | 
 |     PyObject *nameobj; | 
 |     int ret; | 
 |     nameobj = PyUnicode_InternFromString(name); | 
 |     if (nameobj == NULL) | 
 |         return -1; | 
 |     ret = PyImport_ImportFrozenModuleObject(nameobj); | 
 |     Py_DECREF(nameobj); | 
 |     return ret; | 
 | } | 
 |  | 
 |  | 
 | /* Import a module, either built-in, frozen, or external, and return | 
 |    its module object WITH INCREMENTED REFERENCE COUNT */ | 
 |  | 
 | PyObject * | 
 | PyImport_ImportModule(const char *name) | 
 | { | 
 |     PyObject *pname; | 
 |     PyObject *result; | 
 |  | 
 |     pname = PyUnicode_FromString(name); | 
 |     if (pname == NULL) | 
 |         return NULL; | 
 |     result = PyImport_Import(pname); | 
 |     Py_DECREF(pname); | 
 |     return result; | 
 | } | 
 |  | 
 | /* Import a module without blocking | 
 |  * | 
 |  * At first it tries to fetch the module from sys.modules. If the module was | 
 |  * never loaded before it loads it with PyImport_ImportModule() unless another | 
 |  * thread holds the import lock. In the latter case the function raises an | 
 |  * ImportError instead of blocking. | 
 |  * | 
 |  * Returns the module object with incremented ref count. | 
 |  */ | 
 | PyObject * | 
 | PyImport_ImportModuleNoBlock(const char *name) | 
 | { | 
 |     PyObject *nameobj, *modules, *result; | 
 |     long me; | 
 |  | 
 |     /* Try to get the module from sys.modules[name] */ | 
 |     modules = PyImport_GetModuleDict(); | 
 |     if (modules == NULL) | 
 |         return NULL; | 
 |  | 
 |     nameobj = PyUnicode_FromString(name); | 
 |     if (nameobj == NULL) | 
 |         return NULL; | 
 |     result = PyDict_GetItem(modules, nameobj); | 
 |     if (result != NULL) { | 
 |         Py_DECREF(nameobj); | 
 |         Py_INCREF(result); | 
 |         return result; | 
 |     } | 
 |     PyErr_Clear(); | 
 | #ifdef WITH_THREAD | 
 |     /* check the import lock | 
 |      * me might be -1 but I ignore the error here, the lock function | 
 |      * takes care of the problem */ | 
 |     me = PyThread_get_thread_ident(); | 
 |     if (import_lock_thread == -1 || import_lock_thread == me) { | 
 |         /* no thread or me is holding the lock */ | 
 |         result = PyImport_Import(nameobj); | 
 |     } | 
 |     else { | 
 |         PyErr_Format(PyExc_ImportError, | 
 |                      "Failed to import %R because the import lock" | 
 |                      "is held by another thread.", | 
 |                      nameobj); | 
 |         result = NULL; | 
 |     } | 
 | #else | 
 |     result = PyImport_Import(nameobj); | 
 | #endif | 
 |     Py_DECREF(nameobj); | 
 |     return result; | 
 | } | 
 |  | 
 | /* Forward declarations for helper routines */ | 
 | static PyObject *get_parent(PyObject *globals, | 
 |                             PyObject **p_name, | 
 |                             int level); | 
 | static PyObject *load_next(PyObject *mod, PyObject *altmod, | 
 |                            PyObject *inputname, PyObject **p_outputname, | 
 |                            Py_UNICODE *buf, Py_ssize_t *p_buflen, | 
 |                            Py_ssize_t bufsize); | 
 | static int mark_miss(PyObject *name); | 
 | static int ensure_fromlist(PyObject *mod, PyObject *fromlist, | 
 |                            PyObject *buf, int recursive); | 
 | static PyObject * import_submodule(PyObject *mod, PyObject *name, | 
 |                                    PyObject *fullname); | 
 |  | 
 | /* The Magnum Opus of dotted-name import :-) */ | 
 |  | 
 | static PyObject * | 
 | import_module_level(PyObject *name, PyObject *globals, PyObject *locals, | 
 |                     PyObject *fromlist, int level) | 
 | { | 
 |     Py_UNICODE buf[MAXPATHLEN+1]; | 
 |     Py_ssize_t buflen; | 
 |     Py_ssize_t bufsize = MAXPATHLEN+1; | 
 |     PyObject *parent, *head, *next, *tail, *inputname, *outputname; | 
 |     PyObject *parent_name, *ensure_name; | 
 |     const Py_UNICODE *nameunicode; | 
 |  | 
 |     nameunicode = PyUnicode_AS_UNICODE(name); | 
 |  | 
 |     if (Py_UNICODE_strchr(nameunicode, SEP) != NULL | 
 | #ifdef ALTSEP | 
 |         || Py_UNICODE_strchr(nameunicode, ALTSEP) != NULL | 
 | #endif | 
 |         ) { | 
 |         PyErr_SetString(PyExc_ImportError, | 
 |                         "Import by filename is not supported."); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     parent = get_parent(globals, &parent_name, level); | 
 |     if (parent == NULL) | 
 |         return NULL; | 
 |  | 
 |     buflen = PyUnicode_GET_SIZE(parent_name); | 
 |     if (buflen+1 > bufsize) { | 
 |         Py_DECREF(parent_name); | 
 |         PyErr_SetString(PyExc_ValueError, | 
 |                         "Module name too long"); | 
 |         return NULL; | 
 |     } | 
 |     Py_UNICODE_strcpy(buf, PyUnicode_AS_UNICODE(parent_name)); | 
 |     Py_DECREF(parent_name); | 
 |  | 
 |     head = load_next(parent, level < 0 ? Py_None : parent, name, &outputname, | 
 |                      buf, &buflen, bufsize); | 
 |     if (head == NULL) | 
 |         return NULL; | 
 |  | 
 |     tail = head; | 
 |     Py_INCREF(tail); | 
 |  | 
 |     if (outputname != NULL) { | 
 |         while (1) { | 
 |             inputname = outputname; | 
 |             next = load_next(tail, tail, inputname, &outputname, | 
 |                              buf, &buflen, bufsize); | 
 |             Py_DECREF(tail); | 
 |             Py_DECREF(inputname); | 
 |             if (next == NULL) { | 
 |                 Py_DECREF(head); | 
 |                 return NULL; | 
 |             } | 
 |             tail = next; | 
 |  | 
 |             if (outputname == NULL) { | 
 |                 break; | 
 |             } | 
 |         } | 
 |     } | 
 |     if (tail == Py_None) { | 
 |         /* If tail is Py_None, both get_parent and load_next found | 
 |            an empty module name: someone called __import__("") or | 
 |            doctored faulty bytecode */ | 
 |         Py_DECREF(tail); | 
 |         Py_DECREF(head); | 
 |         PyErr_SetString(PyExc_ValueError, "Empty module name"); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     if (fromlist != NULL) { | 
 |         if (fromlist == Py_None || !PyObject_IsTrue(fromlist)) | 
 |             fromlist = NULL; | 
 |     } | 
 |  | 
 |     if (fromlist == NULL) { | 
 |         Py_DECREF(tail); | 
 |         return head; | 
 |     } | 
 |  | 
 |     Py_DECREF(head); | 
 |  | 
 |     ensure_name = PyUnicode_FromUnicode(buf, Py_UNICODE_strlen(buf)); | 
 |     if (ensure_name == NULL) { | 
 |         Py_DECREF(tail); | 
 |         return NULL; | 
 |     } | 
 |     if (!ensure_fromlist(tail, fromlist, ensure_name, 0)) { | 
 |         Py_DECREF(tail); | 
 |         Py_DECREF(ensure_name); | 
 |         return NULL; | 
 |     } | 
 |     Py_DECREF(ensure_name); | 
 |  | 
 |     return tail; | 
 | } | 
 |  | 
 | PyObject * | 
 | PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, | 
 |                                  PyObject *locals, PyObject *fromlist, | 
 |                                  int level) | 
 | { | 
 |     PyObject *mod; | 
 |     _PyImport_AcquireLock(); | 
 |     mod = import_module_level(name, globals, locals, fromlist, level); | 
 |     if (_PyImport_ReleaseLock() < 0) { | 
 |         Py_XDECREF(mod); | 
 |         PyErr_SetString(PyExc_RuntimeError, | 
 |                         "not holding the import lock"); | 
 |         return NULL; | 
 |     } | 
 |     return mod; | 
 | } | 
 |  | 
 | PyObject * | 
 | PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, | 
 |                            PyObject *fromlist, int level) | 
 | { | 
 |     PyObject *nameobj, *mod; | 
 |     nameobj = PyUnicode_FromString(name); | 
 |     if (nameobj == NULL) | 
 |         return NULL; | 
 |     mod = PyImport_ImportModuleLevelObject(nameobj, globals, locals, | 
 |                                            fromlist, level); | 
 |     Py_DECREF(nameobj); | 
 |     return mod; | 
 | } | 
 |  | 
 |  | 
 | /* Return the package that an import is being performed in.  If globals comes | 
 |    from the module foo.bar.bat (not itself a package), this returns the | 
 |    sys.modules entry for foo.bar.  If globals is from a package's __init__.py, | 
 |    the package's entry in sys.modules is returned, as a borrowed reference. | 
 |  | 
 |    The name of the returned package is returned in *p_name. | 
 |  | 
 |    If globals doesn't come from a package or a module in a package, or a | 
 |    corresponding entry is not found in sys.modules, Py_None is returned. | 
 | */ | 
 | static PyObject * | 
 | get_parent(PyObject *globals, PyObject **p_name, int level) | 
 | { | 
 |     Py_UNICODE name[MAXPATHLEN+1]; | 
 |     const Py_ssize_t bufsize = MAXPATHLEN+1; | 
 |     PyObject *nameobj; | 
 |  | 
 |     static PyObject *namestr = NULL; | 
 |     static PyObject *pathstr = NULL; | 
 |     static PyObject *pkgstr = NULL; | 
 |     PyObject *pkgname, *modname, *modpath, *modules, *parent; | 
 |     int orig_level = level; | 
 |  | 
 |     if (globals == NULL || !PyDict_Check(globals) || !level) | 
 |         goto return_none; | 
 |  | 
 |     if (namestr == NULL) { | 
 |         namestr = PyUnicode_InternFromString("__name__"); | 
 |         if (namestr == NULL) | 
 |             return NULL; | 
 |     } | 
 |     if (pathstr == NULL) { | 
 |         pathstr = PyUnicode_InternFromString("__path__"); | 
 |         if (pathstr == NULL) | 
 |             return NULL; | 
 |     } | 
 |     if (pkgstr == NULL) { | 
 |         pkgstr = PyUnicode_InternFromString("__package__"); | 
 |         if (pkgstr == NULL) | 
 |             return NULL; | 
 |     } | 
 |  | 
 |     pkgname = PyDict_GetItem(globals, pkgstr); | 
 |  | 
 |     if ((pkgname != NULL) && (pkgname != Py_None)) { | 
 |         /* __package__ is set, so use it */ | 
 |         if (!PyUnicode_Check(pkgname)) { | 
 |             PyErr_SetString(PyExc_ValueError, | 
 |                             "__package__ set to non-string"); | 
 |             return NULL; | 
 |         } | 
 |         if (PyUnicode_GET_SIZE(pkgname) == 0) { | 
 |             if (level > 0) { | 
 |                 PyErr_SetString(PyExc_ValueError, | 
 |                     "Attempted relative import in non-package"); | 
 |                 return NULL; | 
 |             } | 
 |             goto return_none; | 
 |         } | 
 |         if (PyUnicode_GET_SIZE(pkgname)+1 > bufsize) { | 
 |             PyErr_SetString(PyExc_ValueError, | 
 |                             "Package name too long"); | 
 |             return NULL; | 
 |         } | 
 |         Py_UNICODE_strcpy(name, PyUnicode_AS_UNICODE(pkgname)); | 
 |     } else { | 
 |         /* __package__ not set, so figure it out and set it */ | 
 |         modname = PyDict_GetItem(globals, namestr); | 
 |         if (modname == NULL || !PyUnicode_Check(modname)) | 
 |             goto return_none; | 
 |  | 
 |         modpath = PyDict_GetItem(globals, pathstr); | 
 |         if (modpath != NULL) { | 
 |             /* __path__ is set, so modname is already the package name */ | 
 |             int error; | 
 |  | 
 |             if (PyUnicode_GET_SIZE(modname)+1 > bufsize) { | 
 |                 PyErr_SetString(PyExc_ValueError, | 
 |                                 "Module name too long"); | 
 |                 return NULL; | 
 |             } | 
 |             Py_UNICODE_strcpy(name, PyUnicode_AS_UNICODE(modname)); | 
 |             error = PyDict_SetItem(globals, pkgstr, modname); | 
 |             if (error) { | 
 |                 PyErr_SetString(PyExc_ValueError, | 
 |                                 "Could not set __package__"); | 
 |                 return NULL; | 
 |             } | 
 |         } else { | 
 |             /* Normal module, so work out the package name if any */ | 
 |             Py_UNICODE *start = PyUnicode_AS_UNICODE(modname); | 
 |             Py_UNICODE *lastdot = Py_UNICODE_strrchr(start, '.'); | 
 |             Py_ssize_t len; | 
 |             int error; | 
 |             if (lastdot == NULL && level > 0) { | 
 |                 PyErr_SetString(PyExc_ValueError, | 
 |                     "Attempted relative import in non-package"); | 
 |                 return NULL; | 
 |             } | 
 |             if (lastdot == NULL) { | 
 |                 error = PyDict_SetItem(globals, pkgstr, Py_None); | 
 |                 if (error) { | 
 |                     PyErr_SetString(PyExc_ValueError, | 
 |                         "Could not set __package__"); | 
 |                     return NULL; | 
 |                 } | 
 |                 goto return_none; | 
 |             } | 
 |             len = lastdot - start; | 
 |             if (len+1 > bufsize) { | 
 |                 PyErr_SetString(PyExc_ValueError, | 
 |                                 "Module name too long"); | 
 |                 return NULL; | 
 |             } | 
 |             Py_UNICODE_strncpy(name, start, len); | 
 |             name[len] = '\0'; | 
 |             pkgname = PyUnicode_FromUnicode(name, len); | 
 |             if (pkgname == NULL) { | 
 |                 return NULL; | 
 |             } | 
 |             error = PyDict_SetItem(globals, pkgstr, pkgname); | 
 |             Py_DECREF(pkgname); | 
 |             if (error) { | 
 |                 PyErr_SetString(PyExc_ValueError, | 
 |                                 "Could not set __package__"); | 
 |                 return NULL; | 
 |             } | 
 |         } | 
 |     } | 
 |     while (--level > 0) { | 
 |         Py_UNICODE *dot = Py_UNICODE_strrchr(name, '.'); | 
 |         if (dot == NULL) { | 
 |             PyErr_SetString(PyExc_ValueError, | 
 |                 "Attempted relative import beyond " | 
 |                 "toplevel package"); | 
 |             return NULL; | 
 |         } | 
 |         *dot = '\0'; | 
 |     } | 
 |  | 
 |     nameobj = PyUnicode_FromUnicode(name, Py_UNICODE_strlen(name)); | 
 |     if (nameobj == NULL) | 
 |         return NULL; | 
 |  | 
 |     modules = PyImport_GetModuleDict(); | 
 |     parent = PyDict_GetItem(modules, nameobj); | 
 |     if (parent == NULL) { | 
 |         int err; | 
 |  | 
 |         if (orig_level >= 1) { | 
 |             PyErr_Format(PyExc_SystemError, | 
 |                 "Parent module %R not loaded, " | 
 |                 "cannot perform relative import", nameobj); | 
 |             Py_DECREF(nameobj); | 
 |             return NULL; | 
 |         } | 
 |  | 
 |         err = PyErr_WarnFormat( | 
 |             PyExc_RuntimeWarning, 1, | 
 |             "Parent module %R not found while handling absolute import", | 
 |             nameobj); | 
 |         Py_DECREF(nameobj); | 
 |         if (err) | 
 |             return NULL; | 
 |  | 
 |         goto return_none; | 
 |     } | 
 |     *p_name = nameobj; | 
 |     return parent; | 
 |     /* We expect, but can't guarantee, if parent != None, that: | 
 |        - parent.__name__ == name | 
 |        - parent.__dict__ is globals | 
 |        If this is violated...  Who cares? */ | 
 |  | 
 | return_none: | 
 |     nameobj = PyUnicode_FromUnicode(NULL, 0); | 
 |     if (nameobj == NULL) | 
 |         return NULL; | 
 |     *p_name = nameobj; | 
 |     return Py_None; | 
 | } | 
 |  | 
 | /* altmod is either None or same as mod */ | 
 | static PyObject * | 
 | load_next(PyObject *mod, PyObject *altmod, | 
 |           PyObject *inputname, PyObject **p_outputname, | 
 |           Py_UNICODE *buf, Py_ssize_t *p_buflen, Py_ssize_t bufsize) | 
 | { | 
 |     const Py_UNICODE *dot; | 
 |     Py_ssize_t len; | 
 |     Py_UNICODE *p; | 
 |     PyObject *fullname, *name, *result, *mark_name; | 
 |     const Py_UNICODE *nameuni; | 
 |  | 
 |     *p_outputname = NULL; | 
 |  | 
 |     if (PyUnicode_GET_SIZE(inputname) == 0) { | 
 |         /* completely empty module name should only happen in | 
 |            'from . import' (or '__import__("")')*/ | 
 |         Py_INCREF(mod); | 
 |         return mod; | 
 |     } | 
 |  | 
 |     nameuni = PyUnicode_AS_UNICODE(inputname); | 
 |     if (nameuni == NULL) | 
 |         return NULL; | 
 |  | 
 |     dot = Py_UNICODE_strchr(nameuni, '.'); | 
 |     if (dot != NULL) { | 
 |         len = dot - nameuni; | 
 |         if (len == 0) { | 
 |             PyErr_SetString(PyExc_ValueError, | 
 |                             "Empty module name"); | 
 |             return NULL; | 
 |         } | 
 |     } | 
 |     else | 
 |         len = PyUnicode_GET_SIZE(inputname); | 
 |  | 
 |     if (*p_buflen+len+1 >= bufsize) { | 
 |         PyErr_SetString(PyExc_ValueError, | 
 |                         "Module name too long"); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     p = buf + *p_buflen; | 
 |     if (p != buf) { | 
 |         *p++ = '.'; | 
 |         *p_buflen += 1; | 
 |     } | 
 |     Py_UNICODE_strncpy(p, nameuni, len); | 
 |     p[len] = '\0'; | 
 |     *p_buflen += len; | 
 |  | 
 |     fullname = PyUnicode_FromUnicode(buf, *p_buflen); | 
 |     if (fullname == NULL) | 
 |         return NULL; | 
 |     name = PyUnicode_FromUnicode(p, len); | 
 |     if (name == NULL) { | 
 |         Py_DECREF(fullname); | 
 |         return NULL; | 
 |     } | 
 |     result = import_submodule(mod, name, fullname); | 
 |     Py_DECREF(fullname); | 
 |     if (result == Py_None && altmod != mod) { | 
 |         Py_DECREF(result); | 
 |         /* Here, altmod must be None and mod must not be None */ | 
 |         result = import_submodule(altmod, name, name); | 
 |         Py_DECREF(name); | 
 |         if (result != NULL && result != Py_None) { | 
 |             mark_name = PyUnicode_FromUnicode(buf, *p_buflen); | 
 |             if (mark_name == NULL) { | 
 |                 Py_DECREF(result); | 
 |                 return NULL; | 
 |             } | 
 |             if (mark_miss(mark_name) != 0) { | 
 |                 Py_DECREF(result); | 
 |                 Py_DECREF(mark_name); | 
 |                 return NULL; | 
 |             } | 
 |             Py_DECREF(mark_name); | 
 |             Py_UNICODE_strncpy(buf, nameuni, len); | 
 |             buf[len] = '\0'; | 
 |             *p_buflen = len; | 
 |         } | 
 |     } | 
 |     else | 
 |         Py_DECREF(name); | 
 |     if (result == NULL) | 
 |         return NULL; | 
 |  | 
 |     if (result == Py_None) { | 
 |         Py_DECREF(result); | 
 |         PyErr_Format(PyExc_ImportError, | 
 |                      "No module named %R", inputname); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     if (dot != NULL) { | 
 |         *p_outputname = PyUnicode_FromUnicode(dot+1, Py_UNICODE_strlen(dot+1)); | 
 |         if (*p_outputname == NULL) { | 
 |             Py_DECREF(result); | 
 |             return NULL; | 
 |         } | 
 |     } | 
 |  | 
 |     return result; | 
 | } | 
 |  | 
 | static int | 
 | mark_miss(PyObject *name) | 
 | { | 
 |     PyObject *modules = PyImport_GetModuleDict(); | 
 |     return PyDict_SetItem(modules, name, Py_None); | 
 | } | 
 |  | 
 | static int | 
 | ensure_fromlist(PyObject *mod, PyObject *fromlist, PyObject *name, | 
 |                 int recursive) | 
 | { | 
 |     int i; | 
 |     PyObject *fullname; | 
 |     Py_ssize_t fromlist_len; | 
 |  | 
 |     if (!PyObject_HasAttrString(mod, "__path__")) | 
 |         return 1; | 
 |  | 
 |     fromlist_len = PySequence_Size(fromlist); | 
 |  | 
 |     for (i = 0; i < fromlist_len; i++) { | 
 |         PyObject *item = PySequence_GetItem(fromlist, i); | 
 |         int hasit; | 
 |         if (item == NULL) | 
 |             return 0; | 
 |         if (!PyUnicode_Check(item)) { | 
 |             PyErr_SetString(PyExc_TypeError, | 
 |                             "Item in ``from list'' not a string"); | 
 |             Py_DECREF(item); | 
 |             return 0; | 
 |         } | 
 |         if (PyUnicode_AS_UNICODE(item)[0] == '*') { | 
 |             PyObject *all; | 
 |             Py_DECREF(item); | 
 |             /* See if the package defines __all__ */ | 
 |             if (recursive) | 
 |                 continue; /* Avoid endless recursion */ | 
 |             all = PyObject_GetAttrString(mod, "__all__"); | 
 |             if (all == NULL) | 
 |                 PyErr_Clear(); | 
 |             else { | 
 |                 int ret = ensure_fromlist(mod, all, name, 1); | 
 |                 Py_DECREF(all); | 
 |                 if (!ret) | 
 |                     return 0; | 
 |             } | 
 |             continue; | 
 |         } | 
 |         hasit = PyObject_HasAttr(mod, item); | 
 |         if (!hasit) { | 
 |             PyObject *submod; | 
 |             fullname = PyUnicode_FromFormat("%U.%U", name, item); | 
 |             if (fullname != NULL) { | 
 |                 submod = import_submodule(mod, item, fullname); | 
 |                 Py_DECREF(fullname); | 
 |             } | 
 |             else | 
 |                 submod = NULL; | 
 |             Py_XDECREF(submod); | 
 |             if (submod == NULL) { | 
 |                 Py_DECREF(item); | 
 |                 return 0; | 
 |             } | 
 |         } | 
 |         Py_DECREF(item); | 
 |     } | 
 |  | 
 |     return 1; | 
 | } | 
 |  | 
 | static int | 
 | add_submodule(PyObject *mod, PyObject *submod, PyObject *fullname, | 
 |               PyObject *subname, PyObject *modules) | 
 | { | 
 |     if (mod == Py_None) | 
 |         return 1; | 
 |     /* Irrespective of the success of this load, make a | 
 |        reference to it in the parent package module.  A copy gets | 
 |        saved in the modules dictionary under the full name, so get a | 
 |        reference from there, if need be.  (The exception is when the | 
 |        load failed with a SyntaxError -- then there's no trace in | 
 |        sys.modules.  In that case, of course, do nothing extra.) */ | 
 |     if (submod == NULL) { | 
 |         submod = PyDict_GetItem(modules, fullname); | 
 |         if (submod == NULL) | 
 |             return 1; | 
 |     } | 
 |     if (PyModule_Check(mod)) { | 
 |         /* We can't use setattr here since it can give a | 
 |          * spurious warning if the submodule name shadows a | 
 |          * builtin name */ | 
 |         PyObject *dict = PyModule_GetDict(mod); | 
 |         if (!dict) | 
 |             return 0; | 
 |         if (PyDict_SetItem(dict, subname, submod) < 0) | 
 |             return 0; | 
 |     } | 
 |     else { | 
 |         if (PyObject_SetAttr(mod, subname, submod) < 0) | 
 |             return 0; | 
 |     } | 
 |     return 1; | 
 | } | 
 |  | 
 | static PyObject * | 
 | import_submodule(PyObject *mod, PyObject *subname, PyObject *fullname) | 
 | { | 
 |     PyObject *modules = PyImport_GetModuleDict(); | 
 |     PyObject *m = NULL, *bufobj, *path_list, *loader; | 
 |     struct filedescr *fdp; | 
 |     FILE *fp; | 
 |  | 
 |     /* Require: | 
 |        if mod == None: subname == fullname | 
 |        else: mod.__name__ + "." + subname == fullname | 
 |     */ | 
 |  | 
 |     if ((m = PyDict_GetItem(modules, fullname)) != NULL) { | 
 |         Py_INCREF(m); | 
 |         return m; | 
 |     } | 
 |  | 
 |     if (mod == Py_None) | 
 |         path_list = NULL; | 
 |     else { | 
 |         path_list = PyObject_GetAttrString(mod, "__path__"); | 
 |         if (path_list == NULL) { | 
 |             PyErr_Clear(); | 
 |             Py_INCREF(Py_None); | 
 |             return Py_None; | 
 |         } | 
 |     } | 
 |  | 
 |     fdp = find_module(fullname, subname, path_list, | 
 |                       &bufobj, &fp, &loader); | 
 |     Py_XDECREF(path_list); | 
 |     if (fdp == NULL) { | 
 |         if (!PyErr_ExceptionMatches(PyExc_ImportError)) | 
 |             return NULL; | 
 |         PyErr_Clear(); | 
 |         Py_INCREF(Py_None); | 
 |         return Py_None; | 
 |     } | 
 |     m = load_module(fullname, fp, bufobj, fdp->type, loader); | 
 |     Py_XDECREF(bufobj); | 
 |     Py_XDECREF(loader); | 
 |     if (fp) | 
 |         fclose(fp); | 
 |     if (m == NULL) | 
 |         return NULL; | 
 |     if (!add_submodule(mod, m, fullname, subname, modules)) { | 
 |         Py_XDECREF(m); | 
 |         return NULL; | 
 |     } | 
 |     return m; | 
 | } | 
 |  | 
 |  | 
 | /* Re-import a module of any kind and return its module object, WITH | 
 |    INCREMENTED REFERENCE COUNT */ | 
 |  | 
 | PyObject * | 
 | PyImport_ReloadModule(PyObject *m) | 
 | { | 
 |     PyInterpreterState *interp = PyThreadState_Get()->interp; | 
 |     PyObject *modules_reloading = interp->modules_reloading; | 
 |     PyObject *modules = PyImport_GetModuleDict(); | 
 |     PyObject *path_list = NULL, *loader = NULL, *existing_m = NULL; | 
 |     PyObject *nameobj, *bufobj, *subnameobj; | 
 |     Py_UNICODE *name, *subname; | 
 |     struct filedescr *fdp; | 
 |     FILE *fp = NULL; | 
 |     PyObject *newm = NULL; | 
 |  | 
 |     if (modules_reloading == NULL) { | 
 |         Py_FatalError("PyImport_ReloadModule: " | 
 |                       "no modules_reloading dictionary!"); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     if (m == NULL || !PyModule_Check(m)) { | 
 |         PyErr_SetString(PyExc_TypeError, | 
 |                         "reload() argument must be module"); | 
 |         return NULL; | 
 |     } | 
 |     nameobj = PyModule_GetNameObject(m); | 
 |     if (nameobj == NULL) | 
 |         return NULL; | 
 |     if (m != PyDict_GetItem(modules, nameobj)) { | 
 |         PyErr_Format(PyExc_ImportError, | 
 |                      "reload(): module %R not in sys.modules", | 
 |                      nameobj); | 
 |         Py_DECREF(nameobj); | 
 |         return NULL; | 
 |     } | 
 |     existing_m = PyDict_GetItem(modules_reloading, nameobj); | 
 |     if (existing_m != NULL) { | 
 |         /* Due to a recursive reload, this module is already | 
 |            being reloaded. */ | 
 |         Py_DECREF(nameobj); | 
 |         Py_INCREF(existing_m); | 
 |         return existing_m; | 
 |     } | 
 |     if (PyDict_SetItem(modules_reloading, nameobj, m) < 0) { | 
 |         Py_DECREF(nameobj); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     name = PyUnicode_AS_UNICODE(nameobj); | 
 |     subname = Py_UNICODE_strrchr(name, '.'); | 
 |     if (subname == NULL) { | 
 |         Py_INCREF(nameobj); | 
 |         subnameobj = nameobj; | 
 |     } | 
 |     else { | 
 |         PyObject *parentname, *parent; | 
 |         Py_ssize_t len; | 
 |         len = subname - name; | 
 |         parentname = PyUnicode_FromUnicode(name, len); | 
 |         if (parentname == NULL) { | 
 |             goto error; | 
 |         } | 
 |         parent = PyDict_GetItem(modules, parentname); | 
 |         if (parent == NULL) { | 
 |             PyErr_Format(PyExc_ImportError, | 
 |                 "reload(): parent %R not in sys.modules", | 
 |                  parentname); | 
 |             Py_DECREF(parentname); | 
 |             goto error; | 
 |         } | 
 |         Py_DECREF(parentname); | 
 |         path_list = PyObject_GetAttrString(parent, "__path__"); | 
 |         if (path_list == NULL) | 
 |             PyErr_Clear(); | 
 |         subname++; | 
 |         len = PyUnicode_GET_SIZE(nameobj) - (len + 1); | 
 |         subnameobj = PyUnicode_FromUnicode(subname, len); | 
 |     } | 
 |     if (subnameobj == NULL) | 
 |         goto error; | 
 |     fdp = find_module(nameobj, subnameobj, path_list, | 
 |                       &bufobj, &fp, &loader); | 
 |     Py_DECREF(subnameobj); | 
 |     Py_XDECREF(path_list); | 
 |  | 
 |     if (fdp == NULL) { | 
 |         Py_XDECREF(loader); | 
 |         goto error; | 
 |     } | 
 |  | 
 |     newm = load_module(nameobj, fp, bufobj, fdp->type, loader); | 
 |     Py_XDECREF(bufobj); | 
 |     Py_XDECREF(loader); | 
 |  | 
 |     if (fp) | 
 |         fclose(fp); | 
 |     if (newm == NULL) { | 
 |         /* load_module probably removed name from modules because of | 
 |          * the error.  Put back the original module object.  We're | 
 |          * going to return NULL in this case regardless of whether | 
 |          * replacing name succeeds, so the return value is ignored. | 
 |          */ | 
 |         PyDict_SetItem(modules, nameobj, m); | 
 |     } | 
 |  | 
 | error: | 
 |     imp_modules_reloading_clear(); | 
 |     Py_DECREF(nameobj); | 
 |     return newm; | 
 | } | 
 |  | 
 |  | 
 | /* Higher-level import emulator which emulates the "import" statement | 
 |    more accurately -- it invokes the __import__() function from the | 
 |    builtins of the current globals.  This means that the import is | 
 |    done using whatever import hooks are installed in the current | 
 |    environment. | 
 |    A dummy list ["__doc__"] is passed as the 4th argument so that | 
 |    e.g. PyImport_Import(PyUnicode_FromString("win32com.client.gencache")) | 
 |    will return <module "gencache"> instead of <module "win32com">. */ | 
 |  | 
 | PyObject * | 
 | PyImport_Import(PyObject *module_name) | 
 | { | 
 |     static PyObject *silly_list = NULL; | 
 |     static PyObject *builtins_str = NULL; | 
 |     static PyObject *import_str = NULL; | 
 |     PyObject *globals = NULL; | 
 |     PyObject *import = NULL; | 
 |     PyObject *builtins = NULL; | 
 |     PyObject *modules = NULL; | 
 |     PyObject *r = NULL; | 
 |  | 
 |     /* Initialize constant string objects */ | 
 |     if (silly_list == NULL) { | 
 |         import_str = PyUnicode_InternFromString("__import__"); | 
 |         if (import_str == NULL) | 
 |             return NULL; | 
 |         builtins_str = PyUnicode_InternFromString("__builtins__"); | 
 |         if (builtins_str == NULL) | 
 |             return NULL; | 
 |         silly_list = PyList_New(0); | 
 |         if (silly_list == NULL) | 
 |             return NULL; | 
 |     } | 
 |  | 
 |     /* Get the builtins from current globals */ | 
 |     globals = PyEval_GetGlobals(); | 
 |     if (globals != NULL) { | 
 |         Py_INCREF(globals); | 
 |         builtins = PyObject_GetItem(globals, builtins_str); | 
 |         if (builtins == NULL) | 
 |             goto err; | 
 |     } | 
 |     else { | 
 |         /* No globals -- use standard builtins, and fake globals */ | 
 |         builtins = PyImport_ImportModuleLevel("builtins", | 
 |                                               NULL, NULL, NULL, 0); | 
 |         if (builtins == NULL) | 
 |             return NULL; | 
 |         globals = Py_BuildValue("{OO}", builtins_str, builtins); | 
 |         if (globals == NULL) | 
 |             goto err; | 
 |     } | 
 |  | 
 |     /* Get the __import__ function from the builtins */ | 
 |     if (PyDict_Check(builtins)) { | 
 |         import = PyObject_GetItem(builtins, import_str); | 
 |         if (import == NULL) | 
 |             PyErr_SetObject(PyExc_KeyError, import_str); | 
 |     } | 
 |     else | 
 |         import = PyObject_GetAttr(builtins, import_str); | 
 |     if (import == NULL) | 
 |         goto err; | 
 |  | 
 |     /* Call the __import__ function with the proper argument list | 
 |        Always use absolute import here. | 
 |        Calling for side-effect of import. */ | 
 |     r = PyObject_CallFunction(import, "OOOOi", module_name, globals, | 
 |                               globals, silly_list, 0, NULL); | 
 |     if (r == NULL) | 
 |         goto err; | 
 |     Py_DECREF(r); | 
 |  | 
 |     modules = PyImport_GetModuleDict(); | 
 |     r = PyDict_GetItem(modules, module_name); | 
 |     if (r != NULL) | 
 |         Py_INCREF(r); | 
 |  | 
 |   err: | 
 |     Py_XDECREF(globals); | 
 |     Py_XDECREF(builtins); | 
 |     Py_XDECREF(import); | 
 |  | 
 |     return r; | 
 | } | 
 |  | 
 |  | 
 | /* Module 'imp' provides Python access to the primitives used for | 
 |    importing modules. | 
 | */ | 
 |  | 
 | static PyObject * | 
 | imp_make_magic(long magic) | 
 | { | 
 |     char buf[4]; | 
 |  | 
 |     buf[0] = (char) ((magic >>  0) & 0xff); | 
 |     buf[1] = (char) ((magic >>  8) & 0xff); | 
 |     buf[2] = (char) ((magic >> 16) & 0xff); | 
 |     buf[3] = (char) ((magic >> 24) & 0xff); | 
 |  | 
 |     return PyBytes_FromStringAndSize(buf, 4); | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_get_magic(PyObject *self, PyObject *noargs) | 
 | { | 
 |     return imp_make_magic(pyc_magic); | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_get_tag(PyObject *self, PyObject *noargs) | 
 | { | 
 |     return PyUnicode_FromString(pyc_tag); | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_get_suffixes(PyObject *self, PyObject *noargs) | 
 | { | 
 |     PyObject *list; | 
 |     struct filedescr *fdp; | 
 |  | 
 |     list = PyList_New(0); | 
 |     if (list == NULL) | 
 |         return NULL; | 
 |     for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) { | 
 |         PyObject *item = Py_BuildValue("ssi", | 
 |                                fdp->suffix, fdp->mode, fdp->type); | 
 |         if (item == NULL) { | 
 |             Py_DECREF(list); | 
 |             return NULL; | 
 |         } | 
 |         if (PyList_Append(list, item) < 0) { | 
 |             Py_DECREF(list); | 
 |             Py_DECREF(item); | 
 |             return NULL; | 
 |         } | 
 |         Py_DECREF(item); | 
 |     } | 
 |     return list; | 
 | } | 
 |  | 
 | static PyObject * | 
 | call_find_module(PyObject *name, PyObject *path_list) | 
 | { | 
 |     extern int fclose(FILE *); | 
 |     PyObject *fob, *ret; | 
 |     PyObject *pathobj; | 
 |     struct filedescr *fdp; | 
 |     FILE *fp; | 
 |     int fd = -1; | 
 |     char *found_encoding = NULL; | 
 |     char *encoding = NULL; | 
 |  | 
 |     if (path_list == Py_None) | 
 |         path_list = NULL; | 
 |     fdp = find_module(NULL, name, path_list, | 
 |                       &pathobj, &fp, NULL); | 
 |     if (fdp == NULL) | 
 |         return NULL; | 
 |     if (fp != NULL) { | 
 |         fd = fileno(fp); | 
 |         if (fd != -1) | 
 |             fd = dup(fd); | 
 |         fclose(fp); | 
 |         fp = NULL; | 
 |     } | 
 |     if (fd != -1) { | 
 |         if (strchr(fdp->mode, 'b') == NULL) { | 
 |             /* PyTokenizer_FindEncoding() returns PyMem_MALLOC'ed | 
 |                memory. */ | 
 |             found_encoding = PyTokenizer_FindEncoding(fd); | 
 |             lseek(fd, 0, 0); /* Reset position */ | 
 |             if (found_encoding == NULL && PyErr_Occurred()) { | 
 |                 Py_XDECREF(pathobj); | 
 |                 return NULL; | 
 |             } | 
 |             encoding = (found_encoding != NULL) ? found_encoding : | 
 |                    (char*)PyUnicode_GetDefaultEncoding(); | 
 |         } | 
 |         fob = PyFile_FromFd(fd, NULL, fdp->mode, -1, | 
 |                             (char*)encoding, NULL, NULL, 1); | 
 |         if (fob == NULL) { | 
 |             Py_XDECREF(pathobj); | 
 |             close(fd); | 
 |             PyMem_FREE(found_encoding); | 
 |             return NULL; | 
 |         } | 
 |     } | 
 |     else { | 
 |         fob = Py_None; | 
 |         Py_INCREF(fob); | 
 |     } | 
 |     if (pathobj == NULL) { | 
 |         Py_INCREF(Py_None); | 
 |         pathobj = Py_None; | 
 |     } | 
 |     ret = Py_BuildValue("NN(ssi)", | 
 |                   fob, pathobj, fdp->suffix, fdp->mode, fdp->type); | 
 |     PyMem_FREE(found_encoding); | 
 |  | 
 |     return ret; | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_find_module(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name, *path_list = NULL; | 
 |     if (!PyArg_ParseTuple(args, "U|O:find_module", | 
 |                           &name, &path_list)) | 
 |         return NULL; | 
 |     return call_find_module(name, path_list); | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_init_builtin(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name; | 
 |     int ret; | 
 |     PyObject *m; | 
 |     if (!PyArg_ParseTuple(args, "U:init_builtin", &name)) | 
 |         return NULL; | 
 |     ret = init_builtin(name); | 
 |     if (ret < 0) | 
 |         return NULL; | 
 |     if (ret == 0) { | 
 |         Py_INCREF(Py_None); | 
 |         return Py_None; | 
 |     } | 
 |     m = PyImport_AddModuleObject(name); | 
 |     Py_XINCREF(m); | 
 |     return m; | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_init_frozen(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name; | 
 |     int ret; | 
 |     PyObject *m; | 
 |     if (!PyArg_ParseTuple(args, "U:init_frozen", &name)) | 
 |         return NULL; | 
 |     ret = PyImport_ImportFrozenModuleObject(name); | 
 |     if (ret < 0) | 
 |         return NULL; | 
 |     if (ret == 0) { | 
 |         Py_INCREF(Py_None); | 
 |         return Py_None; | 
 |     } | 
 |     m = PyImport_AddModuleObject(name); | 
 |     Py_XINCREF(m); | 
 |     return m; | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_get_frozen_object(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name; | 
 |  | 
 |     if (!PyArg_ParseTuple(args, "U:get_frozen_object", &name)) | 
 |         return NULL; | 
 |     return get_frozen_object(name); | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_is_frozen_package(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name; | 
 |  | 
 |     if (!PyArg_ParseTuple(args, "U:is_frozen_package", &name)) | 
 |         return NULL; | 
 |     return is_frozen_package(name); | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_is_builtin(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name; | 
 |     if (!PyArg_ParseTuple(args, "U:is_builtin", &name)) | 
 |         return NULL; | 
 |     return PyLong_FromLong(is_builtin(name)); | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_is_frozen(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name; | 
 |     struct _frozen *p; | 
 |     if (!PyArg_ParseTuple(args, "U:is_frozen", &name)) | 
 |         return NULL; | 
 |     p = find_frozen(name); | 
 |     return PyBool_FromLong((long) (p == NULL ? 0 : p->size)); | 
 | } | 
 |  | 
 | static FILE * | 
 | get_file(PyObject *pathname, PyObject *fob, char *mode) | 
 | { | 
 |     FILE *fp; | 
 |     if (mode[0] == 'U') | 
 |         mode = "r" PY_STDIOTEXTMODE; | 
 |     if (fob == NULL) { | 
 |         fp = _Py_fopen(pathname, mode); | 
 |     } | 
 |     else { | 
 |         int fd = PyObject_AsFileDescriptor(fob); | 
 |         if (fd == -1) | 
 |             return NULL; | 
 |         if (!_PyVerify_fd(fd)) | 
 |             goto error; | 
 |         /* the FILE struct gets a new fd, so that it can be closed | 
 |          * independently of the file descriptor given | 
 |          */ | 
 |         fd = dup(fd); | 
 |         if (fd == -1) | 
 |             goto error; | 
 |         fp = fdopen(fd, mode); | 
 |     } | 
 |     if (fp) | 
 |         return fp; | 
 | error: | 
 |     PyErr_SetFromErrno(PyExc_IOError); | 
 |     return NULL; | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_load_compiled(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name, *pathname; | 
 |     PyObject *fob = NULL; | 
 |     PyObject *m; | 
 |     FILE *fp; | 
 |     if (!PyArg_ParseTuple(args, "UO&|O:load_compiled", | 
 |                           &name, | 
 |                           PyUnicode_FSDecoder, &pathname, | 
 |                           &fob)) | 
 |         return NULL; | 
 |     fp = get_file(pathname, fob, "rb"); | 
 |     if (fp == NULL) { | 
 |         Py_DECREF(pathname); | 
 |         return NULL; | 
 |     } | 
 |     m = load_compiled_module(name, pathname, fp); | 
 |     fclose(fp); | 
 |     Py_DECREF(pathname); | 
 |     return m; | 
 | } | 
 |  | 
 | #ifdef HAVE_DYNAMIC_LOADING | 
 |  | 
 | static PyObject * | 
 | imp_load_dynamic(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name, *pathname, *fob = NULL, *mod; | 
 |     FILE *fp; | 
 |  | 
 |     if (!PyArg_ParseTuple(args, "UO&|O:load_dynamic", | 
 |                           &name, PyUnicode_FSDecoder, &pathname, &fob)) | 
 |         return NULL; | 
 |     if (fob != NULL) { | 
 |         fp = get_file(NULL, fob, "r"); | 
 |         if (fp == NULL) { | 
 |             Py_DECREF(pathname); | 
 |             return NULL; | 
 |         } | 
 |     } | 
 |     else | 
 |         fp = NULL; | 
 |     mod = _PyImport_LoadDynamicModule(name, pathname, fp); | 
 |     Py_DECREF(pathname); | 
 |     if (fp) | 
 |         fclose(fp); | 
 |     return mod; | 
 | } | 
 |  | 
 | #endif /* HAVE_DYNAMIC_LOADING */ | 
 |  | 
 | static PyObject * | 
 | imp_load_source(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name, *pathname; | 
 |     PyObject *fob = NULL; | 
 |     PyObject *m; | 
 |     FILE *fp; | 
 |     if (!PyArg_ParseTuple(args, "UO&|O:load_source", | 
 |                           &name, | 
 |                           PyUnicode_FSDecoder, &pathname, | 
 |                           &fob)) | 
 |         return NULL; | 
 |     fp = get_file(pathname, fob, "r"); | 
 |     if (fp == NULL) { | 
 |         Py_DECREF(pathname); | 
 |         return NULL; | 
 |     } | 
 |     m = load_source_module(name, pathname, fp); | 
 |     Py_DECREF(pathname); | 
 |     fclose(fp); | 
 |     return m; | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_load_module(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name, *fob, *pathname, *pathname_obj, *ret; | 
 |     char *suffix; /* Unused */ | 
 |     char *mode; | 
 |     int type; | 
 |     FILE *fp; | 
 |  | 
 |     if (!PyArg_ParseTuple(args, "UOO(ssi):load_module", | 
 |                           &name, &fob, &pathname_obj, &suffix, &mode, &type)) | 
 |         return NULL; | 
 |     if (pathname_obj != Py_None) { | 
 |         if (!PyUnicode_FSDecoder(pathname_obj, &pathname)) | 
 |             return NULL; | 
 |     } | 
 |     else | 
 |         pathname = NULL; | 
 |  | 
 |     if (*mode) { | 
 |         /* Mode must start with 'r' or 'U' and must not contain '+'. | 
 |            Implicit in this test is the assumption that the mode | 
 |            may contain other modifiers like 'b' or 't'. */ | 
 |  | 
 |         if (!(*mode == 'r' || *mode == 'U') || strchr(mode, '+')) { | 
 |             PyErr_Format(PyExc_ValueError, | 
 |                          "invalid file open mode %.200s", mode); | 
 |             Py_XDECREF(pathname); | 
 |             return NULL; | 
 |         } | 
 |     } | 
 |     if (fob == Py_None) | 
 |         fp = NULL; | 
 |     else { | 
 |         fp = get_file(NULL, fob, mode); | 
 |         if (fp == NULL) { | 
 |             Py_XDECREF(pathname); | 
 |             return NULL; | 
 |         } | 
 |     } | 
 |     ret = load_module(name, fp, pathname, type, NULL); | 
 |     Py_XDECREF(pathname); | 
 |     if (fp) | 
 |         fclose(fp); | 
 |     return ret; | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_load_package(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name, *pathname; | 
 |     PyObject * ret; | 
 |     if (!PyArg_ParseTuple(args, "UO&:load_package", | 
 |                           &name, PyUnicode_FSDecoder, &pathname)) | 
 |         return NULL; | 
 |     ret = load_package(name, pathname); | 
 |     Py_DECREF(pathname); | 
 |     return ret; | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_new_module(PyObject *self, PyObject *args) | 
 | { | 
 |     PyObject *name; | 
 |     if (!PyArg_ParseTuple(args, "U:new_module", &name)) | 
 |         return NULL; | 
 |     return PyModule_NewObject(name); | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_reload(PyObject *self, PyObject *v) | 
 | { | 
 |     return PyImport_ReloadModule(v); | 
 | } | 
 |  | 
 | PyDoc_STRVAR(doc_reload, | 
 | "reload(module) -> module\n\ | 
 | \n\ | 
 | Reload the module.  The module must have been successfully imported before."); | 
 |  | 
 | static PyObject * | 
 | imp_cache_from_source(PyObject *self, PyObject *args, PyObject *kws) | 
 | { | 
 |     static char *kwlist[] = {"path", "debug_override", NULL}; | 
 |  | 
 |     PyObject *pathname, *cpathname; | 
 |     PyObject *debug_override = NULL; | 
 |     int debug = !Py_OptimizeFlag; | 
 |  | 
 |     if (!PyArg_ParseTupleAndKeywords( | 
 |                 args, kws, "O&|O", kwlist, | 
 |                 PyUnicode_FSDecoder, &pathname, &debug_override)) | 
 |         return NULL; | 
 |  | 
 |     if (debug_override != NULL && | 
 |         (debug = PyObject_IsTrue(debug_override)) < 0) { | 
 |         Py_DECREF(pathname); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     cpathname = make_compiled_pathname( | 
 |         PyUnicode_AS_UNICODE(pathname), | 
 |         debug); | 
 |     Py_DECREF(pathname); | 
 |  | 
 |     if (cpathname == NULL) { | 
 |         PyErr_Format(PyExc_SystemError, "path buffer too short"); | 
 |         return NULL; | 
 |     } | 
 |     return cpathname; | 
 | } | 
 |  | 
 | PyDoc_STRVAR(doc_cache_from_source, | 
 | "Given the path to a .py file, return the path to its .pyc/.pyo file.\n\ | 
 | \n\ | 
 | The .py file does not need to exist; this simply returns the path to the\n\ | 
 | .pyc/.pyo file calculated as if the .py file were imported.  The extension\n\ | 
 | will be .pyc unless __debug__ is not defined, then it will be .pyo.\n\ | 
 | \n\ | 
 | If debug_override is not None, then it must be a boolean and is taken as\n\ | 
 | the value of __debug__ instead."); | 
 |  | 
 | static PyObject * | 
 | imp_source_from_cache(PyObject *self, PyObject *args, PyObject *kws) | 
 | { | 
 |     static char *kwlist[] = {"path", NULL}; | 
 |     PyObject *pathname, *source; | 
 |  | 
 |     if (!PyArg_ParseTupleAndKeywords( | 
 |                 args, kws, "O&", kwlist, | 
 |                 PyUnicode_FSDecoder, &pathname)) | 
 |         return NULL; | 
 |  | 
 |     source = make_source_pathname(pathname); | 
 |     if (source == NULL) { | 
 |         PyErr_Format(PyExc_ValueError, "Not a PEP 3147 pyc path: %R", | 
 |                      pathname); | 
 |         Py_DECREF(pathname); | 
 |         return NULL; | 
 |     } | 
 |     Py_DECREF(pathname); | 
 |     return source; | 
 | } | 
 |  | 
 | PyDoc_STRVAR(doc_source_from_cache, | 
 | "Given the path to a .pyc./.pyo file, return the path to its .py file.\n\ | 
 | \n\ | 
 | The .pyc/.pyo file does not need to exist; this simply returns the path to\n\ | 
 | the .py file calculated to correspond to the .pyc/.pyo file.  If path\n\ | 
 | does not conform to PEP 3147 format, ValueError will be raised."); | 
 |  | 
 | /* Doc strings */ | 
 |  | 
 | PyDoc_STRVAR(doc_imp, | 
 | "This module provides the components needed to build your own\n\ | 
 | __import__ function.  Undocumented functions are obsolete."); | 
 |  | 
 | PyDoc_STRVAR(doc_find_module, | 
 | "find_module(name, [path]) -> (file, filename, (suffix, mode, type))\n\ | 
 | Search for a module.  If path is omitted or None, search for a\n\ | 
 | built-in, frozen or special module and continue search in sys.path.\n\ | 
 | The module name cannot contain '.'; to search for a submodule of a\n\ | 
 | package, pass the submodule name and the package's __path__."); | 
 |  | 
 | PyDoc_STRVAR(doc_load_module, | 
 | "load_module(name, file, filename, (suffix, mode, type)) -> module\n\ | 
 | Load a module, given information returned by find_module().\n\ | 
 | The module name must include the full package name, if any."); | 
 |  | 
 | PyDoc_STRVAR(doc_get_magic, | 
 | "get_magic() -> string\n\ | 
 | Return the magic number for .pyc or .pyo files."); | 
 |  | 
 | PyDoc_STRVAR(doc_get_tag, | 
 | "get_tag() -> string\n\ | 
 | Return the magic tag for .pyc or .pyo files."); | 
 |  | 
 | PyDoc_STRVAR(doc_get_suffixes, | 
 | "get_suffixes() -> [(suffix, mode, type), ...]\n\ | 
 | Return a list of (suffix, mode, type) tuples describing the files\n\ | 
 | that find_module() looks for."); | 
 |  | 
 | PyDoc_STRVAR(doc_new_module, | 
 | "new_module(name) -> module\n\ | 
 | Create a new module.  Do not enter it in sys.modules.\n\ | 
 | The module name must include the full package name, if any."); | 
 |  | 
 | PyDoc_STRVAR(doc_lock_held, | 
 | "lock_held() -> boolean\n\ | 
 | Return True if the import lock is currently held, else False.\n\ | 
 | On platforms without threads, return False."); | 
 |  | 
 | PyDoc_STRVAR(doc_acquire_lock, | 
 | "acquire_lock() -> None\n\ | 
 | Acquires the interpreter's import lock for the current thread.\n\ | 
 | This lock should be used by import hooks to ensure thread-safety\n\ | 
 | when importing modules.\n\ | 
 | On platforms without threads, this function does nothing."); | 
 |  | 
 | PyDoc_STRVAR(doc_release_lock, | 
 | "release_lock() -> None\n\ | 
 | Release the interpreter's import lock.\n\ | 
 | On platforms without threads, this function does nothing."); | 
 |  | 
 | static PyMethodDef imp_methods[] = { | 
 |     {"find_module",      imp_find_module,  METH_VARARGS, doc_find_module}, | 
 |     {"get_magic",        imp_get_magic,    METH_NOARGS,  doc_get_magic}, | 
 |     {"get_tag",          imp_get_tag,      METH_NOARGS,  doc_get_tag}, | 
 |     {"get_suffixes", imp_get_suffixes, METH_NOARGS,  doc_get_suffixes}, | 
 |     {"load_module",      imp_load_module,  METH_VARARGS, doc_load_module}, | 
 |     {"new_module",       imp_new_module,   METH_VARARGS, doc_new_module}, | 
 |     {"lock_held",        imp_lock_held,    METH_NOARGS,  doc_lock_held}, | 
 |     {"acquire_lock", imp_acquire_lock, METH_NOARGS,  doc_acquire_lock}, | 
 |     {"release_lock", imp_release_lock, METH_NOARGS,  doc_release_lock}, | 
 |     {"reload",       imp_reload,       METH_O,       doc_reload}, | 
 |     {"cache_from_source", (PyCFunction)imp_cache_from_source, | 
 |      METH_VARARGS | METH_KEYWORDS, doc_cache_from_source}, | 
 |     {"source_from_cache", (PyCFunction)imp_source_from_cache, | 
 |      METH_VARARGS | METH_KEYWORDS, doc_source_from_cache}, | 
 |     /* The rest are obsolete */ | 
 |     {"get_frozen_object",       imp_get_frozen_object,  METH_VARARGS}, | 
 |     {"is_frozen_package",   imp_is_frozen_package,  METH_VARARGS}, | 
 |     {"init_builtin",            imp_init_builtin,       METH_VARARGS}, | 
 |     {"init_frozen",             imp_init_frozen,        METH_VARARGS}, | 
 |     {"is_builtin",              imp_is_builtin,         METH_VARARGS}, | 
 |     {"is_frozen",               imp_is_frozen,          METH_VARARGS}, | 
 |     {"load_compiled",           imp_load_compiled,      METH_VARARGS}, | 
 | #ifdef HAVE_DYNAMIC_LOADING | 
 |     {"load_dynamic",            imp_load_dynamic,       METH_VARARGS}, | 
 | #endif | 
 |     {"load_package",            imp_load_package,       METH_VARARGS}, | 
 |     {"load_source",             imp_load_source,        METH_VARARGS}, | 
 |     {"_fix_co_filename",        imp_fix_co_filename,    METH_VARARGS}, | 
 |     {NULL,                      NULL}           /* sentinel */ | 
 | }; | 
 |  | 
 | static int | 
 | setint(PyObject *d, char *name, int value) | 
 | { | 
 |     PyObject *v; | 
 |     int err; | 
 |  | 
 |     v = PyLong_FromLong((long)value); | 
 |     err = PyDict_SetItemString(d, name, v); | 
 |     Py_XDECREF(v); | 
 |     return err; | 
 | } | 
 |  | 
 | typedef struct { | 
 |     PyObject_HEAD | 
 | } NullImporter; | 
 |  | 
 | static int | 
 | NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds) | 
 | { | 
 | #ifndef MS_WINDOWS | 
 |     PyObject *path; | 
 |     struct stat statbuf; | 
 |     int rv; | 
 |  | 
 |     if (!_PyArg_NoKeywords("NullImporter()", kwds)) | 
 |         return -1; | 
 |  | 
 |     if (!PyArg_ParseTuple(args, "O&:NullImporter", | 
 |                           PyUnicode_FSConverter, &path)) | 
 |         return -1; | 
 |  | 
 |     if (PyBytes_GET_SIZE(path) == 0) { | 
 |         Py_DECREF(path); | 
 |         PyErr_SetString(PyExc_ImportError, "empty pathname"); | 
 |         return -1; | 
 |     } | 
 |  | 
 |     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; | 
 |  | 
 |     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; | 
 |     } | 
 |  | 
 |     path = PyUnicode_AsWideCharString(pathobj, NULL); | 
 |     if (path == NULL) | 
 |         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); | 
 |     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 | 
 |     return 0; | 
 | } | 
 |  | 
 | static PyObject * | 
 | NullImporter_find_module(NullImporter *self, PyObject *args) | 
 | { | 
 |     Py_RETURN_NONE; | 
 | } | 
 |  | 
 | static PyMethodDef NullImporter_methods[] = { | 
 |     {"find_module", (PyCFunction)NullImporter_find_module, METH_VARARGS, | 
 |      "Always return None" | 
 |     }, | 
 |     {NULL}  /* Sentinel */ | 
 | }; | 
 |  | 
 |  | 
 | PyTypeObject PyNullImporter_Type = { | 
 |     PyVarObject_HEAD_INIT(NULL, 0) | 
 |     "imp.NullImporter",        /*tp_name*/ | 
 |     sizeof(NullImporter),      /*tp_basicsize*/ | 
 |     0,                         /*tp_itemsize*/ | 
 |     0,                         /*tp_dealloc*/ | 
 |     0,                         /*tp_print*/ | 
 |     0,                         /*tp_getattr*/ | 
 |     0,                         /*tp_setattr*/ | 
 |     0,                         /*tp_reserved*/ | 
 |     0,                         /*tp_repr*/ | 
 |     0,                         /*tp_as_number*/ | 
 |     0,                         /*tp_as_sequence*/ | 
 |     0,                         /*tp_as_mapping*/ | 
 |     0,                         /*tp_hash */ | 
 |     0,                         /*tp_call*/ | 
 |     0,                         /*tp_str*/ | 
 |     0,                         /*tp_getattro*/ | 
 |     0,                         /*tp_setattro*/ | 
 |     0,                         /*tp_as_buffer*/ | 
 |     Py_TPFLAGS_DEFAULT,        /*tp_flags*/ | 
 |     "Null importer object",    /* tp_doc */ | 
 |     0,                             /* tp_traverse */ | 
 |     0,                             /* tp_clear */ | 
 |     0,                             /* tp_richcompare */ | 
 |     0,                             /* tp_weaklistoffset */ | 
 |     0,                             /* tp_iter */ | 
 |     0,                             /* tp_iternext */ | 
 |     NullImporter_methods,      /* tp_methods */ | 
 |     0,                         /* tp_members */ | 
 |     0,                         /* tp_getset */ | 
 |     0,                         /* tp_base */ | 
 |     0,                         /* tp_dict */ | 
 |     0,                         /* tp_descr_get */ | 
 |     0,                         /* tp_descr_set */ | 
 |     0,                         /* tp_dictoffset */ | 
 |     (initproc)NullImporter_init,      /* tp_init */ | 
 |     0,                         /* tp_alloc */ | 
 |     PyType_GenericNew          /* tp_new */ | 
 | }; | 
 |  | 
 | static struct PyModuleDef impmodule = { | 
 |     PyModuleDef_HEAD_INIT, | 
 |     "imp", | 
 |     doc_imp, | 
 |     0, | 
 |     imp_methods, | 
 |     NULL, | 
 |     NULL, | 
 |     NULL, | 
 |     NULL | 
 | }; | 
 |  | 
 | PyMODINIT_FUNC | 
 | PyInit_imp(void) | 
 | { | 
 |     PyObject *m, *d; | 
 |  | 
 |     if (PyType_Ready(&PyNullImporter_Type) < 0) | 
 |         return NULL; | 
 |  | 
 |     m = PyModule_Create(&impmodule); | 
 |     if (m == NULL) | 
 |         goto failure; | 
 |     d = PyModule_GetDict(m); | 
 |     if (d == NULL) | 
 |         goto failure; | 
 |  | 
 |     if (setint(d, "SEARCH_ERROR", SEARCH_ERROR) < 0) goto failure; | 
 |     if (setint(d, "PY_SOURCE", PY_SOURCE) < 0) goto failure; | 
 |     if (setint(d, "PY_COMPILED", PY_COMPILED) < 0) goto failure; | 
 |     if (setint(d, "C_EXTENSION", C_EXTENSION) < 0) goto failure; | 
 |     if (setint(d, "PY_RESOURCE", PY_RESOURCE) < 0) goto failure; | 
 |     if (setint(d, "PKG_DIRECTORY", PKG_DIRECTORY) < 0) goto failure; | 
 |     if (setint(d, "C_BUILTIN", C_BUILTIN) < 0) goto failure; | 
 |     if (setint(d, "PY_FROZEN", PY_FROZEN) < 0) goto failure; | 
 |     if (setint(d, "PY_CODERESOURCE", PY_CODERESOURCE) < 0) goto failure; | 
 |     if (setint(d, "IMP_HOOK", IMP_HOOK) < 0) goto failure; | 
 |  | 
 |     Py_INCREF(&PyNullImporter_Type); | 
 |     PyModule_AddObject(m, "NullImporter", (PyObject *)&PyNullImporter_Type); | 
 |     return m; | 
 |   failure: | 
 |     Py_XDECREF(m); | 
 |     return NULL; | 
 | } | 
 |  | 
 |  | 
 | /* API for embedding applications that want to add their own entries | 
 |    to the table of built-in modules.  This should normally be called | 
 |    *before* Py_Initialize().  When the table resize fails, -1 is | 
 |    returned and the existing table is unchanged. | 
 |  | 
 |    After a similar function by Just van Rossum. */ | 
 |  | 
 | int | 
 | PyImport_ExtendInittab(struct _inittab *newtab) | 
 | { | 
 |     static struct _inittab *our_copy = NULL; | 
 |     struct _inittab *p; | 
 |     int i, n; | 
 |  | 
 |     /* Count the number of entries in both tables */ | 
 |     for (n = 0; newtab[n].name != NULL; n++) | 
 |         ; | 
 |     if (n == 0) | 
 |         return 0; /* Nothing to do */ | 
 |     for (i = 0; PyImport_Inittab[i].name != NULL; i++) | 
 |         ; | 
 |  | 
 |     /* Allocate new memory for the combined table */ | 
 |     p = our_copy; | 
 |     PyMem_RESIZE(p, struct _inittab, i+n+1); | 
 |     if (p == NULL) | 
 |         return -1; | 
 |  | 
 |     /* Copy the tables into the new memory */ | 
 |     if (our_copy != PyImport_Inittab) | 
 |         memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab)); | 
 |     PyImport_Inittab = our_copy = p; | 
 |     memcpy(p+i, newtab, (n+1) * sizeof(struct _inittab)); | 
 |  | 
 |     return 0; | 
 | } | 
 |  | 
 | /* Shorthand to add a single entry given a name and a function */ | 
 |  | 
 | int | 
 | PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) | 
 | { | 
 |     struct _inittab newtab[2]; | 
 |  | 
 |     memset(newtab, '\0', sizeof newtab); | 
 |  | 
 |     newtab[0].name = (char *)name; | 
 |     newtab[0].initfunc = initfunc; | 
 |  | 
 |     return PyImport_ExtendInittab(newtab); | 
 | } | 
 |  | 
 | #ifdef __cplusplus | 
 | } | 
 | #endif |