Search code examples
pythonpython-3.xpython-importcythonpython-module

Module not found error when importing a Cython .pyd file


I know this might seem like a duplicated question, but I really could not find what I'm doing wrong... I wrote a .pyx file in order to compile it into a .pyd with cython. Long story short, it compiles my file just fine and creates a .pyd file. However, when I try to import that .pyd file I get an error saying No module named: "name_of_module". Note that this is my first time trying cython...

I am using venv with python3.9 on windows 10. I have cython installed along with minGW. To compile it into the .pyd file, I imply type in the command prompt in the same directory as the .pyx file:

python setup.py build_ext --inplace

Here is my setup.py file to cythonize my .pyx file:

from setuptools import setup, Extension
from Cython.Build import cythonize

extensions = [Extension('negamax_cy', ['negamax_cy.pyx'])]
setup(ext_modules=cythonize(extensions, language_level=3))

This is my .pyx file:

from connect4.constants import COLS, ROWS
from .position import Position

cdef int COLUMN_ORDER[7]
cdef int x
for x in range(COLS):
    COLUMN_ORDER.append(COLS // 2 + (1 - 2 * (x % 2)) * (1 + x) // 2)


cpdef int negamax(pos, int depth, int alpha, int beta):
    if pos.can_win():   # Check if current player can win this move
        return 1000 - pos.moves*2

    cdef long next_move = pos.possible_non_loosing_moves()
    if next_move == 0:              # Check for moves which are not losing moves
        return -1000 + pos.moves    # If we have 2 or more forcing moves we lose

    if depth == 0:  # Check if we have reached max depth
        return 0

    if pos.moves == ROWS * COLS:  # Check for a draw game
        return 0

    cdef int col = 0
    for col in COLUMN_ORDER[col]:
        if next_move & Position.column_mask(col):
            pos_cp = Position(position=pos)
            pos_cp.play_col(col)
            score = -negamax(pos_cp, depth - 1, -beta, -alpha)

            if score >= beta:
                return score
            alpha = max(alpha, score)

    return alpha

My project structure is as follow (I am trying to do a connect4 game with an A.I. in pygame):

connect4
   /venv
   /ai
     __init__.py
     setup.py
     file_where_pyd_is_imported.py
     negamax_cy.pyx
     negamax_cy.pyd
     negamax_cy.c
   /connect4
     __init__.py
     other_files.py
__init__.py
main.py

Note that main.py imports file_where_pyd_is_imported.py

When I import I simply type:

import negamax_cy

this is the error I get:

Traceback (most recent call last):
  File "D:\Users\dalla\Documents\Coding Projects\python\games\connect4\main.py", line 5, in <module>
    from ai.negamax import mp_best_move, best_move, print_avg
  File "D:\Users\dalla\Documents\Coding Projects\python\games\connect4\ai\negamax.py", line 7, in <module>
    import negamax_cy
ModuleNotFoundError: No module named 'negamax_cy'

As I said I don't know what is wrong. Maybe it has to do with my project structure or something, or my setup.py file, but I am unsure... If anyone has an idea let me know.


Solution

  • Well turns in python3 I have to import it like this:

    from . import negamax_cy