cpython/Python/import.c

/* Module definition and import implementation */

#include "Python.h"
#include "pycore_audit.h"         // _PySys_Audit()
#include "pycore_ceval.h"
#include "pycore_hashtable.h"     // _Py_hashtable_new_full()
#include "pycore_import.h"        // _PyImport_BootstrapImp()
#include "pycore_initconfig.h"    // _PyStatus_OK()
#include "pycore_interp.h"        // struct _import_runtime_state
#include "pycore_magic_number.h"  // PYC_MAGIC_NUMBER_TOKEN
#include "pycore_namespace.h"     // _PyNamespace_Type
#include "pycore_object.h"        // _Py_SetImmortal()
#include "pycore_pyerrors.h"      // _PyErr_SetString()
#include "pycore_pyhash.h"        // _Py_KeyedHash()
#include "pycore_pylifecycle.h"
#include "pycore_pymem.h"         // _PyMem_SetDefaultAllocator()
#include "pycore_pystate.h"       // _PyInterpreterState_GET()
#include "pycore_sysmodule.h"     // _PySys_ClearAttrString()
#include "pycore_time.h"          // _PyTime_AsMicroseconds()
#include "pycore_weakref.h"       // _PyWeakref_GET_REF()

#include "marshal.h"              // PyMarshal_ReadObjectFromString()
#include "pycore_importdl.h"      // _PyImport_DynLoadFiletab
#include "pydtrace.h"             // PyDTrace_IMPORT_FIND_LOAD_START_ENABLED()
#include <stdbool.h>              // bool

#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif


/*[clinic input]
module _imp
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9c332475d8686284]*/

#include "clinic/import.c.h"


#ifndef NDEBUG
static bool
is_interpreter_isolated(PyInterpreterState *interp)
{
    return !_Py_IsMainInterpreter(interp)
        && !(interp->feature_flags & Py_RTFLAGS_USE_MAIN_OBMALLOC)
        && interp->ceval.own_gil;
}
#endif


/*******************************/
/* process-global import state */
/*******************************/

/* This table is defined in config.c: */
extern struct _inittab _PyImport_Inittab[];

// This is not used after Py_Initialize() is called.
// (See _PyRuntimeState.imports.inittab.)
struct _inittab *PyImport_Inittab =;
// When we dynamically allocate a larger table for PyImport_ExtendInittab(),
// we track the pointer here so we can deallocate it during finalization.
static struct _inittab *inittab_copy =;


/*******************************/
/* runtime-global import state */
/*******************************/

#define INITTAB
#define LAST_MODULE_INDEX
#define EXTENSIONS

#define PKGCONTEXT


/*******************************/
/* interpreter import state */
/*******************************/

#define MODULES(interp)
#define MODULES_BY_INDEX(interp)
#define IMPORTLIB(interp)
#define OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp)
#define OVERRIDE_FROZEN_MODULES(interp)
#ifdef HAVE_DLOPEN
#define DLOPENFLAGS(interp)
#endif
#define IMPORT_FUNC(interp)

#define IMPORT_LOCK(interp)

#define FIND_AND_LOAD(interp)


/*******************/
/* the import lock */
/*******************/

/* 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. */

void
_PyImport_AcquireLock(PyInterpreterState *interp)
{}

void
_PyImport_ReleaseLock(PyInterpreterState *interp)
{}

void
_PyImport_ReInitLock(PyInterpreterState *interp)
{}


/***************/
/* sys.modules */
/***************/

PyObject *
_PyImport_InitModules(PyInterpreterState *interp)
{}

PyObject *
_PyImport_GetModules(PyInterpreterState *interp)
{}

void
_PyImport_ClearModules(PyInterpreterState *interp)
{}

static inline PyObject *
get_modules_dict(PyThreadState *tstate, bool fatal)
{}

PyObject *
PyImport_GetModuleDict(void)
{}

int
_PyImport_SetModule(PyObject *name, PyObject *m)
{}

int
_PyImport_SetModuleString(const char *name, PyObject *m)
{}

static PyObject *
import_get_module(PyThreadState *tstate, PyObject *name)
{}

static int
import_ensure_initialized(PyInterpreterState *interp, PyObject *mod, PyObject *name)
{}

static void remove_importlib_frames(PyThreadState *tstate);

PyObject *
PyImport_GetModule(PyObject *name)
{}

/* 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. */

static PyObject *
import_add_module(PyThreadState *tstate, PyObject *name)
{}

PyObject *
PyImport_AddModuleRef(const char *name)
{}


PyObject *
PyImport_AddModuleObject(PyObject *name)
{}


PyObject *
PyImport_AddModule(const char *name)
{}


/* Remove name from sys.modules, if it's there.
 * Can be called with an exception raised.
 * If fail to remove name a new exception will be chained with the old
 * exception, otherwise the old exception is preserved.
 */
