Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Sphinx with a distutils-built C extension

I have written a Python module including a submodule written in C: the module itself is called foo and the C part is foo._bar. The structure looks like:

src/ 
  foo/__init__.py   <- contains the public stuff 
  foo/_bar/bar.c    <- the C extension
doc/                <- Sphinx configuration
  conf.py
  ...

foo/__init__.py imports _bar to augment it, and the useful stuff is exposed in the foo module. This works fine when it's built, but obviously won't work in uncompiled form, since _bar doesn't exist until it's built.

I'd like to use Sphinx to document the project, and use the autodoc extension on the foo module. This means I need to build the project before I can build the documentation.

Since I build with distutils, the built module ends up in some variably named dir build/lib.linux-ARCH-PYVERSION — which means I can't just hard-code the directory into a Sphinx' conf.py.

So how do I configure my distutils setup.py script to run the Sphinx builder over the built module?

For completeness, here's the call to setup (the 'fake' things are custom builders that subclass build and build_ext):

setup(cmdclass = {
        'fake': fake,
        'build_ext_fake' : build_ext_fake
      },
      package_dir = {'': 'src'},
      packages = ['foo'],
      name = 'foo',
      version = '0.1',
      description = desc,
      ext_modules = [module_real])
like image 771
detly Avatar asked Jan 14 '11 03:01

detly


2 Answers

Since distutils has a way of figuring out the variable build path, why not just use it?

import distutils.command.build
from distutils.dist import Distribution

b = distutils.command.build.build(Distribution())
b.initialize_options()
b.finalize_options()

print b.build_temp

# If you're building a library, you might need:
print b.build_lib

# Other values of interest are:
b.build_purelib
b.build_platlib
b.build_scripts
b.build_base

Even thought the distutils docs are sparse, here you'll find one-liners about what kinds of build are there.

like image 126
TryPyPy Avatar answered Oct 21 '22 23:10

TryPyPy


There are simpler ways to get the build dir name:

>>> from distutils.util import get_platform
>>> get_platform()
'linux-x86_64'

I’ll let you finish the string concatenation :)

Another way to solve your problem is to create a setup.cfg file alongside your setup.py with this content:

[build_ext]
inplace = 1

This will build your extension modules in its parent package directory. Sphinx should see it.

like image 2
merwok Avatar answered Oct 21 '22 22:10

merwok