ModuleNotFound when trying to install Python Extension Module (Cython) inside the same package specified in setup.py

Viewed 193

I have a Cython extension module for a Python project I want to install to the same namespace as the project on installation. When I try to specify in the extension to install it inside the package itself, it can't be found and imported. If I specify the extension goes in the root of the Python namespace, it works fine, but it's not in the module namespace I want. How do I get the Extension Module to be importable from the same namespace as the package itself?

I've made a simple test case for this question.

Folder Structure:

mypkg
├── foo
│   ├── __init__.py
│   └── barCy.pyx
└── setup.py

The .barCy.pyx file:

cpdef long bar():
    return 0

The setup.py code:

import distutils.extension
from Cython.Build import cythonize

from setuptools import setup, find_packages

extensions = [distutils.extension.Extension("foo.bar",
                                            ['foo/barCy.pyx'])]
setup(
        name='foo',
        packages=find_packages(),
        ext_modules=cythonize(extensions),
        )

The __init.py__ is empty.

I want to be able to do:

>>> import foo.bar as bar
>>> bar.bar()
0

Instead, I get

>>> import foo.bar as bar
ModuleNotFoundError: No module named 'foo.bar'

If I were to change the Extension("foo.bar",... to Extension("bar",..., then I can do import bar like it were a top level package. Although that is the expected behavior, it's not what I want as I only want this extension module to be accessible through the foo namespace.

1 Answers

My Python interpreter was being run from the same folder as the setup.py script, so doing import foo was importing the local package, rather than the one installed in Python interpreter's site-packages directory. Because they have the same folder structure, the local directory was chosen as the superseding imported package.

Do testing/running from a different folder than the source.

Related