static void
remove_module(PyThreadState *tstate, PyObject *name)
{}


/************************************/
/* per-interpreter modules-by-index */
/************************************/

Py_ssize_t
_PyImport_GetNextModuleIndex(void)
{}

#ifndef NDEBUG
struct extensions_cache_value;
static struct extensions_cache_value * _find_cached_def(PyModuleDef *);
static Py_ssize_t _get_cached_module_index(struct extensions_cache_value *);
#endif

static Py_ssize_t
_get_module_index_from_def(PyModuleDef *def)
{}

static void
_set_module_index(PyModuleDef *def, Py_ssize_t index)
{}

static const char *
_modules_by_index_check(PyInterpreterState *interp, Py_ssize_t index)
{}

static PyObject *
_modules_by_index_get(PyInterpreterState *interp, Py_ssize_t index)
{}

static int
_modules_by_index_set(PyInterpreterState *interp,
                      Py_ssize_t index, PyObject *module)
{}

static int
_modules_by_index_clear_one(PyInterpreterState *interp, Py_ssize_t index)
{}


PyObject*
PyState_FindModule(PyModuleDef* module)
{}

/* _PyState_AddModule() has been completely removed from the C-API
   (and was removed from the limited API in 3.6).  However, we're
   playing it safe and keeping it around for any stable ABI extensions
   built against 3.2-3.5. */
int
_PyState_AddModule(PyThreadState *tstate, PyObject* module, PyModuleDef* def)
{}

int
PyState_AddModule(PyObject* module, PyModuleDef* def)
{}

int
PyState_RemoveModule(PyModuleDef* def)
{}


// Used by finalize_modules()
void
_PyImport_ClearModulesByIndex(PyInterpreterState *interp)
{}


/*********************/
/* extension modules */
/*********************/

/*
    It may help to have a big picture view of what happens
    when an extension is loaded.  This includes when it is imported
    for the first time.

    Here's a summary, using importlib._bootstrap._load() as a starting point.

    1.  importlib._bootstrap._load()
    2.    _load():  acquire import lock
    3.    _load() -> importlib._bootstrap._load_unlocked()
    4.      _load_unlocked() -> importlib._bootstrap.module_from_spec()
    5.        module_from_spec() -> ExtensionFileLoader.create_module()
    6.          create_module() -> _imp.create_dynamic()
                    (see below)
    7.        module_from_spec() -> importlib._bootstrap._init_module_attrs()
    8.      _load_unlocked():  sys.modules[name] = module
    9.      _load_unlocked() -> ExtensionFileLoader.exec_module()
    10.       exec_module() -> _imp.exec_dynamic()
                  (see below)
    11.   _load():  release import lock


    ...for single-phase init modules, where m_size == -1:

    (6). first time  (not found in _PyRuntime.imports.extensions):
       A. _imp_create_dynamic_impl() -> import_find_extension()
       B. _imp_create_dynamic_impl() -> _PyImport_GetModInitFunc()
       C.   _PyImport_GetModInitFunc():  load <module init func>
       D. _imp_create_dynamic_impl() -> import_run_extension()
       E.   import_run_extension() -> _PyImport_RunModInitFunc()
       F.     _PyImport_RunModInitFunc():  call <module init func>
       G.       <module init func> -> PyModule_Create() -> PyModule_Create2()
                                          -> PyModule_CreateInitialized()
       H.         PyModule_CreateInitialized() -> PyModule_New()
       I.         PyModule_CreateInitialized():  allocate mod->md_state
       J.         PyModule_CreateInitialized() -> PyModule_AddFunctions()
       K.         PyModule_CreateInitialized() -> PyModule_SetDocString()
       L.       PyModule_CreateInitialized():  set mod->md_def
       M.       <module init func>:  initialize the module, etc.
       N.   import_run_extension()
                -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
       O.   import_run_extension():  set __file__
       P.   import_run_extension() -> update_global_state_for_extension()
       Q.     update_global_state_for_extension():
                      copy __dict__ into def->m_base.m_copy
       R.     update_global_state_for_extension():
                      add it to _PyRuntime.imports.extensions
       S.   import_run_extension() -> finish_singlephase_extension()
       T.     finish_singlephase_extension():
                      add it to interp->imports.modules_by_index
       U.     finish_singlephase_extension():  add it to sys.modules

       Step (Q) is skipped for core modules (sys/builtins).

    (6). subsequent times  (found in _PyRuntime.imports.extensions):
       A. _imp_create_dynamic_impl() -> import_find_extension()
       B.   import_find_extension() -> reload_singlephase_extension()
       C.     reload_singlephase_extension()
                  -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
       D.     reload_singlephase_extension() -> import_add_module()
       E.       if name in sys.modules:  use that module
       F.       else:
                  1. import_add_module() -> PyModule_NewObject()
                  2. import_add_module():  set it on sys.modules
       G.     reload_singlephase_extension():  copy the "m_copy" dict into __dict__
       H.     reload_singlephase_extension():  add to modules_by_index

    (10). (every time):
       A. noop


    ...for single-phase init modules, where m_size >= 0:

    (6). not main interpreter and never loaded there - every time  (not found in _PyRuntime.imports.extensions):
       A-P. (same as for m_size == -1)
       Q.     _PyImport_RunModInitFunc():  set def->m_base.m_init
       R. (skipped)
       S-U. (same as for m_size == -1)

    (6). main interpreter - first time  (not found in _PyRuntime.imports.extensions):
       A-P. (same as for m_size == -1)
       Q.     _PyImport_RunModInitFunc():  set def->m_base.m_init
       R-U. (same as for m_size == -1)

    (6). subsequent times  (found in _PyRuntime.imports.extensions):
       A. _imp_create_dynamic_impl() -> import_find_extension()
       B.   import_find_extension() -> reload_singlephase_extension()
       C.     reload_singlephase_extension()
                  -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed()
       D.     reload_singlephase_extension():  call def->m_base.m_init  (see above)
       E.     reload_singlephase_extension():  add the module to sys.modules
       F.     reload_singlephase_extension():  add to modules_by_index

    (10). every time:
       A. noop


    ...for multi-phase init modules:

    (6). every time:
       A. _imp_create_dynamic_impl() -> import_find_extension()  (not found)
       B. _imp_create_dynamic_impl() -> _PyImport_GetModInitFunc()
       C.   _PyImport_GetModInitFunc():  load <module init func>
       D. _imp_create_dynamic_impl() -> import_run_extension()
       E.   import_run_extension() -> _PyImport_RunModInitFunc()
       F.     _PyImport_RunModInitFunc():  call <module init func>
       G.   import_run_extension() -> PyModule_FromDefAndSpec()
       H.      PyModule_FromDefAndSpec(): gather/check moduledef slots
       I.      if there's a Py_mod_create slot:
                 1. PyModule_FromDefAndSpec():  call its function
       J.      else:
                 1. PyModule_FromDefAndSpec() -> PyModule_NewObject()
       K:      PyModule_FromDefAndSpec():  set mod->md_def
       L.      PyModule_FromDefAndSpec() -> _add_methods_to_object()
       M.      PyModule_FromDefAndSpec() -> PyModule_SetDocString()

    (10). every time:
       A. _imp_exec_dynamic_impl() -> exec_builtin_or_dynamic()
       B.   if mod->md_state == NULL (including if m_size == 0):
            1. exec_builtin_or_dynamic() -> PyModule_ExecDef()
            2.   PyModule_ExecDef():  allocate mod->md_state
            3.   if there's a Py_mod_exec slot:
                 1. PyModule_ExecDef():  call its function
 */


