
/* Testing module for single-phase initialization of extension modules

This file contains several distinct modules, meaning each as its own name
and its own init function (PyInit_...).  The default import system will
only find the one matching the filename: _testsinglephase.  To load the
others you must do so manually.  For example:

```python
name = '_testsinglephase_base_wrapper'
filename = _testsinglephase.__file__
loader = importlib.machinery.ExtensionFileLoader(name, filename)
spec = importlib.util.spec_from_file_location(name, filename, loader=loader)
mod = importlib._bootstrap._load(spec)
loader.exec_module(module)
sys.modules[modname] = module
```

(The last two lines are just for completeness.)

Here are the modules:

* _testsinglephase
   * def: _testsinglephase_basic,
      * m_name: "_testsinglephase"
      * m_size: -1
   * state
      * process-global
         * <int> initialized_count  (default to -1; will never be 0)
         * <module_state> module  (see module state below)
      * module state: no
      * initial __dict__: see common initial __dict__ below
   * init function
      1. create module
      2. clear <global>.module
      3. initialize <global>.module: see module state below
      4. initialize module: set initial __dict__
      5. increment <global>.initialized_count
   * functions
      * (3 common, see below)
      * initialized_count() - return <global>.module.initialized_count
   * import system
      * caches
         * global extensions cache: yes
         * def.m_base.m_copy: yes
         * def.m_base.m_init: no
         * per-interpreter cache: yes  (all single-phase init modules)
      * load in main interpreter
         * initial  (not already in global cache)
            1. get init function from shared object file
            2. run init function
            3. copy __dict__ into def.m_base.m_copy
            4. set entry in global cache
            5. set entry in per-interpreter cache
            6. set entry in sys.modules
         * reload  (already in sys.modules)
            1. get def from global cache
            2. get module from sys.modules
            3. update module with contents of def.m_base.m_copy
         * already loaded in other interpreter  (already in global cache)
            * same as reload, but create new module and update *it*
         * not in any sys.modules, still in global cache
            * same as already loaded
      * load in legacy (non-isolated) interpreter
         * same as main interpreter
      * unload: never  (all single-phase init modules)
* _testsinglephase_basic_wrapper
   * identical to _testsinglephase except module name
* _testsinglephase_basic_copy
   * def: static local variable in init function
      * m_name: "_testsinglephase_basic_copy"
      * m_size: -1
   * state: same as _testsinglephase
   * init function: same as _testsinglephase
   * functions: same as _testsinglephase
   * import system: same as _testsinglephase
* _testsinglephase_with_reinit
   * def: _testsinglephase_with_reinit,
      * m_name: "_testsinglephase_with_reinit"
      * m_size: 0
   * state
      * process-global state: no
      * module state: no
      * initial __dict__: see common initial __dict__ below
   * init function
      1. create module
      2. initialize temporary module state (local var): see module state below
      3. initialize module: set initial __dict__
   * functions: see common functions below
   * import system
      * caches
         * global extensions cache: only if loaded in main interpreter
         * def.m_base.m_copy: no
         * def.m_base.m_init: only if loaded in the main interpreter
         * per-interpreter cache: yes  (all single-phase init modules)
      * load in main interpreter
         * initial  (not already in global cache)
            * (same as _testsinglephase except step 3)
            1. get init function from shared object file
            2. run init function
            3. set def.m_base.m_init to the init function
            4. set entry in global cache
            5. set entry in per-interpreter cache
            6. set entry in sys.modules
         * reload  (already in sys.modules)
            1. get def from global cache
            2. call def->m_base.m_init to get a new module object
            3. replace the existing module in sys.modules
         * already loaded in other interpreter  (already in global cache)
            * same as reload (since will only be in cache for main interp)
         * not in any sys.modules, still in global cache
            * same as already loaded
      * load in legacy (non-isolated) interpreter
         * initial  (not already in global cache)
            * (same as main interpreter except skip steps 3 & 4 there)
            1. get init function from shared object file
            2. run init function
            ...
            5. set entry in per-interpreter cache
            6. set entry in sys.modules
         * reload  (already in sys.modules)
            * same as initial  (load from scratch)
         * already loaded in other interpreter  (already in global cache)
            * same as initial  (load from scratch)
         * not in any sys.modules, still in global cache
            * same as initial  (load from scratch)
      * unload: never  (all single-phase init modules)
* _testsinglephase_with_state
   * def: _testsinglephase_with_state,
      * m_name: "_testsinglephase_with_state"
      * m_size: sizeof(module_state)
   * state
      * process-global: no
      * module state: see module state below
      * initial __dict__: see common initial __dict__ below
   * init function
      1. create module
      3. initialize module state: see module state below
      4. initialize module: set initial __dict__
      5. increment <global>.initialized_count
   * functions: see common functions below
   * import system: same as _testsinglephase_basic_copy
* _testsinglephase_check_cache_first
   * def: _testsinglepahse_check_cache_first
      * m_name: "_testsinglephase_check_cache_first"
      * m_size: -1
   * state: none
   * init function:
      * tries PyState_FindModule() first
      * otherwise creates empty module
   * functions: none
   * import system: same as _testsinglephase
* _testsinglephase_with_reinit_check_cache_first
   * def: _testsinglepahse_with_reinit_check_cache_first
      * m_name: "_testsinglephase_with_reinit_check_cache_first"
      * m_size: 0
   * state: none
   * init function: same as _testsinglephase_check_cache_first
   * functions: none
   * import system: same as _testsinglephase_with_reinit
* _testsinglephase_with_state_check_cache_first
   * def: _testsinglepahse_with_state_check_cache_first
      * m_name: "_testsinglephase_with_state_check_cache_first"
      * m_size: 42
   * state: none
   * init function: same as _testsinglephase_check_cache_first
   * functions: none
   * import system: same as _testsinglephase_with_state

* _testsinglephase_circular
   Regression test for gh-123880.
   Does not have the common attributes & methods.
   See test_singlephase_circular test.test_import.SinglephaseInitTests.

Module state:

* fields
   * <PyTime_t> initialized - when the module was first initialized
   * <PyObject> *error
   * <PyObject> *int_const
   * <PyObject> *str_const
* initialization
   1. set state.initialized to the current time
   2. set state.error to a new exception class
   3. set state->int_const to int(1969)
   4. set state->str_const to "something different"

Common initial __dict__:

* error: state.error
* int_const: state.int_const
* str_const: state.str_const
* _module_initialized: state.initialized

Common functions:

* look_up_self() - return the module from the per-interpreter "by-index" cache
* sum() - return a + b
* state_initialized() - return state->initialized (or None if m_size == 0)

See Python/import.c, especially the long comments, for more about
single-phase init modules.
*/

