error: [WinError 2] The system cannot find the file specified while using distutils in python - python

I am trying to call a C function from Python (Extending Python with C).
I built a hello.c file and a setup.py file. When I run the setup file it's supposed to build a Python extension so that I can import it in Python.
But, when I try to run python setup.py install I am getting the error
error: [WinError 2] The system cannot find the file specified
I tried setting up the environmental variable, insert path in to sys, but still the error persists.
Can someone identify where I'm going wrong?
setup.py:
from distutils.core import setup, Extension
module1 = Extension('helloworld', sources = ['hello.c'])
setup(name='helloworld', version='1.0', ext_modules=[module1])
hello.c:
#include <Python.h>
static PyObject* helloworld(PyObject* self, PyObject* args) {
return Py_BuildValue("s", "Hello, Python extensions!!");
}
static char helloworld_docs[] =
"helloworld( ): Any message you want to put here!!\n";
static PyMethodDef helloworld_funcs[] = {
{"helloworld", (PyCFunction)helloworld,
METH_NOARGS, helloworld_docs},
{NULL}
};
void inithelloworld(void) {
Py_InitModule3("helloworld", helloworld_funcs,
"Extension module example!");
}
error:

Related

Importing python file to c++ program - ModuleNotFoundError

Following this thread
Assume I have the following files in the directory prog:
main.cpp (located in the directory prog)
int main(int argc, char *argv[]){
Py_Initialize();
//Adding current path
PyObject* sys = PyImport_ImportModule("sys");
PyObject* path = PyObject_GetAttrString(sys, "path");
PyObject* cur_dir = PyUnicode_FromString("");
PyList_Append(path, cur_dir);
PyObject* myModuleString = PyUnicode_DecodeFSDefault((char*)"multiset_bell_numbers.py");
PyObject *pModule = PyImport_Import(myModuleString);
if (pModule == nullptr) {
PyErr_Print();
throw std::runtime_error("pModule is empty");
}
return 0;
}
multiset_bell_numbers.py (located in the directory prog)
from sympy.utilities.iterables import multiset_partitions
def calc_partitions(arr):
res = list(multiset_partitions(arr))
res.sort(key=lambda part:len(part))
return res
CMakeLists.txt
cmake_minimum_required(VERSION 3.24)
project(prog)
set(CMAKE_CXX_STANDARD 17)
find_package(Python REQUIRED COMPONENTS Interpreter Development)
include_directories(${Python_INCLUDE_DIRS})
add_executable(prog main.cpp)
target_link_libraries(prog ${Python_LIBRARIES})
But still got an error:
ModuleNotFoundError: No module named 'multiset_bell_numbers'
I have also tried to remove ".py" from the suffix of the string
What should I do?
In order for Python to find the multiset_bell_numbers module, it needs to be located in a directory that is in the Python Module Search Path.
The following directories will be checked:
The current folder from which the program executes.
A list of folders specified in the PYTHONPATH environment variable, if you set it before.
An installation-dependent list of folders that you configured when you installed Python.
If you ensure that the multiset_bell_numbers is in the same directory that the program is executed from, it should import successfully.
If that is not feasible, you can try updating PYTHONPATH to include the directory containing your module.

PyImport_Import cannot find module

I'm trying to call a python function inside my c++
When i import my python module it gives this error:
ModuleNotFoundError: No module named 'test'
Here is how i'm importing the module:
#define PY_SSIZE_T_CLEAN
#include <Python.h>
int main()
{
Py_Initialize();
PyObject *pName = PyUnicode_FromString("test");
PyObject *pModule = PyImport_Import(pName);
if (pModule == nullptr)
{
PyErr_Print();
std::exit(1);
}
Py_Finalize();
return 0;
}
I feel like this must have to do with my project structure. It currently looks like this:
project
|-- main.cpp
|-- test.py
I'm not sure if it's worth mentioning, but the executable is in the same directory, and it's being run from that directory aswell.
How can i fix this?
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.
This was solved by setting the "PYTHONPATH" environment variable:
setenv("PYTHONPATH", ".", 1);
Thanks #Botje
As dwib mentioned I was able to overcome by the error by setting the PYTHONPATH variable in my zshrc (may be bashrc for you) file.
export PYTHONPATH=$PATH:/home/jk/jk/c
where /home/jk/jk/c is the folder where my file was residing.
Also sourced it
. ~/.zshrc