/* Make sure name is fully qualified.

   This is a bit of a hack: when the shared library is loaded,
   the module name is "package.module", but the module calls
   PyModule_Create*() with just "module" for the name.  The shared
   library loader squirrels away the true name of the module in
   _PyRuntime.imports.pkgcontext, and PyModule_Create*() will
   substitute this (if the name actually matches).
*/

#ifdef HAVE_THREAD_LOCAL
_Py_thread_local const char *pkgcontext =;
# undef PKGCONTEXT
#define PKGCONTEXT
#endif

const char *
_PyImport_ResolveNameWithPackageContext(const char *name)
{}

const char *
_PyImport_SwapPackageContext(const char *newcontext)
{}

#ifdef HAVE_DLOPEN
int
_PyImport_GetDLOpenFlags(PyInterpreterState *interp)
{}

void
_PyImport_SetDLOpenFlags(PyInterpreterState *interp, int new_val)
{}
#endif  // HAVE_DLOPEN


/* Common implementation for _imp.exec_dynamic and _imp.exec_builtin */
static int
exec_builtin_or_dynamic(PyObject *mod) {}


static int clear_singlephase_extension(PyInterpreterState *interp,
                                       PyObject *name, PyObject *filename);

// Currently, this is only used for testing.
// (See _testinternalcapi.clear_extension().)
// If adding another use, be careful about modules that import themselves
// recursively (see gh-123880).
int
_PyImport_ClearExtension(PyObject *name, PyObject *filename)
{}


/*****************************/
/* single-phase init modules */
/*****************************/

