Why does PyImport_Import fail to load a module from the current directory?
You need to call PySys_SetArgv(int argc, char **argv, int updatepath)
for the relative imports to work. This will add the path of the script being executed to sys.path
if updatepath
is 0
(refer to the docs for more information).
The following should do the trick
#include <Python.h>
int
main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PySys_SetArgv(argc, argv); // must call this to get sys.argv and relative imports
PyRun_SimpleString("import os, sys\n"
"print sys.argv, \"\\n\".join(sys.path)\n"
"print os.getcwd()\n"
"import thing\n" // import a relative module
"thing.printer()\n");
Py_Finalize();
return 0;
}
PyImport_Import cannot find module
Use Py_SetPath
before Py_Initialize()
to set the sys.path
.
Here is a longer list of what can be done before you initialize the interpreter: pre-init-safe
Isolate the embedded Python interpreter and set the path properly to avoid problems with partially using the modules of the installed Python version.
PyImport_Import fails to import module that contains imports
I found the solution. This happens because the debug symbols of numpy and scipy are missing. Setting visual studio in release mode solved the problem
PyImport_Import failing when submodules are imported in a python module
Use PyList_Insert
in place of PyList_Append
to get test imported from the location you want.
as @DavidW mentioned there is an importable module in the core libs called test
.
change
PyList_Append(sysPath, PyUnicode_FromString("/jarvis_repo/src/cpp/packages/jarvis/nlp/"));
to
PyList_Insert(sysPath, 0, PyUnicode_FromString("/jarvis_repo/src/cpp/packages/jarvis/nlp/"));
so the test
module is first found in /jarvis_repo/src/cpp/packages/jarvis/nlp/ and not in core libs.
Note: you should rename test
instead
PyImport_Import fails (returns NULL)
I have resolved this issue by setting PYTHONPATH to pwd
. Also module name (without .py) should be set for argv[1].
Thank you!
Python Embedding: PyImport_Import not from the current directory
Just found the answer I was looking for at http://realmike.org/blog/2012/07/08/embedding-python-tutorial-part-1/
Normally, when importing a module, Python tries to find the module
file next to the importing module (the module that contains the import
statement). Python then tries the directories in “sys.path”. The
current working directory is usually not considered. In our case, the
import is performed via the API, so there is no importing module in
whose directory Python could search for “shout_filter.py”. The plug-in
is also not on “sys.path”. One way of enabling Python to find the
plug-in is to add the current working directory to the module search
path by doing the equivalent of “sys.path.append(‘.’)” via the API.
Py_Initialize();
PyObject* sysPath = PySys_GetObject((char*)"path");
PyObject* programName = PyString_FromString(SplitFilename(argv[1]).c_str());
PyList_Append(sysPath, programName);
Py_DECREF(programName);
SplitFilename
is a function I wrote to get the directory.
Why does importing a dotted module name fail when upper level is matched by a module in current directory?
An import statement like import foo.bar.baz
first imports foo
, then asks it for bar
, and then asks foo.bar
for baz
. Whether foo
will, once imported, be able to satisfy the request for bar
or bar.baz
is unimportant to the import of foo
. It's just a module. There is only one foo
module. Both import foo
and import foo.bar.baz
will find the same module -- just like any other way of importing the foo
module.
There is actually a way for foo
to be a single module, rather than a package, and still be able to satisfy a statement like import foo.bar.baz
: it can add "foo.bar"
and "foo.bar.baz"
to the sys.modules
dict. This is exactly what the os
module does with os.path
: it imports the right "path" module for the platform (posixpath
, ntpath
, os2path
, etc), and assigns it to the path
attribute. Then it does sys.modules["os.path"] = path
to make that module importable as os.path
, so a statement like import os.path
works. There isn't really a reason to do this -- os.path
is available without importing it as well -- but it's possible.
how to load a custom python module in c
I think it should be in the same directory or in sys.path
as it loads a module by name, this should work:
./call multiply multiply 5 6
Update: if I add the current directory explicitly to sys.path
it works:
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\".\")");
And this prints:
./call multiply multiply 5 6
('Will compute', 5, 'times', 6)
Result of call: 30
Update: I've asked a relevant question and it seems that if you just add PySys_SetArgv
instead it works:
Py_Initialize();
PySys_SetArgv(argc, argv);
The reason is mentioned here:
Otherwise (that is, if argc is 0 or argv[0] doesn’t point to an
existing file name), an empty string is prepended to sys.path, which
is the same as prepending the current working directory (".")
And this is the question you can check the answers there too:
Why does PyImport_Import fail to load a module from the current directory?
PyImport_Import fails - Returns NULL
I thought that PyBytes_FromString
was the the 3.x alternative of PyString_From
.
I was wrong. PyUnicode_FromString
is the correct alternative.
(Thanks to @wakjah for given me the tip of using error handling)
Related Topics
How to Make a Call to an Executable from Python Script
Python3.6 Importerror: Cannot Import Name 'Main' Linux Rhel6
Show Default Value for Editing on Python Input Possible
Send File Using Post from a Python Script
How to Zip Two Differently Sized Lists, Repeating the Shorter List
Sftp in Python? (Platform Independent)
Horizontal Stacked Bar Plot and Add Labels to Each Section
Python Pandas: Apply a Function with Arguments to a Series
How to Connect to Tor Browser Using Python
Safe Method to Get Value of Nested Dictionary
Authenticate from Linux to Windows SQL Server with Pyodbc
Run a Linux System Command as a Superuser, Using a Python Script
How to Postpone/Defer the Evaluation of F-Strings
Python Date String to Date Object
What Is the Fastest Way to Flatten Arbitrarily Nested Lists in Python
Does Python Support Multithreading? Can It Speed Up Execution Time