I am attempting to call a function print_stuff
which is a member of the class Spam
from a user-defined Python module Spam
in C++
#define PY_SSIZE_T_CLEAN
#include <Python.h>
int main()
{
Py_Initialize();
//modify python module search path
auto modulePath = /* hardcoded search path for module */
PyObject* sysPath = PySys_GetObject("path");
PyList_Append(sysPath, PyUnicode_FromString(modulePath));
PyObject* pModule = PyImport_ImportModule("Spam");
PyObject* pDict = PyModule_GetDict(pModule);
PyObject* pFunc = PyObject_GetAttrString(pDict, "print_stuff");
if (pFunc != NULL)
PyObject_CallObject(pFunc, NULL);
else
PyErr_Print();
return 1;
}
My Python module consists of 2 files; Spam.py
and __init__.py
both located in same directory /Spam
which is a subfolder of the directory containing my VS solution and C++ code.
Spam.py
class Spam:
def __init__(self):
pass
def print_stuff(self):
print((1,2,3))
__init__.py
import Spam as Spam
When I run my C++ code I get the following error: AttributeError: 'dict' object has no attribute 'print_stuff'
I have tried getting the contents of the dictionary returned from PyModule_GetDict(pModule)
as a string and confirmed that it doesn't mention the function.
I looked up the docs for PyModule_GetDict
which says that it returns the same dictionary as you would get calling __dict__
on the module in Python. When I tried calling Spam.__dict__
inside of __init__.py
I got the same result, my function was missing, but when I tried Spam.Spam.__dict__
I got a dictionary containing the function.
From this I decided to change the import statement to from Spam import Spam
so that Spam.__dict__
would now include my function, which it did. However, nothing changes when I run my C++ code. I still get the same error from my dictionary and am still unable to call my function.
I did wonder if it was an issue of not having an instance of the class in the my C++ code, so I also tried removing the surrounding class and having Spam.py
just contain the function definition and then importing that but, again, I got the same error.
I have a hunch this is some kind of namespace issue, otherwise I don't see how PyModule_GetDict
and __dict__
could return different dictionaries for the same module, but honestly I don't know where to go from here.
Is my class Spam
not considered part of the module I am trying to import from C++? Is my __init__.py
missing something or perhaps I need to include another statement in C++ to import the class after I have imported the module or have I not correctly imported the module in the first place?
I have seen similar questions before but they tended to be in cases where exceptions were raised, the search path was incorrect, or where one the prerequisite values had returned NULL. I am fairly experienced with C++ but am new to Python and newer still to the Python/C API, although I have read the docs covering the basics of the API and how modules work in Python.