/*
We support a number of kinds of single-phase init builtin/extension modules:

* "basic"
    * no module state (PyModuleDef.m_size == -1)
    * does not support repeated init (we use PyModuleDef.m_base.m_copy)
    * may have process-global state
    * the module's def is cached in _PyRuntime.imports.extensions,
      by (name, filename)
* "reinit"
    * no module state (PyModuleDef.m_size == 0)
    * supports repeated init (m_copy is never used)
    * should not have any process-global state
    * its def is never cached in _PyRuntime.imports.extensions
      (except, currently, under the main interpreter, for some reason)
* "with state"  (almost the same as reinit)
    * has module state (PyModuleDef.m_size > 0)
    * supports repeated init (m_copy is never used)
    * should not have any process-global state
    * its def is never cached in _PyRuntime.imports.extensions
      (except, currently, under the main interpreter, for some reason)

There are also variants within those classes:

* two or more modules share a PyModuleDef
    * a module's init func uses another module's PyModuleDef
    * a module's init func calls another's module's init func
    * a module's init "func" is actually a variable statically initialized
      to another module's init func
* two or modules share "methods"
    * a module's init func copies another module's PyModuleDef
      (with a different name)
* (basic-only) two or modules share process-global state

In the first case, where modules share a PyModuleDef, the following
notable weirdness happens:

* the module's __name__ matches the def, not the requested name
* the last module (with the same def) to be imported for the first time wins
    * returned by PyState_Find_Module() (via interp->modules_by_index)
    * (non-basic-only) its init func is used when re-loading any of them
      (via the def's m_init)
    * (basic-only) the copy of its __dict__ is used when re-loading any of them
      (via the def's m_copy)

However, the following happens as expected:

* a new module object (with its own __dict__) is created for each request
* the module's __spec__ has the requested name
* the loaded module is cached in sys.modules under the requested name
* the m_index field of the shared def is not changed,
  so at least PyState_FindModule() will always look in the same place

For "basic" modules there are other quirks:

* (whether sharing a def or not) when loaded the first time,
  m_copy is set before _init_module_attrs() is called
  in importlib._bootstrap.module_from_spec(),
  so when the module is re-loaded, the previous value
  for __wpec__ (and others) is reset, possibly unexpectedly.

Generally, when multiple interpreters are involved, some of the above
gets even messier.
*/

static inline void
extensions_lock_acquire(void)
{}

static inline void
extensions_lock_release(void)
{}


/* 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 the tuple
   (module name, module name)  (for built-in modules) or by
   (filename, module name) (for dynamically loaded modules), containing these
   modules.  A copy of the module's dictionary is stored by calling
   fix_up_extension() immediately after the module initialization
   function succeeds.  A copy can be retrieved from there by calling
   import_find_extension().

   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.
*/

cached_m_dict_t;

struct extensions_cache_value {};

static struct extensions_cache_value *
alloc_extensions_cache_value(void)
{}

static void
free_extensions_cache_value(struct extensions_cache_value *value)
{}

static Py_ssize_t
_get_cached_module_index(struct extensions_cache_value *cached)
{}

static void
fixup_cached_def(struct extensions_cache_value *value)
{}

static void
restore_old_cached_def(PyModuleDef *def, PyModuleDef_Base *oldbase)
{}

static void
cleanup_old_cached_def(PyModuleDef_Base *oldbase)
{}

static void
del_cached_def(struct extensions_cache_value *value)
{}

static int
init_cached_m_dict(struct extensions_cache_value *value, PyObject *m_dict)
{}

static void
del_cached_m_dict(struct extensions_cache_value *value)
{}

static PyObject * get_core_module_dict(
        PyInterpreterState *interp, PyObject *name, PyObject *path);

static PyObject *
get_cached_m_dict(struct extensions_cache_value *value,
                  PyObject *name, PyObject *path)
{}

static void
del_extensions_cache_value(struct extensions_cache_value *value)
{}

static void *
hashtable_key_from_2_strings(PyObject *str1, PyObject *str2, const char sep)
{}

static Py_uhash_t
hashtable_hash_str(const void *key)
{}

static int
hashtable_compare_str(const void *key1, const void *key2)
{}

static void
hashtable_destroy_str(void *ptr)
{}

#ifndef NDEBUG
struct hashtable_next_match_def_data {
    PyModuleDef *def;
    struct extensions_cache_value *matched;
};

static int
hashtable_next_match_def(_Py_hashtable_t *ht,
                         const void *key, const void *value, void *user_data)
{
    if (value == NULL) {
        /* It was previously deleted. */
        return 0;
    }
    struct hashtable_next_match_def_data *data
            = (struct hashtable_next_match_def_data *)user_data;
    struct extensions_cache_value *cur
            = (struct extensions_cache_value *)value;
    if (cur->def == data->def) {
        data->matched = cur;
        return 1;
    }
    return 0;
}

static struct extensions_cache_value *
_find_cached_def(PyModuleDef *def)
{
    struct hashtable_next_match_def_data data = {0};
    (void)_Py_hashtable_foreach(
            EXTENSIONS.hashtable, hashtable_next_match_def, &data);
    return data.matched;
}
#endif

#define HTSEP

static int
_extensions_cache_init(void)
{}

static _Py_hashtable_entry_t *
_extensions_cache_find_unlocked(PyObject *path, PyObject *name,
                                void **p_key)
{}

