Hello Cython team,
I'm trying to compile a project with a Cython extension using a pyproject.toml file within a Conda virtual environment. I want to build the package in development mode using "pip install --editable ."
The compilation process seems to run smoothly without any errors or warnings, resulting in the generation of both a .c file and a .so file within the package's source folder. I can see the package listed inside the virtual environment by using "conda list."
However, when I attempt to call a function from this package, I encounter an "AttributeError: module <package name> has no attribute <module name>" error.
The module can be imported. The intellisense of my editor shows all modules and functions but they can not be executed.
Is there something I need to modify in my "pyproject.toml" or my "setup.py" file to resolve this issue?
# =============================================================================
# System
# =============================================================================
System: Linux Mint 21.2 Victoria
Python: 3.10.13
Cython: 3.0.0
# =============================================================================
# package tree BEFORE compilation
# =============================================================================
cythontest
├── pyproject.toml
├── README.md
├── setup.py
└── src
└── cythontest
├── cython_module.pyx
├── __init__.py
└── module1.py
# =============================================================================
# package tree AFTER compilation
# =============================================================================
cythontest
├── pyproject.toml
├── README.md
├── setup.py
└── src
├── cythontest
│ ├── cython_module.c
│ ├──
cython_module.cpython-310-x86_64-linux-gnu.so │ ├── cython_module.pyx
│ ├── __init__.py
│ └── module1.py
└── cythontest.egg-info
├── dependency_links.txt
├── PKG-INFO
├── SOURCES.txt
└── top_level.txt
# =============================================================================
# conda list AFTER compilation
# =============================================================================
[...]
cythontest 0.1.0 pypi_0 pypi
[...]
# =============================================================================
# Error
# =============================================================================
import cythontest
cythontest.cython_module.primes(10)
# AttributeError: module 'cythontest' has no attribute 'cython_module'
# =============================================================================
# pyproject.toml
# =============================================================================
[build-system]
requires = ["setuptools", "Cython"]
build-backend = "setuptools.build_meta"
[project]
name = "cythontest"
version = "0.1.0"
description = "My Python package with Cython extension"
authors = [
{name = "My Name", email = "
m...@email.com"},
]
license = {text = "MIT License"}
readme = "README.md"
requires-python = ">=3.10.0"
# =============================================================================
# setup.py
# =============================================================================
from setuptools import setup, Extension
from Cython.Build import cythonize
# import numpy
# Modules to be compiled and include_dirs when necessary
extensions = [
Extension(
"cythontest.cython_module",
["src/cythontest/cython_module.pyx"], #include_dirs=[numpy.get_include()],
),
]
# This is the function that is executed
setup(name='cythontest', # Required
ext_modules = cythonize(extensions, compiler_directives={"language_level": 3, "profile": False}),
)
# =============================================================================
# cython_module.pyx
# =============================================================================
def primes(int nb_primes):
cdef int n, i, len_p
cdef int[1000] p
if nb_primes > 1000:
nb_primes = 1000
len_p = 0 # The current number of elements in p.
n = 2
while len_p < nb_primes:
# Is n prime?
for i in p[:len_p]:
if n % i == 0:
break
# If no break occurred in the loop, we have a prime.
else:
p[len_p] = n
len_p += 1
n += 1
result_as_list = [prime for prime in p[:len_p]]
return result_as_list