#ifndef Py_BUILD_CORE_BUILTIN
#  define Py_BUILD_CORE_MODULE 1
#endif

//#include <time.h>
#include "Python.h"
#include "pycore_namespace.h"     // _PyNamespace_New()


typedef struct {
    PyTime_t initialized;
    PyObject *error;
    PyObject *int_const;
    PyObject *str_const;
} module_state;


/* Process-global state is only used by _testsinglephase
   since it's the only one that does not support re-init. */
static struct {
    int initialized_count;
    module_state module;
} global_state = {

#define NOT_INITIALIZED -1
    .initialized_count = NOT_INITIALIZED,
};

static void clear_state(module_state *state);

static void
clear_global_state(void)
{
    clear_state(&global_state.module);
    global_state.initialized_count = NOT_INITIALIZED;
}


static inline module_state *
get_module_state(PyObject *module)
{
    PyModuleDef *def = PyModule_GetDef(module);
    assert(def);

    if (def->m_size == -1) {
        return &global_state.module;
    }
    else if (def->m_size == 0) {
        return NULL;
    }
    else {
        module_state *state = (module_state*)PyModule_GetState(module);
        assert(state != NULL);
        return state;
    }
}

static void
clear_state(module_state *state)
{
    state->initialized = 0;
    Py_CLEAR(state->error);
    Py_CLEAR(state->int_const);
    Py_CLEAR(state->str_const);
}

static int
_set_initialized(PyTime_t *initialized)
{
    /* We go strictly monotonic to ensure each time is unique. */
    PyTime_t prev;
    if (PyTime_Monotonic(&prev) != 0) {
        return -1;
    }
    /* We do a busy sleep since the interval should be super short. */
    PyTime_t t;
    do {
        if (PyTime_Monotonic(&t) != 0) {
            return -1;
        }
    } while (t == prev);

    *initialized = t;
    return 0;
}

static int
init_state(module_state *state)
{
    assert(state->initialized == 0 &&
           state->error == NULL &&
           state->int_const == NULL &&
           state->str_const == NULL);

    if (_set_initialized(&state->initialized) != 0) {
        goto error;
    }
    assert(state->initialized > 0);

    /* Add an exception type */
    state->error = PyErr_NewException("_testsinglephase.error", NULL, NULL);
    if (state->error == NULL) {
        goto error;
    }

    state->int_const = PyLong_FromLong(1969);
    if (state->int_const == NULL) {
        goto error;
    }

    state->str_const = PyUnicode_FromString("something different");
    if (state->str_const == NULL) {
        goto error;
    }

    return 0;

error:
    clear_state(state);
    return -1;
}