/* This can only fail with "out of memory". */
static struct extensions_cache_value *
_extensions_cache_get(PyObject *path, PyObject *name)
{}

/* This can only fail with "out of memory". */
static struct extensions_cache_value *
_extensions_cache_set(PyObject *path, PyObject *name,
                      PyModuleDef *def, PyModInitFunction m_init,
                      Py_ssize_t m_index, PyObject *m_dict,
                      _Py_ext_module_origin origin, void *md_gil)
{}

static void
_extensions_cache_delete(PyObject *path, PyObject *name)
{}

static void
_extensions_cache_clear_all(void)
{}

#undef HTSEP


static bool
check_multi_interp_extensions(PyInterpreterState *interp)
{}

int
_PyImport_CheckSubinterpIncompatibleExtensionAllowed(const char *name)
{}

#ifdef Py_GIL_DISABLED
int
_PyImport_CheckGILForModule(PyObject* module, PyObject *module_name)
{
    PyThreadState *tstate = _PyThreadState_GET();
    if (module == NULL) {
        _PyEval_DisableGIL(tstate);
        return 0;
    }

    if (!PyModule_Check(module) ||
        ((PyModuleObject *)module)->md_gil == Py_MOD_GIL_USED) {
        if (_PyEval_EnableGILPermanent(tstate)) {
            int warn_result = PyErr_WarnFormat(
                PyExc_RuntimeWarning,
                1,
                "The global interpreter lock (GIL) has been enabled to load "
                "module '%U', which has not declared that it can run safely "
                "without the GIL. To override this behavior and keep the GIL "
                "disabled (at your own risk), run with PYTHON_GIL=0 or -Xgil=0.",
                module_name
            );
            if (warn_result < 0) {
                return warn_result;
            }
        }

        const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp);
        if (config->enable_gil == _PyConfig_GIL_DEFAULT && config->verbose) {
            PySys_FormatStderr("# loading module '%U', which requires the GIL\n",
                               module_name);
        }
    }
    else {
        _PyEval_DisableGIL(tstate);
    }

    return 0;
}
#endif

static PyThreadState *
switch_to_main_interpreter(PyThreadState *tstate)
{}

static void
switch_back_from_main_interpreter(PyThreadState *tstate,
                                  PyThreadState *main_tstate,
                                  PyObject *tempobj)
{}

static PyObject *
get_core_module_dict(PyInterpreterState *interp,
                     PyObject *name, PyObject *path)
{}

#ifndef NDEBUG
static inline int
is_core_module(PyInterpreterState *interp, PyObject *name, PyObject *path)
{
    /* This might be called before the core dict copies are in place,
       so we can't rely on get_core_module_dict() here. */
    if (path == name) {
        if (PyUnicode_CompareWithASCIIString(name, "sys") == 0) {
            return 1;
        }
        if (PyUnicode_CompareWithASCIIString(name, "builtins") == 0) {
            return 1;
        }
    }
    return 0;
}


static _Py_ext_module_kind
_get_extension_kind(PyModuleDef *def, bool check_size)
{
    _Py_ext_module_kind kind;
    if (def == NULL) {
        /* It must be a module created by reload_singlephase_extension()
         * from m_copy.  Ideally we'd do away with this case. */
        kind = _Py_ext_module_kind_SINGLEPHASE;
    }
    else if (def->m_slots != NULL) {
        kind = _Py_ext_module_kind_MULTIPHASE;
    }
    else if (check_size && def->m_size == -1) {
        kind = _Py_ext_module_kind_SINGLEPHASE;
    }
    else if (def->m_base.m_init != NULL) {
        kind = _Py_ext_module_kind_SINGLEPHASE;
    }
    else {
        // This is probably single-phase init, but a multi-phase
        // module *can* have NULL m_slots.
        kind = _Py_ext_module_kind_UNKNOWN;
    }
    return kind;
}

/* The module might not be fully initialized yet
 * and PyModule_FromDefAndSpec() checks m_size
 * so we skip m_size. */
#define assert_multiphase_def

#define assert_singlephase_def

#define assert_singlephase

#else  /* defined(NDEBUG) */
#define assert_multiphase_def(def)
#define assert_singlephase_def(def)
#define assert_singlephase(cached)
#endif


struct singlephase_global_update {};

static struct extensions_cache_value *
update_global_state_for_extension(PyThreadState *tstate,
                                  PyObject *path, PyObject *name,
                                  PyModuleDef *def,
                                  struct singlephase_global_update *singlephase)
{}

/* For multi-phase init modules, the module is finished
 * by PyModule_FromDefAndSpec(). */
static int
finish_singlephase_extension(PyThreadState *tstate, PyObject *mod,
                             struct extensions_cache_value *cached,
                             PyObject *name, PyObject *modules)
{}


static PyObject *
reload_singlephase_extension(PyThreadState *tstate,
                             struct extensions_cache_value *cached,
                             struct _Py_ext_module_loader_info *info)
{}