Python CExtension gives ModuleNotFoundError

I am using Python 3 with Anaconda Spyder on CentOS 7. I am trying to get the Python CExtension working by following this video.
https://www.youtube.com/watch?v=a65JdvOaygM
I have all of my files in /home/peter/pythonCExtensions which is in the PYTHONPATH
I have a file myModule.c that has the following contents.
#include <stdio.h>
#include <stdlib.h>
#include "/home/peter/anaconda3/include/python3.7m/Python.h"
int Cfib(int n)
{
if (n<2){
return n;
} else {
return Cfib(n-1)+Cfib(n-2);
}
}
static PyObject* fib(PyObject* self, PyObject* args)
{
int n;
if (!PyArg_ParseTuple(args, "i", &n))
return NULL;
return Py_BuildValue("i", Cfib(n));
}
static PyObject* version(PyObject* self){
return Py_BuildValue("s", "Version 1.0");
}
static PyMethodDef myMethods[] = {
{"fib", fib, METH_VARARGS, "Calculates the Fibronacci numbers"},
{"version", (PyCFunction)version, METH_NOARGS, "Returns the version"},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"myModule",
"Fibronacci Module",
-1,
myMethods
};
PyMODINIT_FUNC PyInit_myModule(void){
return PyModule_Create(&myModule);
}
I made another file, setup.py, that has the following contents.
from distutils.core import setup, Extension
module = Extension("MyModule", sources = ["myModule.c"])
setup(name="PackageName",
version="1.0",
description="This is a package for myModule",
ext_modules = [module])
I ran
python3 setup.py install
and got
running install
running build
running build_ext
running install_lib
copying build/lib.linux-x86_64-3.7/MyModule.cpython-37m-x86_64-linux-gnu.so -> /home/peter/anaconda3/lib/python3.7/site-packages
running install_egg_info
Writing /home/peter/anaconda3/lib/python3.7/site-packages/PackageName-1.0-py3.7.egg-info
I then copied MyModule.cpython-37m-x86_64-linux-gnu.so and myModule.o into /home/peter/pythonCExtensions.
I then opened Spyder and created a file, CInterface.py, that contains only
import myModule
However, when I run this file (F5) I get
Traceback (most recent call last):
File "<ipython-input-1-c29fad851da0>", line 1, in <module>
runfile('/home/peter/Simple3dShapes/CInterface.py', wdir='/home/peter/Simple3dShapes')
File "/home/peter/anaconda3/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 827, in runfile
execfile(filename, namespace)
File "/home/peter/anaconda3/lib/python3.7/site-packages/spyder_kernels/customize/spydercustomize.py", line 110, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "/home/peter/Simple3dShapes/CInterface.py", line 19, in <module>
import myModule
ModuleNotFoundError: No module named 'myModule'
sudo yum install tree
resulted in
Install 1 Package
Total download size: 46 k
Installed size: 87 k
Is this ok [y/d/N]: y
Downloading packages:
tree-1.6.0-10.el7.x86_64.rpm | 46 kB 00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : tree-1.6.0-10.el7.x86_64 1/1
Verifying : tree-1.6.0-10.el7.x86_64 1/1
Installed:
tree.x86_64 0:1.6.0-10.el7
Complete!
Listing [Python 3.Docs]: Building C and C++ Extensions.
At its core, this is a typo (upper vs. lower case), combined with the fact that on Nix, file names are case sensitive (most likely, it couldn't be reproduced on Win).
So, your module is called myModule (function PyInit_myModule), but it resides in a file called MyModule.cpython-37m-x86_64-linux-gnu.so, which is not OK because the 2 names must match. Correct that by specifying the proper extension name in setup.py:
module = Extension("myModule", sources = ["myModule.c"])
As a side remark, don't name the module myModule (in general don't name stuff myStuff - personally, I find it ugly :) ). You could use e.g. fibonacci_module as a name.