static int
init_module(PyObject *module, module_state *state)
{
    if (PyModule_AddObjectRef(module, "error", state->error) != 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(module, "int_const", state->int_const) != 0) {
        return -1;
    }
    if (PyModule_AddObjectRef(module, "str_const", state->str_const) != 0) {
        return -1;
    }

    double d = PyTime_AsSecondsDouble(state->initialized);
    if (PyModule_Add(module, "_module_initialized", PyFloat_FromDouble(d)) < 0) {
        return -1;
    }

    return 0;
}


PyDoc_STRVAR(common_state_initialized_doc,
"state_initialized()\n\
\n\
Return the seconds-since-epoch when the module state was initialized.");

static PyObject *
common_state_initialized(PyObject *self, PyObject *Py_UNUSED(ignored))
{
    module_state *state = get_module_state(self);
    if (state == NULL) {
        Py_RETURN_NONE;
    }
    double d = PyTime_AsSecondsDouble(state->initialized);
    return PyFloat_FromDouble(d);
}

#define STATE_INITIALIZED_METHODDEF \
    {"state_initialized", common_state_initialized, METH_NOARGS, \
     common_state_initialized_doc}


PyDoc_STRVAR(common_look_up_self_doc,
"look_up_self()\n\
\n\
Return the module associated with this module's def.m_base.m_index.");

static PyObject *
common_look_up_self(PyObject *self, PyObject *Py_UNUSED(ignored))
{
    PyModuleDef *def = PyModule_GetDef(self);
    if (def == NULL) {
        return NULL;
    }
    return Py_NewRef(
            PyState_FindModule(def));
}

#define LOOK_UP_SELF_METHODDEF \
    {"look_up_self", common_look_up_self, METH_NOARGS, common_look_up_self_doc}


/* Function of two integers returning integer */

PyDoc_STRVAR(common_sum_doc,
"sum(i,j)\n\
\n\
Return the sum of i and j.");

static PyObject *
common_sum(PyObject *self, PyObject *args)
{
    long i, j;
    long res;
    if (!PyArg_ParseTuple(args, "ll:sum", &i, &j))
        return NULL;
    res = i + j;
    return PyLong_FromLong(res);
}

#define SUM_METHODDEF \
    {"sum", common_sum, METH_VARARGS, common_sum_doc}


PyDoc_STRVAR(basic_initialized_count_doc,
"initialized_count()\n\
\n\
Return how many times the module has been initialized.");

static PyObject *
basic_initialized_count(PyObject *self, PyObject *Py_UNUSED(ignored))
{
    assert(PyModule_GetDef(self)->m_size == -1);
    return PyLong_FromLong(global_state.initialized_count);
}

#define INITIALIZED_COUNT_METHODDEF \
    {"initialized_count", basic_initialized_count, METH_NOARGS, \
     basic_initialized_count_doc}


PyDoc_STRVAR(basic__clear_globals_doc,
"_clear_globals()\n\
\n\
Free all global state and set it to uninitialized.");

static PyObject *
basic__clear_globals(PyObject *self, PyObject *Py_UNUSED(ignored))
{
    assert(PyModule_GetDef(self)->m_size == -1);
    clear_global_state();
    Py_RETURN_NONE;
}

#define _CLEAR_GLOBALS_METHODDEF \
    {"_clear_globals", basic__clear_globals, METH_NOARGS, \
     basic__clear_globals_doc}


PyDoc_STRVAR(basic__clear_module_state_doc, "_clear_module_state()\n\
\n\
Free the module state and set it to uninitialized.");

static PyObject *
basic__clear_module_state(PyObject *self, PyObject *Py_UNUSED(ignored))
{
    module_state *state = get_module_state(self);
    if (state != NULL) {
        clear_state(state);
    }
    Py_RETURN_NONE;
}

#define _CLEAR_MODULE_STATE_METHODDEF \
    {"_clear_module_state", basic__clear_module_state, METH_NOARGS, \
     basic__clear_module_state_doc}


/*********************************************/
/* the _testsinglephase module (and aliases) */
/*********************************************/

/* This ia more typical of legacy extensions in the wild:
   - single-phase init
   - no module state
   - does not support repeated initialization
    (so m_copy is used)
   - the module def is cached in _PyRuntime.extensions
     (by name/filename)

   Also note that, because the module has single-phase init,
   it is cached in interp->module_by_index (using mod->md_def->m_base.m_index).
 */