static PyObject *
import_find_extension(PyThreadState *tstate,
                      struct _Py_ext_module_loader_info *info,
                      struct extensions_cache_value **p_cached)
{}

static PyObject *
import_run_extension(PyThreadState *tstate, PyModInitFunction p0,
                     struct _Py_ext_module_loader_info *info,
                     PyObject *spec, PyObject *modules)
{}


// Used in _PyImport_ClearExtension; see notes there.
static int
clear_singlephase_extension(PyInterpreterState *interp,
                            PyObject *name, PyObject *path)
{}


/*******************/
/* builtin modules */
/*******************/

int
_PyImport_FixupBuiltin(PyThreadState *tstate, PyObject *mod, const char *name,
                       PyObject *modules)
{}

/* Helper to test for built-in module */

static int
is_builtin(PyObject *name)
{}

static PyObject*
create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec)
{}


/*****************************/
/* the builtin modules table */
/*****************************/

/* 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)
{}

/* Shorthand to add a single entry given a name and a function */

int
PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void))
{}


/* the internal table */

static int
init_builtin_modules_table(void)
{}

static void
fini_builtin_modules_table(void)
{}

PyObject *
_PyImport_GetBuiltinModuleNames(void)
{}


/********************/
/* the magic number */
/********************/

/* Helper for pythonrun.c -- return magic number and tag. */

long
PyImport_GetMagicNumber(void)
{}

extern const char * _PySys_ImplCacheTag;

const char *
PyImport_GetMagicTag(void)
{}


/*********************************/
/* a Python module's code object */
/*********************************/

/* 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(const char *name, PyObject *co)
{}

PyObject *
PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname)
{}

PyObject *
PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co,
                                     const char *pathname,
                                     const char *cpathname)
{}

static PyObject *
module_dict_for_exec(PyThreadState *tstate, PyObject *name)
{}

static PyObject *
exec_code_in_module(PyThreadState *tstate, PyObject *name,
                    PyObject *module_dict, PyObject *code_object)
{}

PyObject*
PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
                              PyObject *cpathname)
{}


static void
update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname)
{}

static void
update_compiled_module(PyCodeObject *co, PyObject *newname)
{}


/******************/
/* frozen modules */
/******************/

/* Return true if the name is an alias.  In that case, "alias" is set
   to the original module name.  If it is an alias but the original
   module isn't known then "alias" is set to NULL while true is returned. */
static bool
resolve_module_alias(const char *name, const struct _module_alias *aliases,
                     const char **alias)
{}

static bool
use_frozen(void)
{}

static PyObject *
list_frozen_module_names(void)
{}

frozen_status;

static inline void
set_frozen_error(frozen_status status, PyObject *modname)
{}

static const struct _frozen *
look_up_frozen(const char *name)
{}

struct frozen_info {};

static frozen_status
find_frozen(PyObject *nameobj, struct frozen_info *info)
{}

static PyObject *
unmarshal_frozen_code(PyInterpreterState *interp, struct frozen_info *info)
{}


/* 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)
{}

int
PyImport_ImportFrozenModule(const char *name)
{}


/*************/
/* importlib */
/*************/

/* Import the _imp extension by calling manually _imp.create_builtin() and
   _imp.exec_builtin() since importlib is not initialized yet. Initializing
   importlib requires the _imp module: this function fix the bootstrap issue.
 */
static PyObject*
bootstrap_imp(PyThreadState *tstate)
{}

/* Global initializations.  Can be undone by Py_FinalizeEx().  Don't
   call this twice without an intervening Py_FinalizeEx() call.  When
   initializations fail, a fatal error is issued and the function does
   not return.  On return, the first thread and interpreter state have
   been created.

   Locking: you must hold the interpreter lock while calling this.
   (If the lock has not yet been initialized, that's equivalent to
   having the lock, but you cannot use multiple threads.)

*/
static int
init_importlib(PyThreadState *tstate, PyObject *sysmod)
{}


static int
init_importlib_external(PyInterpreterState *interp)
{}

PyObject *
_PyImport_GetImportlibLoader(PyInterpreterState *interp,
                             const char *loader_name)
{}

PyObject *
_PyImport_GetImportlibExternalLoader(PyInterpreterState *interp,
                                     const char *loader_name)
{}

PyObject *
_PyImport_BlessMyLoader(PyInterpreterState *interp, PyObject *module_globals)
{}

PyObject *
_PyImport_ImportlibModuleRepr(PyInterpreterState *interp, PyObject *m)
{}


/*******************/

/* Return a finder 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 that the path based finder could not find
   a finder for this path item. Cache the result in
   path_importer_cache. */

static PyObject *
get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache,
                  PyObject *path_hooks, PyObject *p)
{}

PyObject *
PyImport_GetImporter(PyObject *path)
{}


/*********************/
/* importing modules */
/*********************/

