f.write(prefix_code)
f.write('set breakpoint pending on\n')
f.write("set print pretty on\n")
- f.write('python from Cython.Debugger import libcython\n')
+ f.write('python from Cython.Debugger import libcython, libpython\n')
if no_import:
# don't do this, this overrides file command in .gdbinit
import sys
import uuid
import shutil
+import warnings
import textwrap
import unittest
import tempfile
from distutils import sysconfig
from distutils import ccompiler
+import runtests
import Cython.Distutils.extension
from Cython.Debugger import Cygdb as cygdb
compiler = ccompiler.new_compiler()
compiler.compile(['cfuncs.c'], debug=True)
- ext = Cython.Distutils.extension.Extension(
- 'codefile',
- ['codefile.pyx'],
- pyrex_gdb=True,
- extra_objects=['cfuncs.o'])
-
- distutils.core.setup(
- script_args=['build_ext', '--inplace'],
- ext_modules=[ext],
- cmdclass=dict(build_ext=Cython.Distutils.build_ext)
+ opts = dict(
+ test_directory=self.tempdir,
+ module='codefile',
)
-
+
+ cython_compile_testcase = runtests.CythonCompileTestCase(
+ workdir=self.tempdir,
+ # we clean up everything (not only compiled files)
+ cleanup_workdir=False,
+ **opts
+ )
+
+ cython_compile_testcase.run_cython(
+ targetdir=self.tempdir,
+ incdir=None,
+ annotate=False,
+ extra_compile_options={
+ 'gdb_debug':True,
+ 'output_dir':self.tempdir,
+ },
+ **opts
+ )
+
+ cython_compile_testcase.run_distutils(
+ incdir=None,
+ workdir=self.tempdir,
+ extra_extension_args={'extra_objects':['cfuncs.o']},
+ **opts
+ )
+
+ # ext = Cython.Distutils.extension.Extension(
+ # 'codefile',
+ # ['codefile.pyx'],
+ # pyrex_gdb=True,
+ # extra_objects=['cfuncs.o'])
+ #
+ # distutils.core.setup(
+ # script_args=['build_ext', '--inplace'],
+ # ext_modules=[ext],
+ # cmdclass=dict(build_ext=Cython.Distutils.build_ext)
+ # )
+
def tearDown(self):
os.chdir(self.cwd)
shutil.rmtree(self.tempdir)
paths.append(os.path.dirname(os.path.dirname(
os.path.abspath(Cython.__file__))))
env = dict(os.environ, PYTHONPATH=os.pathsep.join(paths))
+
+ try:
+ p = subprocess.Popen(['gdb', '-v'], stdout=subprocess.PIPE)
+ have_gdb = True
+ except OSError:
+ # gdb was not installed
+ have_gdb = False
+ else:
+ gdb_version = p.stdout.read()
+ p.wait()
+ p.stdout.close()
+
+ if have_gdb:
+ # Based on Lib/test/test_gdb.py
+ regex = "^GNU gdb [^\d]*(\d+)\.(\d+)"
+ gdb_version_number = re.search(regex, gdb_version).groups()
- self.p = subprocess.Popen(
- args,
- stdout=open(os.devnull, 'w'),
- stderr=subprocess.PIPE,
- env=env)
+ if not have_gdb or map(int, gdb_version_number) < [7, 2]:
+ self.p = None
+ warnings.warn('Skipping gdb tests, need gdb >= 7.2')
+ else:
+ self.p = subprocess.Popen(
+ args,
+ stdout=open(os.devnull, 'w'),
+ stderr=subprocess.PIPE,
+ env=env)
def tearDown(self):
super(GdbDebuggerTestCase, self).tearDown()
- self.p.stderr.close()
- self.p.wait()
+ if self.p:
+ self.p.stderr.close()
+ self.p.wait()
os.remove(self.gdb_command_file)
class TestAll(GdbDebuggerTestCase):
def test_all(self):
+ if self.p is None:
+ return
+
out, err = self.p.communicate()
border = '*' * 30
start = '%s v INSIDE GDB v %s' % (border, border)
import textwrap
import tempfile
import traceback
+import itertools
from test import test_support
import gdb
self.break_and_run('os.path.join("foo", "bar")')
result = gdb.execute('cy bt', to_string=True)
+
+ _debug(libpython.execute, libpython._execute, gdb.execute)
+ _debug(gdb.execute('cy list', to_string=True))
+ _debug(repr(result))
+
assert re.search(r'\#\d+ *0x.* in spam\(\) at .*codefile\.pyx:22',
result), result
assert 'os.path.join("foo", "bar")' in result, result
self.assertEqual('14', self.eval_command('some_random_var'))
+_do_debug = os.environ.get('CYTHON_GDB_DEBUG')
+if _do_debug:
+ _debug_file = open('/dev/tty', 'w')
+
+def _debug(*messages):
+ if _do_debug:
+ messages = itertools.chain([sys._getframe(1).f_code.co_name],
+ messages)
+ _debug_file.write(' '.join(str(msg) for msg in messages) + '\n')
+
def _main():
try:
gdb.lookup_type('PyModuleObject')
import gdb
-# I think this is the only way to fix this bug :'(
-# http://sourceware.org/bugzilla/show_bug.cgi?id=12285
-reload(sys).setdefaultencoding('UTF-8')
+if sys.version_info[0] < 3:
+ # I think this is the only way to fix this bug :'(
+ # http://sourceware.org/bugzilla/show_bug.cgi?id=12285
+ out, err = sys.stdout, sys.stderr
+ reload(sys).setdefaultencoding('UTF-8')
+ sys.stdout = out
+ sys.stderr = err
# Look up the gdb.Type for some standard types:
_type_char_ptr = gdb.lookup_type('char').pointer() # char*
from Cython.Debugger import Cygdb as cygdb
if __name__ == '__main__':
- cygdb.main()
+ cygdb.main()
from Cython.Debugger import Cygdb as cygdb
if __name__ == '__main__':
- cygdb.main()
+ cygdb.main()
else:
return geterrors()
- def run_cython(self, test_directory, module, targetdir, incdir, annotate):
+ def run_cython(self, test_directory, module, targetdir, incdir, annotate,
+ extra_compile_options=None):
include_dirs = INCLUDE_DIRS[:]
if incdir:
include_dirs.append(incdir)
source = self.find_module_source_file(
os.path.join(test_directory, module + '.pyx'))
target = os.path.join(targetdir, self.build_target_filename(module))
+
+ if extra_compile_options is None:
+ extra_compile_options = {}
+
+ try:
+ CompilationOptions
+ except NameError:
+ from Cython.Compiler.Main import CompilationOptions
+ from Cython.Compiler.Main import compile as cython_compile
+ from Cython.Compiler.Main import default_options
+
options = CompilationOptions(
- pyrex_default_options,
+ default_options,
include_path = include_dirs,
output_file = target,
annotate = annotate,
language_level = self.language_level,
generate_pxi = False,
evaluate_tree_assertions = True,
+ **extra_compile_options
)
cython_compile(source, options=options,
full_module_name=module)
- def run_distutils(self, test_directory, module, workdir, incdir):
+ def run_distutils(self, test_directory, module, workdir, incdir,
+ extra_extension_args=None):
cwd = os.getcwd()
os.chdir(workdir)
try:
if match(module):
ext_include_dirs += get_additional_include_dirs()
self.copy_related_files(test_directory, workdir, module)
+
+ if extra_extension_args is None:
+ extra_extension_args = {}
+
extension = Extension(
module,
sources = self.find_source_files(workdir, module),
include_dirs = ext_include_dirs,
extra_compile_args = CFLAGS,
+ **extra_extension_args
)
if self.language == 'cpp':
extension.language = 'c++'