static PyMethodDef TestMethods_Basic[] = {
    LOOK_UP_SELF_METHODDEF,
    SUM_METHODDEF,
    STATE_INITIALIZED_METHODDEF,
    INITIALIZED_COUNT_METHODDEF,
    _CLEAR_GLOBALS_METHODDEF,
    {NULL, NULL}           /* sentinel */
};

static struct PyModuleDef _testsinglephase_basic = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_testsinglephase",
    .m_doc = PyDoc_STR("Test module _testsinglephase"),
    .m_size = -1,  // no module state
    .m_methods = TestMethods_Basic,
};

static PyObject *
init__testsinglephase_basic(PyModuleDef *def)
{
    if (global_state.initialized_count == -1) {
        global_state.initialized_count = 0;
    }

    PyObject *module = PyModule_Create(def);
    if (module == NULL) {
        return NULL;
    }
#ifdef Py_GIL_DISABLED
    PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED);
#endif

    module_state *state = &global_state.module;
    // It may have been set by a previous run or under a different name.
    clear_state(state);
    if (init_state(state) < 0) {
        Py_CLEAR(module);
        return NULL;
    }

    if (init_module(module, state) < 0) {
        Py_CLEAR(module);
        goto finally;
    }

    global_state.initialized_count++;

finally:
    return module;
}

PyMODINIT_FUNC
PyInit__testsinglephase(void)
{
    return init__testsinglephase_basic(&_testsinglephase_basic);
}


PyMODINIT_FUNC
PyInit__testsinglephase_basic_wrapper(void)
{
    return PyInit__testsinglephase();
}


PyMODINIT_FUNC
PyInit__testsinglephase_basic_copy(void)
{
    static struct PyModuleDef def = {
        PyModuleDef_HEAD_INIT,
        .m_name = "_testsinglephase_basic_copy",
        .m_doc = PyDoc_STR("Test module _testsinglephase_basic_copy"),
        .m_size = -1,  // no module state
        .m_methods = TestMethods_Basic,
    };
    return init__testsinglephase_basic(&def);
}


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

/* This ia less typical of legacy extensions in the wild:
   - single-phase init  (same as _testsinglephase above)
   - no module state
   - supports repeated initialization
     (so m_copy is not used)
   - the module def is not cached in _PyRuntime.extensions

   At this point most modules would reach for multi-phase init (PEP 489).
   However, module state has been around a while (PEP 3121),
   and most extensions predate multi-phase init.

   (This module is basically the same as _testsinglephase,
    but supports repeated initialization.)
 */

static PyMethodDef TestMethods_Reinit[] = {
    LOOK_UP_SELF_METHODDEF,
    SUM_METHODDEF,
    STATE_INITIALIZED_METHODDEF,
    {NULL, NULL}           /* sentinel */
};

static struct PyModuleDef _testsinglephase_with_reinit = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_testsinglephase_with_reinit",
    .m_doc = PyDoc_STR("Test module _testsinglephase_with_reinit"),
    .m_size = 0,
    .m_methods = TestMethods_Reinit,
};

PyMODINIT_FUNC
PyInit__testsinglephase_with_reinit(void)
{
    /* We purposefully do not try PyState_FindModule() first here
       since we want to check the behavior of re-loading the module. */
    PyObject *module = PyModule_Create(&_testsinglephase_with_reinit);
    if (module == NULL) {
        return NULL;
    }
#ifdef Py_GIL_DISABLED
    PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED);
#endif

    assert(get_module_state(module) == NULL);

    module_state state = {0};
    if (init_state(&state) < 0) {
        Py_CLEAR(module);
        return NULL;
    }

    if (init_module(module, &state) < 0) {
        Py_CLEAR(module);
        goto finally;
    }

finally:
    /* We only needed the module state for setting the module attrs. */
    clear_state(&state);
    return module;
}


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

/* This is less typical of legacy extensions in the wild:
   - single-phase init  (same as _testsinglephase above)
   - has some module state
   - supports repeated initialization
     (so m_copy is not used)
   - the module def is not cached in _PyRuntime.extensions

   At this point most modules would reach for multi-phase init (PEP 489).
   However, module state has been around a while (PEP 3121),
   and most extensions predate multi-phase init.
 */

static PyMethodDef TestMethods_WithState[] = {
    LOOK_UP_SELF_METHODDEF,
    SUM_METHODDEF,
    STATE_INITIALIZED_METHODDEF,
    _CLEAR_MODULE_STATE_METHODDEF,
    {NULL, NULL}           /* sentinel */
};