int
_PyImport_InitDefaultImportFunc(PyInterpreterState *interp)
{}

int
_PyImport_IsDefaultImportFunc(PyInterpreterState *interp, PyObject *func)
{}


/* Import a module, either built-in, frozen, or external, and return
   its module object WITH INCREMENTED REFERENCE COUNT */

PyObject *
PyImport_ImportModule(const char *name)
{}


/* 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)
{}


/* Remove importlib frames from the traceback,
 * except in Verbose mode. */
static void
remove_importlib_frames(PyThreadState *tstate)
{}


static PyObject *
resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level)
{}

static PyObject *
import_find_and_load(PyThreadState *tstate, PyObject *abs_name)
{}

PyObject *
PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
                                 PyObject *locals, PyObject *fromlist,
                                 int level)
{}

PyObject *
PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals,
                           PyObject *fromlist, int level)
{}


/* Re-import a module of any kind and return its module object, WITH
   INCREMENTED REFERENCE COUNT */

PyObject *
PyImport_ReloadModule(PyObject *m)
{}


/* 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)
{}


/*********************/
/* runtime lifecycle */
/*********************/

PyStatus
_PyImport_Init(void)
{}

void
_PyImport_Fini(void)
{}

void
_PyImport_Fini2(void)
{}


/*************************/
/* interpreter lifecycle */
/*************************/

PyStatus
_PyImport_InitCore(PyThreadState *tstate, PyObject *sysmod, int importlib)
{}

/* In some corner cases it is important to be sure that the import
   machinery has been initialized (or not cleaned up yet).  For
   example, see issue #4236 and PyModule_Create2(). */

int
_PyImport_IsInitialized(PyInterpreterState *interp)
{}

/* Clear the direct per-interpreter import state, if not cleared already. */
void
_PyImport_ClearCore(PyInterpreterState *interp)
{}

void
_PyImport_FiniCore(PyInterpreterState *interp)
{}

// XXX Add something like _PyImport_Disable() for use early in interp fini?


/* "external" imports */

static int
init_zipimport(PyThreadState *tstate, int verbose)
{}

PyStatus
_PyImport_InitExternal(PyThreadState *tstate)
{}

void
_PyImport_FiniExternal(PyInterpreterState *interp)
{}


/******************/
/* module helpers */
/******************/

PyObject *
_PyImport_GetModuleAttr(PyObject *modname, PyObject *attrname)
{}

PyObject *
_PyImport_GetModuleAttrString(const char *modname, const char *attrname)
{}


/**************/
/* the module */
/**************/

/*[clinic input]
_imp.lock_held

Return True if the import lock is currently held, else False.

On platforms without threads, return False.
[clinic start generated code]*/

static PyObject *
_imp_lock_held_impl(PyObject *module)
/*[clinic end generated code: output=8b89384b5e1963fc input=9b088f9b217d9bdf]*/
{}

/*[clinic input]
_imp.acquire_lock

Acquires the interpreter's import lock for the current thread.

This lock should be used by import hooks to ensure thread-safety when importing
modules. On platforms without threads, this function does nothing.
[clinic start generated code]*/

static PyObject *
_imp_acquire_lock_impl(PyObject *module)
/*[clinic end generated code: output=1aff58cb0ee1b026 input=4a2d4381866d5fdc]*/
{}

/*[clinic input]
_imp.release_lock

Release the interpreter's import lock.

On platforms without threads, this function does nothing.
[clinic start generated code]*/

static PyObject *
_imp_release_lock_impl(PyObject *module)
/*[clinic end generated code: output=7faab6d0be178b0a input=934fb11516dd778b]*/
{}


/*[clinic input]
_imp._fix_co_filename

    code: object(type="PyCodeObject *", subclass_of="&PyCode_Type")
        Code object to change.

    path: unicode
        File path to use.
    /

Changes code.co_filename to specify the passed-in file path.
[clinic start generated code]*/

static PyObject *
_imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code,
                           PyObject *path)
/*[clinic end generated code: output=1d002f100235587d input=895ba50e78b82f05]*/

{}


/*[clinic input]
_imp.create_builtin

    spec: object
    /

Create an extension module.
[clinic start generated code]*/

static PyObject *
_imp_create_builtin(PyObject *module, PyObject *spec)
/*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/
{}


/*[clinic input]
_imp.extension_suffixes

Returns the list of file suffixes used to identify extension modules.
[clinic start generated code]*/

static PyObject *
_imp_extension_suffixes_impl(PyObject *module)
/*[clinic end generated code: output=0bf346e25a8f0cd3 input=ecdeeecfcb6f839e]*/
{}

/*[clinic input]
_imp.init_frozen

    name: unicode
    /

Initializes a frozen module.
[clinic start generated code]*/

static PyObject *
_imp_init_frozen_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=fc0511ed869fd69c input=13019adfc04f3fb3]*/
{}

