Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to deal with "_d" suffix for C extensions when using debug build?

I'm trying to debug my C extension for Python 2.7. I use python2.7 debug build. I build my project with setuptools and my setup.py has such lines:

ext_modules=[Extension("my.extension",
                       ["my/_extension.c"])]

When I invoke python setup.py install for some reason extension compiles to a file with _d suffix, and after that, in Python, I can't do import my.extension, I can only do import my.extension_d. And what I get is:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "build/bdist.linux-x86_64/egg/my/extension_d.py", line 7, in <module>
  File "build/bdist.linux-x86_64/egg/my/extension_d.py", line 6, in __bootstrap__
ImportError: dynamic module does not define init function (initextension_d)

Of course my extension does not have initextension_d, it only has initextension function.

This is very incovenient, because I have to change some code and add this _d suffix to imports and other stuff.

Is it possible to turn off prepending of this suffix? Or how to deal with that problem in other way? Maybe there are some "official" ways?

UPDATE #0

I use Ubuntu Linux.

like image 539
Gill Bates Avatar asked Apr 10 '15 05:04

Gill Bates


3 Answers

Just disable debug mode when build C Extension. Or, if you do like to keep debug info, temporary disable _DEBUG macro:

#ifdef _DEBUG
# ifndef BOOST_DEBUG_PYTHON
#  ifdef _MSC_VER  
    // VC8.0 will complain if system headers are #included both with
    // and without _DEBUG defined, so we have to #include all the
    // system headers used by pyconfig.h right here.
#   include <stddef.h>
#   include <stdarg.h>
#   include <stdio.h>
#   include <stdlib.h>
#   include <assert.h>
#   include <errno.h>
#   include <ctype.h>
#   include <wchar.h>
#   include <basetsd.h>
#   include <io.h>
#   include <limits.h>
#   include <float.h>
#   include <string.h>
#   include <math.h>
#   include <time.h>
#  endif
#  undef _DEBUG // Don't let Python force the debug library just because we're debugging.
#  define DEBUG_WRAP_PYTHON_H
# endif
#endif

#include <Python.h>

#ifdef DEBUG_WRAP_PYTHON_H
# define _DEBUG
#endif

For full code sample you may take a look on full version of how boost.python includes python.h.

like image 101
Andrew Svetlov Avatar answered Oct 13 '22 02:10

Andrew Svetlov


To solve this problem, you can define in your C module function

void initextension_d()
{ initextension(); }
like image 25
kvorobiev Avatar answered Oct 13 '22 02:10

kvorobiev


A comment from the distutils source file of build_ext.py:

# extensions in debug_mode are named 'module_d.pyd' under windows

It's the same for C Extensions, so there shouldn't be any problem. But since there's one, it's also possible to remove the _d suffix:

import os.path
from setuptools.command.build_ext import build_ext as _build_ext

class build_ext(_build_ext):
    def get_ext_filename(self, ext_name):
        fn = _build_ext.get_ext_filename(self, ext_name)
        fn = os.path.splitext(fn)
        if fn[0].endswith('_d'):
            fn[0] = fn[0][:-2]
        return fn[0] + fn[1]

Or just disable debug for a while:

from setuptools.command.build_ext import build_ext as _build_ext

class build_ext(_build_ext):
    def get_ext_filename(self, ext_name):
        debug, self.debug = self.debug, False
        fn = _build_ext.get_ext_filename(self, ext_name)
        self.debug = debug
        return fn

Don't forget to set the cmdclass within setup:

setup(
    ...
    cmdclass={'build_ext': build_ext},
    ...
)

I'm not using Windows myself, so it's just a wild guess, but maybe you're mixing debug and release parts of Python.

like image 33
tynn Avatar answered Oct 13 '22 02:10

tynn