Boost python shared library issue in specific case

I am trying to extend my c++ library which is created using qtcreator to python with boost::python. I create a setup.py like following:
from distutils.core import setup
from distutils.extension import Extension
module1 = Extension('FOO',
include_dirs = ['/usr/include/python3.4', '/home/user/cppProjects/FOOLib','/usr/include', '/usr/local/lib/python3.4/dit-packages'],
libraries = ['python3.4', 'boost_python-py34', 'boost_thread', 'boost_system', 'FOOLib'],
library_dirs = ['/usr/lib/x86_64-linux-gnu/', '/usr/lib/python3.4/config-3.4m-x86_64-linux-gnu/','/home/skywalker/cppProjects/build-FOO-Desktop-Debug/'],
sources = ['pythonprovider.cpp'],
extra_compile_args=['-std=c++11'])
setup(name="PackageName",
ext_modules=[module1])
and Bar.h
class Bar
{
public:
Bar(boost::python::list args)
{
...
}
static void SetN(int n)
{
Bar::N = n;
}
static int N;
};
and Bar.cpp
int Bar::N;
pythonprovider.cpp is
BOOST_PYTHON_MODULE(FOO)
{
class_<Bar>("Bar", init<list>());
}
Compiling the library and using in c++ app is working fine.
I am typing the following code in terminal and installation of python module is working fine.
sudo python3 setup.py install
Including the package in python like
from FOO import *
working fine. But when i modify the pythonprovider.cpp with static method
BOOST_PYTHON_MODULE(FOO)
{
class_<Bar>("Bar", init<list>())
.def("SetN", &Bar::SetN)
.staticmethod("SetN");
}
compiling and installation working fine but importing the module assert an error
ImportError: libFOO.so.1: cannot open shared object file: No such file or directory
This happen to me before. When i move to body of constructor from cpp file to header file problem is solved but in this case it is not solve my problem.

Python dll Extension Import

I created extensions for my Python and created a abcPython.dll. How can I import this dll into my Python scripts?
I get an error message when I try to import it usin the following command
>>>import abcPython
>>>Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named abcPython
>>>
I manually created a system environment variable named PYTHONPATH which stores the path to the abcPython.dll, but still the error remains.
How can I fix this?
Follow Building C and C++ Extensions on Windows carefully - in sub-section 7, it says:
The output file should be called spam.pyd (in Release mode) or spam_d.pyd (in Debug mode). The extension .pyd was chosen to avoid confusion with a system library spam.dll to which your module could be a Python interface
...
Changed in version 2.5: Previously, file names like spam.dll (in release mode) or spam_d.dll (in debug mode) were also recognized.
Try the renaming your DLL to use a .pyd extension instead of .dll.
(thanks, Peter Hansen)
The reference points to a C example, which explicitly includes an INIT function,
PyMODINIT_FUNC initexample(void). The resulting DLL should be renamed example.pyd :
#include "Python.h"
static PyObject *
ex_foo(PyObject *self, PyObject *args)
{
printf("Hello, world\n");
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef example_methods[] = {
{"foo", ex_foo, METH_VARARGS, "foo() doc string"},
{NULL, NULL}
};
PyMODINIT_FUNC
initexample(void)
{
Py_InitModule("example", example_methods);
}
Aarrgghh! Yet another 2.X/3.X gotcha. RTFErrorMessage:
ImportError: dynamic module does not define init function (PyInit_abcPython)
Note the prefix: it's not init, it's PyInit_
See the 3.1 docs ... "The initialization function must be named PyInit_name(), where name is the name of the module"
Simple renaming of .dll to .pyd did not help. I was using SWIG to create the extension module. I created a .pyd instead of creating a .dll module and that solved the issue.
As an example: Imagine you have compiled OpenCV and have several *.dll and the cv2.pyd file.
You need to copy those files to 'DLLs' folder within the python directory.
Then import the module to check wether it is ok.

Categories