0

I wrote a python library with two parts:

  1. A Python C extension
  2. A Python wrapper for the Python C extension

I would like to be able to package it in such a way that the Python wrapper is the top level module foo and the Python C extension is a submodule located at foo._foo. However I have so far only been able to create two top level modules, foo and _foo.

What do I need to do in setup.py and in the init_foo C function in order to accomplish this?

(My question is subtlety different from this)


Current directory structure:

foo/
    foo/
        __init__.py
    foo.c
    setup.py
    tests.py

setup.py looks something like:

from distutils.core import setup, Extension

module = Extension('_foo',
                   sources=['foo.c'])

setup(name='foo', packages=['foo'], ext_modules=[module])

foo.c looks something like:

PyMODINIT_FUNC init_foo(void) {
    PyObject *m;
    m = Py_InitModule("_foo", FooMethods);
    // ..
}
int main(int argc, char *argv[]) {
    Py_SetProgramName(argv[0])
    Py_Initialize();
    init_pychbase();
}

foo/__init__.py looks something like:

from _foo import _Foo, _Bar, _Baz

class Foo(object):
    def __init__(self):
        self._foo = _Foo()
Community
  • 1
  • 1
Matthew Moisen
  • 16,701
  • 27
  • 128
  • 231
  • @MatthewMoisen You said "(My question is subtlety different from [this](http://stackoverflow.com/questions/12097755/how-to-build-a-python-c-extension-so-i-can-import-it-from-a-module))" could you explain why? – MSeifert Feb 06 '17 at 03:43
  • @MSeifert after taking another go at it, I now realize it wasn't different enough to warrant a new question. (The difference is that I want my c extension one level deep, whereas the OP wanted his two levels deep). My issue was that my `tests.py` file was located in the same directory as the foo module so the imports were off when I ran it. Creating a `tests/tests.py` setup solved this. – Matthew Moisen Feb 06 '17 at 05:38

1 Answers1

2

As mentioned in the linked question, the solution is simply to change _foo to foo._foo:

from distutils.core import setup, Extension

module = Extension('foo._foo',
                   sources=['foo.c'])

setup(name='foo', packages=['foo'], ext_modules=[module])

My issue was that I was running my tests.py from the same directory as the foo module was located in.

I fixed this by bringing it into its own directory:

/foo
    /foo
        __init__.py
    foo.c
    setup.py
    /tests
         test.py
Matthew Moisen
  • 16,701
  • 27
  • 128
  • 231