static struct PyModuleDef _testsinglephase_with_state = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_testsinglephase_with_state",
    .m_doc = PyDoc_STR("Test module _testsinglephase_with_state"),
    .m_size = sizeof(module_state),
    .m_methods = TestMethods_WithState,
};

PyMODINIT_FUNC
PyInit__testsinglephase_with_state(void)
{
    /* We purposefully do not try PyState_FindModule() first here
       since we want to check the behavior of re-loading the module. */
    PyObject *module = PyModule_Create(&_testsinglephase_with_state);
    if (module == NULL) {
        return NULL;
    }
#ifdef Py_GIL_DISABLED
    PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED);
#endif

    module_state *state = get_module_state(module);
    assert(state != NULL);
    if (init_state(state) < 0) {
        Py_CLEAR(module);
        return NULL;
    }

    if (init_module(module, state) < 0) {
        clear_state(state);
        Py_CLEAR(module);
        goto finally;
    }

finally:
    return module;
}


/****************************************************/
/* the _testsinglephase_*_check_cache_first modules */
/****************************************************/

/* Each of these modules should only be freshly loaded.  That means
   clearing the caches and each module def's m_base after each load. */

static struct PyModuleDef _testsinglephase_check_cache_first = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_testsinglephase_check_cache_first",
    .m_doc = PyDoc_STR("Test module _testsinglephase_check_cache_first"),
    .m_size = -1,  // no module state
};

PyMODINIT_FUNC
PyInit__testsinglephase_check_cache_first(void)
{
    assert(_testsinglephase_check_cache_first.m_base.m_index == 0);
    PyObject *mod = PyState_FindModule(&_testsinglephase_check_cache_first);
    if (mod != NULL) {
        return Py_NewRef(mod);
    }
    return PyModule_Create(&_testsinglephase_check_cache_first);
}


static struct PyModuleDef _testsinglephase_with_reinit_check_cache_first = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_testsinglephase_with_reinit_check_cache_first",
    .m_doc = PyDoc_STR("Test module _testsinglephase_with_reinit_check_cache_first"),
    .m_size = 0,  // no module state
};

PyMODINIT_FUNC
PyInit__testsinglephase_with_reinit_check_cache_first(void)
{
    assert(_testsinglephase_with_reinit_check_cache_first.m_base.m_index == 0);
    PyObject *mod = PyState_FindModule(&_testsinglephase_with_reinit_check_cache_first);
    if (mod != NULL) {
        return Py_NewRef(mod);
    }
    return PyModule_Create(&_testsinglephase_with_reinit_check_cache_first);
}


static struct PyModuleDef _testsinglephase_with_state_check_cache_first = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_testsinglephase_with_state_check_cache_first",
    .m_doc = PyDoc_STR("Test module _testsinglephase_with_state_check_cache_first"),
    .m_size = 42,  // not used
};

PyMODINIT_FUNC
PyInit__testsinglephase_with_state_check_cache_first(void)
{
    assert(_testsinglephase_with_state_check_cache_first.m_base.m_index == 0);
    PyObject *mod = PyState_FindModule(&_testsinglephase_with_state_check_cache_first);
    if (mod != NULL) {
        return Py_NewRef(mod);
    }
    return PyModule_Create(&_testsinglephase_with_state_check_cache_first);
}


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

static PyObject *static_module_circular;

static PyObject *
circularmod_clear_static_var(PyObject *self, PyObject *arg)
{
    PyObject *result = static_module_circular;
    static_module_circular = NULL;
    return result;
}

static struct PyModuleDef _testsinglephase_circular = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_testsinglephase_circular",
    .m_doc = PyDoc_STR("Test module _testsinglephase_circular"),
    .m_methods = (PyMethodDef[]) {
        {"clear_static_var", circularmod_clear_static_var, METH_NOARGS,
         "Clear the static variable and return its previous value."},
        {NULL, NULL}           /* sentinel */
    }
};

PyMODINIT_FUNC
PyInit__testsinglephase_circular(void)
{
    if (!static_module_circular) {
        static_module_circular = PyModule_Create(&_testsinglephase_circular);
        if (!static_module_circular) {
            return NULL;
        }
    }
    static const char helper_mod_name[] = (
        "test.test_import.data.circular_imports.singlephase");
    PyObject *helper_mod = PyImport_ImportModule(helper_mod_name);
    Py_XDECREF(helper_mod);
    if (!helper_mod) {
        return NULL;
    }
    if(PyModule_AddStringConstant(static_module_circular,
                                  "helper_mod_name",
                                  helper_mod_name) < 0) {
        return NULL;
    }
    return Py_NewRef(static_module_circular);
}
