Search code examples
cythonsubdirectoryattributeerror

Cython 0.23.4 AttributeError when .pyx and .pxd files in subdirectory


I upgraded my Cython to version 0.23.4 and my code now leads to an AttributeError when I put the .pyx and .pxd files in subdirectories of my working directory. The minimal example containing the error is as follows:

Main python file in working directory:

import pyximport;
import os,sys; 
pyximport.install()
sys.path.insert(0, os.getcwd()+'/pxd')
sys.path.insert(0, os.getcwd()+'/pyx')
from X import *

xObj = X(5)

pyx/X.pyx (i.e. in subdirectory pyx/):

cdef class X:
    def __init__(self,var):
        self.var = var

pxd/X.pxd (i.e. in subdirectory pxd/):

cdef class X:
    cdef public int var

Running Main.py gives the following error:

AttributeError: 'X.X' object has no attribute 'var'

Note, the code runs fine if I move the X.pyx and X.pxd files into my working directory. But this is very inconvenient due to a large number of files.

What can I do to get the code running, whilst having the X.pyx and X.pxd in the subdirectories?


Solution

  • Cython expects the .pyx and .pxd files to be in the same directory as each other, (which doesn't have to be your working directory). As it currently stands I think you're importing only "X.pyx", and it isn't realising that "X.pxd" is related to it.

    Therefore you could create a directory called "cython_files" (to keep your files out of your working directory), and in that directory you'd put both "X.pxd" and "X.pyx". You could then add "cython_files" to your path, and you wouldn't get any attribute errors.

    Better yet, you could add an "__init__.py" to your "cython_files" directory and then it's treated as a Python module and you can do from cython_files.X import X, and not have to add anything to your path.

    Edit for clarity: @romenic's answer identifies the same issue, but suggests a slightly different solution to it (which I suspect works) - this answer argues that OP really shouldn't organize their files in the way they do, rather than trying to work round it.