Skip to content Skip to sidebar Skip to footer

Loading Modules By Imp.load_source With Same Name Resulting Merger Of The Modules

I would like to know if the following behavior is expected or a bug. I'm using CPython2.7 Create a file x.py def funcA(): print 'funcA of x.py' def funcB(): print 'funcB o

Solution 1:

This is an expected behavior. See http://docs.python.org/2/library/imp.html

imp.load_source(name, pathname[, file])

Load and initialize a module implemented as a Python source file and return its module object. If the module was already initialized, it will be initialized again. The name argument is used to create or access a module object.

Since your second module has the same name as the first module, it won't replace the first one, but will be merged into the first one.

The source code gives us the same answer. imp is a built-in module, defined in import.c. Let's look at at the definition of load_source

static PyObject *
load_source_module(char *name, char *pathname, FILE *fp){
    ......
    m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname);
    Py_DECREF(co);

    return m;
}

It's just a wrapper for PyImport_ExecCodeModuleEx.

PyObject *
PyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname)
{
    PyObject *modules = PyImport_GetModuleDict();
    PyObject *m, *d, *v;
    m = PyImport_AddModule(name);
    ......
    d = PyModule_GetDict(m);
    ......
    v = PyEval_EvalCode((PyCodeObject *)co, d, d);
    ......
}

Now, we just need to focus on PyImport_AddModule. Python uses it to obtain a module object. Your parsed source file will be put into this module object.

PyObject *
PyImport_AddModule(constchar *name){
    PyObject *modules = PyImport_GetModuleDict();
    PyObject *m;

    if ((m = PyDict_GetItemString(modules, name)) != NULL &&
        PyModule_Check(m))
        return m;
    m = PyModule_New(name);
    if (m == NULL)
        returnNULL;
    if (PyDict_SetItemString(modules, name, m) != 0) {
        Py_DECREF(m);
        returnNULL;
    }
    Py_DECREF(m); /* Yes, it still exists, in modules! */return m;
}

Finally, we find the answer. Given a name, if some module already has this name, namely, name in sys.modules, Python won't create a new module, but will reuse that module.

Post a Comment for "Loading Modules By Imp.load_source With Same Name Resulting Merger Of The Modules"