/*[clinic input]
_imp.find_frozen

    name: unicode
    /
    *
    withdata: bool = False

Return info about the corresponding frozen module (if there is one) or None.

The returned info (a 2-tuple):

 * data         the raw marshalled bytes
 * is_package   whether or not it is a package
 * origname     the originally frozen module's name, or None if not
                a stdlib module (this will usually be the same as
                the module's current name)
[clinic start generated code]*/

static PyObject *
_imp_find_frozen_impl(PyObject *module, PyObject *name, int withdata)
/*[clinic end generated code: output=8c1c3c7f925397a5 input=22a8847c201542fd]*/
{}

/*[clinic input]
_imp.get_frozen_object

    name: unicode
    data as dataobj: object = None
    /

Create a code object for a frozen module.
[clinic start generated code]*/

static PyObject *
_imp_get_frozen_object_impl(PyObject *module, PyObject *name,
                            PyObject *dataobj)
/*[clinic end generated code: output=54368a673a35e745 input=034bdb88f6460b7b]*/
{}

/*[clinic input]
_imp.is_frozen_package

    name: unicode
    /

Returns True if the module name is of a frozen package.
[clinic start generated code]*/

static PyObject *
_imp_is_frozen_package_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=e70cbdb45784a1c9 input=81b6cdecd080fbb8]*/
{}

/*[clinic input]
_imp.is_builtin

    name: unicode
    /

Returns True if the module name corresponds to a built-in module.
[clinic start generated code]*/

static PyObject *
_imp_is_builtin_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=3bfd1162e2d3be82 input=86befdac021dd1c7]*/
{}

/*[clinic input]
_imp.is_frozen

    name: unicode
    /

Returns True if the module name corresponds to a frozen module.
[clinic start generated code]*/

static PyObject *
_imp_is_frozen_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=01f408f5ec0f2577 input=7301dbca1897d66b]*/
{}

/*[clinic input]
_imp._frozen_module_names

Returns the list of available frozen modules.
[clinic start generated code]*/

static PyObject *
_imp__frozen_module_names_impl(PyObject *module)
/*[clinic end generated code: output=80609ef6256310a8 input=76237fbfa94460d2]*/
{}

/*[clinic input]
_imp._override_frozen_modules_for_tests

    override: int
    /

(internal-only) Override PyConfig.use_frozen_modules.

(-1: "off", 1: "on", 0: no override)
See frozen_modules() in Lib/test/support/import_helper.py.
[clinic start generated code]*/

static PyObject *
_imp__override_frozen_modules_for_tests_impl(PyObject *module, int override)
/*[clinic end generated code: output=36d5cb1594160811 input=8f1f95a3ef21aec3]*/
{}

/*[clinic input]
_imp._override_multi_interp_extensions_check

    override: int
    /

(internal-only) Override PyInterpreterConfig.check_multi_interp_extensions.

(-1: "never", 1: "always", 0: no override)
[clinic start generated code]*/

static PyObject *
_imp__override_multi_interp_extensions_check_impl(PyObject *module,
                                                  int override)
/*[clinic end generated code: output=3ff043af52bbf280 input=e086a2ea181f92ae]*/
{}

#ifdef HAVE_DYNAMIC_LOADING

/*[clinic input]
_imp.create_dynamic

    spec: object
    file: object = NULL
    /

Create an extension module.
[clinic start generated code]*/

static PyObject *
_imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file)
/*[clinic end generated code: output=83249b827a4fde77 input=c31b954f4cf4e09d]*/
{}

/*[clinic input]
_imp.exec_dynamic -> int

    mod: object
    /

Initialize an extension module.
[clinic start generated code]*/

static int
_imp_exec_dynamic_impl(PyObject *module, PyObject *mod)
/*[clinic end generated code: output=f5720ac7b465877d input=9fdbfcb250280d3a]*/
{}


#endif /* HAVE_DYNAMIC_LOADING */

/*[clinic input]
_imp.exec_builtin -> int

    mod: object
    /

Initialize a built-in module.
[clinic start generated code]*/

static int
_imp_exec_builtin_impl(PyObject *module, PyObject *mod)
/*[clinic end generated code: output=0262447b240c038e input=7beed5a2f12a60ca]*/
{}

/*[clinic input]
_imp.source_hash

    key: long
    source: Py_buffer
[clinic start generated code]*/

static PyObject *
_imp_source_hash_impl(PyObject *module, long key, Py_buffer *source)
/*[clinic end generated code: output=edb292448cf399ea input=9aaad1e590089789]*/
{}


PyDoc_STRVAR(doc_imp,
"(Extremely) low-level import machinery bits as used by importlib.");

static PyMethodDef imp_methods[] =;


static int
imp_module_exec(PyObject *module)
{}


static PyModuleDef_Slot imp_slots[] =;

static struct PyModuleDef imp_module =;

PyMODINIT_FUNC
PyInit__imp(void)
{}