0

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).

Salvatore
  • 93
  • 1
  • 6
  • Are you building it with Python 2 and running it with Python 3? I.e. is it a duplicate of https://stackoverflow.com/questions/29657319/dynamic-module-does-not-define-init-function-pyinit-fuzzy (with a slightly different method of building)? – DavidW Jan 04 '23 at 07:37
  • Or https://stackoverflow.com/a/36727516/4657412 – DavidW Jan 04 '23 at 07:40
  • @DavidW - no, the code is written in python 3 and Im building in python3 as well! – Salvatore Jan 04 '23 at 07:40
  • 1
    1) Are you renaming any files manually and not mentioning it in the question? 2) What is the *exact* name of the .pyd file generated? – DavidW Jan 04 '23 at 08:38
  • I did rename the output file 'helloWorld.cp36_amd64.pyd' to helloworld1.pyd cuz importing it as is causes a syntax error – Salvatore Jan 04 '23 at 21:26
  • OHH, I think you're right about the naming, I just recreated the file - renamed it helloWorld (exact same name as in the setup.py file [case sensitive]), placed the .pyd into a new empty dir and cmd inside it and voila, I can import it without issues!! @DavidW - Thank You! Just to confirm, the name of the output file must be the same case as well? Another issue that I've run into is when I run the above setup.py with my actual code (not this sample example of hello world), it just gets stuck at 'cythonizing myCode.py to myCode.c' -- I left it overnight and its still stuck! Any idea? – Salvatore Jan 04 '23 at 21:32
  • `helloWorld.cp36_amd64.pyd` is still imported with `import helloWorld`. The `cp36_amd64` is to tell Python that it's only compatible with 64bit Python 3.6, but it isn't a detail that you need to care about. Don't rename it. The name of the file needs to match the name of a function in the file. – DavidW Jan 04 '23 at 22:16
  • 1
    The cythonizing step should take <1s. Definitely don't leave it overnight! I don't know what's going wrong but it should be quick. – DavidW Jan 04 '23 at 22:18
  • @DavidW is there like a verbose version of cython that I can run to help determine why its stuck/taking soo long to cythonize? – Salvatore Jan 04 '23 at 22:36
  • So for the file thats taking forever to cythonize - I just tested removing a rather long list comprehension with lots of if else conditions and it cythonized right away! So now the question is why is Cython not able to handle list comp, even changed that to a for loop but with lots and lots of if else conditions – Salvatore Jan 04 '23 at 22:42
  • I don't know. I've never heard of a specific problem with list comprehensions taking a long time to compile. The best thing would be to report it at github.com/cython/cython/issues and there's a decent chance it can be fixed. – DavidW Jan 04 '23 at 22:44
  • @DavidW - thank you very much!! I shall create a minimum working example and report the issue at github! – Salvatore Jan 04 '23 at 22:48

1 Answers1

0

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
>>>
Salvatore
  • 93
  • 1
  • 6