2

I have PythonCode.py:

import os, ctypes
print "ctypes are imported"

And CCode.c:

...
PySys_SetPath(path_to_PythonCode);
PyObject *pModule = PyImport_ImportModule("PythonCode");
if (!pModule) {
  PyErr_Print();
  return;
}
...

PyErr_Print() prints:

Traceback (most recent call last):   File ".../PythonCode.py", line 1,
  in <module> import os, ctypes
ImportError: No module named ctypes

Executing Python code in terminal shows that ctypes do exist:

$ python --version
Python 2.7.1
$ python PythonCode.py
ctypes are imported

Why Python/C API cannot import ctypes?

AlexP
  • 1,416
  • 1
  • 19
  • 26
  • 3
    This looks suspiciously like a classic circular import problem in Python, only taking a trip through C to get there. You try to import the Python module in C, but the Python module is trying to import the C library as part of ctypes, so you end up trying to get ctypes from sys.modules before the interpreter has had a chance to completely construct it, since the C code is still in the middle of executing. It's not that it doesn't exist, it's that at the point you try to access it in your program flow, the state of the module is incomplete, and thus both unloaded and unloadable. – Silas Ray Dec 20 '12 at 12:54
  • 3
    You replaced the default `sys.path` list with a single path. Instead you can append or insert the new path: `PyObject *sysPath = PySys_GetObject("path"); PyObject *path = PyString_FromString(path_to_PythonCode); PyList_Append(sysPath, path); // or PyList_Insert(sysPath, 0, path);` (needs error handling). – Eryk Sun Dec 20 '12 at 13:42
  • 1
    @eryksun: Thank you! That did the trick! Why are you answering in comments? – AlexP Dec 20 '12 at 14:05
  • @AlexP: I was just waiting to see if someone else was going to write a more complete answer. I'll add it as answer. – Eryk Sun Dec 20 '12 at 14:50

1 Answers1

4

You replaced the default sys.path list with a single path. Instead you can insert the new path:

PyObject *sys_path, *path;

sys_path = PySys_GetObject("path");
if (sys_path == NULL || !PyList_Check(sys_path)) {   
    /* ZOMG! That's so wrong... */
    return;
}
path = PyString_FromString(path_to_PythonCode);
PyList_Insert(sys_path, 0, path);
Py_DECREF(path);
Eryk Sun
  • 33,190
  • 5
  • 92
  • 111