Search code examples
pythoncpython-3.6python-c-api

(Python/C API) "ModuleNotFoundError" for modules in subdirectories


I am using Python 3 within a C program. What I wish to do is "run" a single Python file (.py) which will be the main file for a larger Python project.

When I use import within this Python file, it works fine for other Python files in the same directory. In fact, the import works for files in sub-directories too whenever I run the .py file using "Python" in the terminal.

However, if I run it using PyRun_SimpleFile in C, I receive a "ModuleNotFoundError" error.

Here is my directory setup:

Project/
|-- Program.cpp
|-- Program.exe
|-- __init__.py
|-- bla.py
|-- Test/
|   |-- __init__.py
|   |-- bla2.py

Preferably, I do not want to use sys.path.append('./Test') so I can use the sub-directory names within the imports.

Here are the contents of all relevant files:


bla.py

import Test.bla2

bla2.py

print("in bla2.py now!")

Program.cpp

#include <Python.h>
#include <iostream>

int main(int argc, char **argv)
{
    Py_Initialize();

    FILE *file = _Py_fopen( "bla.py", "r" ); 
    PyRun_SimpleFile(file, "bla.py");

    Py_Finalize();
    return 0;
}

Solution

  • You just need to add

    PySys_SetArgv(1, argv);
    

    after Py_Initialize (documentation). This prepends the directory that your program is in to your Python path. (This is equivalent to prepending . to the path, rather than ./Test, but it should be more reliable, for example if your program is not started from its own directory. It gets the needed information on where your program is located from C++ argv)

    It's probably a bad idea to call your module Test. There's a built-in Python module called test, and on a case-insensitive OS like Windows that might conflict and get loaded instead.