Convert .py file into .pyd file - python-3.x

Well after a lot of search unable to find a proper solution, I have my python file 'Main.py'.I want to have its .pyd file i.e Main.pyd. I have tried the way of using Cpython i.e first I have converted 'Main.py' file into 'Main.c'but then unable to convert the 'Main.c' into 'Main.pyd' and its quite tough way.Can I have a simple way to convert 'Main.py' into 'Main.pyd'?

I think you just need to create a library from your script. Create a new setup.py besides your sample_code.py:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [
Extension("sample_code", ["sample_code.py"]),
]
setup(
name = 'My Program',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
Then use python setup.py build_ext --inplace to generate your library.
You can find more information here.

Related

Importing a .pyd file (created with Cython) inside a .py script

I've created a simple .pyd file from my helloWorld.py script using the sample code from here (https://stackoverflow.com/a/36946412/8729576), and although it does generate the .pyd file (along with a build folder, helloWorld.c file) - it throws an error [ImportError: dynamic module does not define module export function (PyInit_helloWorld)] when I attempt to import the function defined inside the original helloWorld.py called printHW using the normal import syntax of:
from helloWorld import printHW
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define module export function (PyInit_helloWorld)
helloWorld.py
import time
def printHW():
print("Hello World - today's date is %s"%time.strftime('%Y-%m-%d',time.localtime()))
if '__name__' == '__main__':
printHW()
setup.py
try:
from setuptools import setup
from setuptools import Extension
except ImportError:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension("helloWorld",["helloWorld.py"]) ]
for e in ext_modules:
e.cython_directives = {'language_level' : '3'}
setup(
name= 'helloWorld',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules)
and then in the command prompt enter:
python setup.py build_ext --inplace
I've never worked with Cython before so really not sure what I'm doing wrong here and most SO answers are specific and not generic to what I'm trying to understand (with this basic example).
For anyone else that comes across this error - it has to do with the name of your output file. Playing with the name of the output pyd file and the name provided in the setup.py <[Extension("ThisShallBeYourModuleImportName",["helloWorld.py"]) ]> line I was able to fix my issue (thanks to #DavidW). Observe that whatever name you provide to your .py script in the Extensions list is what you will have to import it as, it is case sensitive. Furthermore, to import the compiled .pyd file 'ThisShallBeYourModuleImportName.cp36-win_amd64.pyd' in your python script, all you need is to say import ThisShallBeYourModuleImportName in your python script and it shall import the module, additionally you can remove the .cp36-win_amd64 and it will still be imported successfully. Try building the above setup.py code with the following changes to observe what I've stated:
try:
from setuptools import setup
from setuptools import Extension
except ImportError:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension("jAckSparroW",["helloWorld.py"]) ]
for e in ext_modules:
e.cython_directives = {'language_level' : '3'}
setup(
name= 'WhatEver',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules)
Now open terminal and try
import jacksparrow
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'jacksparrow'
import jAckSparroW
>>>

Cannot import cython module which is generated using setup.py

I have converted a .pyx file to .pyd using cpython setup.py method but always get the following message :
ValueError: no signature found for builtin <built-in function hello>
The file I am converting test.pyx :
from pyxll import xl_func
#xl_func
def hello():
return "HELLO WORLD"
setup.py script :
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [
Extension("example.test", sources=["example/test.pyx"])
]
setup(
name='Example',
cmdclass={'build_ext': build_ext},
ext_modules=ext_modules
)
When I try to import this test module I get the specified message.
Although when I tried to convert test.pyx without import and decorator it worked so is there any specific configuration change required in setup to include pyxll.
Enviorment : Python 3.8.5 32 bit
As #cvanelteren pointed out file type was the problem I compiled a py file and it fixed the issue of imports

Compiling multiple files to exe

I got multiple files to compile to a standalone exe using cython.
compile.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [
Extension("TheMainFile", ["TheMainFile.py"]),
Extension("HelperClass", ["HelperClass.py"]),
Extension("HelperClass2", ["HelperClass2.py"]),
]
setup(
name = 'Main',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
The main file that should be run by the exe is TheMainFile
running the following command
python .\compiler.py build_ext --inplace
creates 3 .c files, in the build dir however is no .exe, just .lib,.exp and .obj files.
Manually adding these files to a VS Projects to build, results in the following error
"Python.h": No such file or directory
Adding the following files to the project from C:\Python\include lastly results in "structmember.h": No such file or directory
My question is:
How do I compile these files to a binary where TheMainFile is executed.

Import error undefined symbol (C++ module in python) ZTINSt8ios_base7failureB5cxx11E

I know there are lots of similar questions on the website but I couldn't find an answer to my problem.
I'm wrapping C++ classes with Cython in order to use them with Python3. After building the external module with a setup.py, when I run the python program I got the following error:
from "name of.pyx file" import "name of the class to import"
Import error: /home/.../filename.so: undefined symbol: _ZTINSt8ios_base7failureB5cxx11E.
I'm on Ubuntu 16.04, I build the extensions from the terminal with the command line python3 setup.py build_ext --inplace, and then run the .py from the terminal or from Spyder in Anaconda (I got the error in both cases.)
From what I read the error might come from the cython compilation because i'm not linking some libraries. Is this true? If it is, could someone explain me how to do it?
I let you here my setup.py, in comments all the different setups I tried.
setup.py
from distutils.core import setup, Extension
from Cython.Build import cythonize
import numpy
#setup(ext_modules = cythonize(
#"pycoralv1.pyx", # our Cython source
#sources=["coralv1cpp.cpp"], # additional source file(s)
#language="c++", # generate C++ code
#))
#setup(ext_modules = cythonize(Extension(
# "pyCoralv1", # the extension name
# sources=["pyCoralv1.pyx", "Coralv1cpp.cpp"], # the Cython source and
# additional C++ source files
# language="c++", # generate and compile C++ code
# )))
#setup(
# name = "testcoral",
# ext_modules = cythonize('*.pyx'),
#)
ext_modules = [
Extension(
"pyCoralv1",
sources=["pyCoralv1.pyx", "Coralv1cpp.cpp"],
extra_compile_args=['-fopenmp',"-fPIC"],
extra_link_args=['-fopenmp',"-I", "/usr/include/glib-2.0", "-l", "glib-2.0", "-I", "/usr/lib/x86_64-linux-gnu/glib-2.0/include"],
language="c++",
)
]
for e in ext_modules:
e.pyrex_directives = {"boundscheck": False}
setup(
name='Coral library',
ext_modules=cythonize(ext_modules),
include_dirs = [numpy.get_include()]
)
The problem was solved after installing libgcc in anaconda: conda install libgcc, there was a missing library.

cython compiles but no pyd files are generated

I tried to run a python code, say myfile.py (also tried to rename it as myfile.pyx) as follows:
import pyximport
pyximport.install(setup_args={"script_args":["--compiler=mingw32"]},
reload_support=True)
import myfile
myfile.mycode()
I am using PyCharm. The code seems to have run fine without any error and even gave me correct results on the Python Console within PyCharm.
However no pyd (or pxd) files were generated. How can I know if my code (myfile.mycode()) ran via Cython or via regular Python?
I am using Python 3.4, Cython 0.21.2.
Thanks
pyximport generates a temporary pyd file that is not in the working directory. You probably want to build a setup.py that looks something like:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension('myfile',
sources=['myfile.pyx'],
language='c++',
)]
setup(
name = 'myfile',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
which you can compile using:
python setup.py build_ext -i clean

Resources