3

I am creating a cython package where several modules share extension types with each other. However I have problems getting the cimports right.

I have created a simple example project to show case my problem. As you can see: All cython files are within a package call myPackage.

myProject │ ├── main.py │ ├── myPackage │   ├── animal.pxd │   ├── animal.pyx │ ├── zoo.pxd │ ├── zoo.pyx │ ├── setup.py 

Can you explain to me, how to use cimport such that zoo.pyx has knowledge about the extension types in animal.pyx ?

This is the animal.pyx file ...

cdef class Animal: def __init__(self, str name, double weight): self.name = name self.weight = weight 

This is the animal.pxd file ...

cdef class Animal: cdef: public str name public double weight 

This is the zoo.pyx file ...

from myPackage.animal cimport Animal cdef class Zoo: def __init__(self): self.animals_cage = [] print('ready!') cpdef void add_animal(self, Animal animal): self.animals_cage.append(animal) 

This is the zoo.pxd file ...

from myPackage.animal cimport Animal cdef class Zoo: cdef list animals_cage cpdef void add_animal(self, Animal animal) 

The setup is done by ...

from distutils.core import setup, Extension from Cython.Build import cythonize ext_modules = [Extension(name="animal", sources=["animal.pyx"]), Extension(name="zoo", sources=["zoo.pyx"])] setup(ext_modules=cythonize(ext_modules)) 

The main.py is as basic as it can get ...

from myPackage.animal import Animal from myPackage.zoo import Zoo if __name__ == '__main__': a = Animal("bob", 4) z = Zoo() 

Trials and Results:
1st Trail:

Run setup.py inside myPackage. Run main.

compiling failed 'Animal' is not a type identifier 

(my guess) cython could not find myPackage.animal.pyx

2nd Trial:
Add include_path=['myPackage'] to cythonize call. Run setup.py inside myPackage. Run main.py

compiling works but main.py produces: AttributeError: 'zoo.Zoo' object has no attribute 'cage' 

3rd Trial
make all cimports relative ( aka. from animal cimport Animal) and remove include_dirs from setup.py

compiling works and main.py works 

However, if you switch the imports in main.py. Making Zoo the 1st import:

from myPackage.zoo import Zoo from myPackage.animal import Animal if __name__ == '__main__': a = Animal("bob", 4) z = Zoo() ModuleNotFoundError: No module named 'animal' 

1 Answer 1

2

To get main.py working, I had to:

  • move setup.py from myPackage to myProject and change Paths accordingly
  • not use include_dir or include_path
  • cimport: from myPackage.animal cimport Animal

Thou I have no Idea why it does not work when setup.py is inside myPackage!

myProject │ ├── main.py ├── setup.py │ ├── myPackage │ ├── animal.pxd │ ├── animal.pyx │ ├── zoo.pxd │ ├── zoo.pyx 

and the setup.py

from setuptools import setup, find_packages, Extension from Cython.Build import cythonize extensions = [ Extension("myPackage.animal", ["myPackage/animal.pyx"]), Extension("myPackage.zoo", ["myPackage/zoo.pyx"])] compiler_directives = {"language_level": 3, "embedsignature": True} extensions = cythonize(extensions, compiler_directives=compiler_directives) 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.