Hello everyone,

I am getting ImportError when I tried to do pure embedding and call Python function from C. The Python code is named dummy.py given by:

def multiply(x, y):
   print x, y
   z = x * y
   return z;

It is called by the c program "calldummy.c" given by:

#include "python2.5/Python.h"
#include <stdio.h>

int main()
{
    double answer = 0.0;
    PyObject *modname, *mod, *mdict, *func, *arg1, *arg2, *args, *result;

    Py_Initialize();
    printf("Python initialized...\n");
    modname = PyString_FromString("dummy");
    printf("Modname loaded\n");
    if (modname == NULL)
    {
       printf("Specified module doesn't exist\n");
       Py_Exit(0);
       return 1;
    }
    mod = PyImport_Import(modname);
    printf("Module imported\n");
    if (mod)
    {
        printf("Imported module not null\n");
        func = PyObject_GetAttrString(mod, "multiply");
        printf("Got function attr\n");
        if (func)
        {
            if (PyCallable_Check(func))
            {
                printf("Function is callable\n");
                long a, b;
                a = 6;
                b = 5;
                arg1 = PyInt_FromLong(a);
                arg2 = PyInt_FromLong(b);
                args = PyTuple_New(2);
                PyTuple_SetItem(args, 0, arg1);
                PyTuple_SetItem(args, 1, arg2);
                result = PyObject_CallObject(func, args);
                if (result)
                {
                    if (PyInt_Check(result))
                        answer = PyInt_AsLong(result);
                    else if (PyFloat_Check(result))
                        answer = PyFloat_AsDouble(result);
                    printf("Answer: %lf\n", answer);
                    Py_XDECREF(result);
                }
                else
                {
                    printf("Result is null!\n");
                    return 1;
                }
                Py_DECREF(arg1);
                Py_DECREF(arg2);
                Py_DECREF(args);
            }
            else
            {
                printf("Function not callable\n");
                Py_Exit(0);
                return 1;
            }
            Py_XDECREF(func);
        }
        else
        {
            printf("Specified function doesn't exist\n");
            Py_Exit(0);
            return 1;
        }
        Py_DECREF(mod);
    }
    else
    {
            printf("Module cannot be imported\n");
            Py_Exit(0);
            return 1;
    }
    Py_DECREF(modname);
    printf("6 x 5 = %lf\n", answer);
    Py_Finalize();
    return 0;
}

Both the a.out created by compiling and linking the C program and dummy.py exist in the same directory. I am getting the following error:
Exception exceptions.ImportError: 'No module named dummy' in 'garbage collection' ignored
If I invoke Python command line interpreter from the same directory and try to import dummy and execute the function, it works fine.

Please help.

Thanks,
Sundar

There are several solutions to this problem. The simplest solution is to put dummy.py in a directory which appears in your PYTHONPATH environment variable. You can create a directory to routinely store your python modules and add this directory to your PYTHONPATH.

Figured that out. Even if we have the Python script in the same directory or we add the directory in which the python file exist in PYTHONPATH, the C program might not be able to recognize that. In such case, just add the following lines immediately after Py_Initialize(); :

PyRun_SimpleString("import sys");
    strcpy(syspath, "sys.path.append('");
    if (getcwd(pwd, sizeof(pwd)) != NULL)
        strcat(syspath, pwd);
    strcat(syspath, "')");
    PyRun_SimpleString(syspath);

This is similar to adding sys.path from Python console.

Figured that out. Even if we have the Python script in the same directory or we add the directory in which the python file exist in PYTHONPATH, the C program might not be able to recognize that. In such case, just add the following lines immediately after Py_Initialize(); :

PyRun_SimpleString("import sys");
    strcpy(syspath, "sys.path.append('");
    if (getcwd(pwd, sizeof(pwd)) != NULL)
        strcat(syspath, pwd);
    strcat(syspath, "')");
    PyRun_SimpleString(syspath);

This is similar to adding sys.path from Python console.

But it will work only if dummy.py is in the current working directory. You should use the directory which contains dummy.py instead...
You can also use strcpy(syspath, "import sys;sys.path.append('"); and run PyRun_SimpleString only once.

Also if the directory is in PYTHONPATH, you can try PyRun_SimpleString("import dummy") . This will put dummy in sys.modules and your second import in C should work...

But it will work only if dummy.py is in the current working directory. You should use the directory which contains dummy.py instead...
You can also use strcpy(syspath, "import sys;sys.path.append('"); and run PyRun_SimpleString only once.

Also if the directory is in PYTHONPATH, you can try PyRun_SimpleString("import dummy") . This will put dummy in sys.modules and your second import in C should work...

Gotcha. Working. Thanks a lot, Gribouillis!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.