aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/cython/Cython/Debugger/Tests
diff options
context:
space:
mode:
authorAnton Samokhvalov <pg83@yandex.ru>2022-02-10 16:45:17 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:17 +0300
commitd3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch)
treedd4bd3ca0f36b817e96812825ffaf10d645803f2 /contrib/tools/cython/Cython/Debugger/Tests
parent72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff)
downloadydb-d3a398281c6fd1d3672036cb2d63f842d2cb28c5.tar.gz
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/tools/cython/Cython/Debugger/Tests')
-rw-r--r--contrib/tools/cython/Cython/Debugger/Tests/TestLibCython.py508
-rw-r--r--contrib/tools/cython/Cython/Debugger/Tests/__init__.py2
-rw-r--r--contrib/tools/cython/Cython/Debugger/Tests/cfuncs.c16
-rw-r--r--contrib/tools/cython/Cython/Debugger/Tests/codefile94
-rw-r--r--contrib/tools/cython/Cython/Debugger/Tests/test_libcython_in_gdb.py970
-rw-r--r--contrib/tools/cython/Cython/Debugger/Tests/test_libpython_in_gdb.py208
6 files changed, 899 insertions, 899 deletions
diff --git a/contrib/tools/cython/Cython/Debugger/Tests/TestLibCython.py b/contrib/tools/cython/Cython/Debugger/Tests/TestLibCython.py
index 6a769cc2fc..13560646ff 100644
--- a/contrib/tools/cython/Cython/Debugger/Tests/TestLibCython.py
+++ b/contrib/tools/cython/Cython/Debugger/Tests/TestLibCython.py
@@ -1,274 +1,274 @@
-
-import os
-import re
-import sys
-import shutil
-import warnings
-import textwrap
-import unittest
-import tempfile
-import subprocess
-#import distutils.core
-#from distutils import sysconfig
-from distutils import ccompiler
-
-import runtests
-import Cython.Distutils.extension
+
+import os
+import re
+import sys
+import shutil
+import warnings
+import textwrap
+import unittest
+import tempfile
+import subprocess
+#import distutils.core
+#from distutils import sysconfig
+from distutils import ccompiler
+
+import runtests
+import Cython.Distutils.extension
import Cython.Distutils.old_build_ext as build_ext
-from Cython.Debugger import Cygdb as cygdb
-
-root = os.path.dirname(os.path.abspath(__file__))
-codefile = os.path.join(root, 'codefile')
-cfuncs_file = os.path.join(root, 'cfuncs.c')
-
-with open(codefile) as f:
- source_to_lineno = dict((line.strip(), i + 1) for i, line in enumerate(f))
-
-
-have_gdb = None
-def test_gdb():
- global have_gdb
- if have_gdb is not None:
- return have_gdb
-
+from Cython.Debugger import Cygdb as cygdb
+
+root = os.path.dirname(os.path.abspath(__file__))
+codefile = os.path.join(root, 'codefile')
+cfuncs_file = os.path.join(root, 'cfuncs.c')
+
+with open(codefile) as f:
+ source_to_lineno = dict((line.strip(), i + 1) for i, line in enumerate(f))
+
+
+have_gdb = None
+def test_gdb():
+ global have_gdb
+ if have_gdb is not None:
+ return have_gdb
+
have_gdb = False
- try:
+ try:
p = subprocess.Popen(['gdb', '-nx', '--version'], stdout=subprocess.PIPE)
- except OSError:
+ except OSError:
# gdb not found
gdb_version = None
- else:
+ else:
stdout, _ = p.communicate()
- # Based on Lib/test/test_gdb.py
+ # Based on Lib/test/test_gdb.py
regex = r"GNU gdb [^\d]*(\d+)\.(\d+)"
gdb_version = re.match(regex, stdout.decode('ascii', 'ignore'))
-
+
if gdb_version:
gdb_version_number = list(map(int, gdb_version.groups()))
- if gdb_version_number >= [7, 2]:
+ if gdb_version_number >= [7, 2]:
have_gdb = True
with tempfile.NamedTemporaryFile(mode='w+') as python_version_script:
- python_version_script.write(
- 'python import sys; print("%s %s" % sys.version_info[:2])')
- python_version_script.flush()
- p = subprocess.Popen(['gdb', '-batch', '-x', python_version_script.name],
- stdout=subprocess.PIPE)
+ python_version_script.write(
+ 'python import sys; print("%s %s" % sys.version_info[:2])')
+ python_version_script.flush()
+ p = subprocess.Popen(['gdb', '-batch', '-x', python_version_script.name],
+ stdout=subprocess.PIPE)
stdout, _ = p.communicate()
- try:
+ try:
internal_python_version = list(map(int, stdout.decode('ascii', 'ignore').split()))
if internal_python_version < [2, 6]:
have_gdb = False
- except ValueError:
- have_gdb = False
-
+ except ValueError:
+ have_gdb = False
+
if not have_gdb:
warnings.warn('Skipping gdb tests, need gdb >= 7.2 with Python >= 2.6')
-
- return have_gdb
-
-
-class DebuggerTestCase(unittest.TestCase):
-
- def setUp(self):
- """
- Run gdb and have cygdb import the debug information from the code
- defined in TestParseTreeTransforms's setUp method
- """
- if not test_gdb():
- return
-
- self.tempdir = tempfile.mkdtemp()
- self.destfile = os.path.join(self.tempdir, 'codefile.pyx')
- self.debug_dest = os.path.join(self.tempdir,
- 'cython_debug',
- 'cython_debug_info_codefile')
- self.cfuncs_destfile = os.path.join(self.tempdir, 'cfuncs')
-
- self.cwd = os.getcwd()
- try:
- os.chdir(self.tempdir)
-
- shutil.copy(codefile, self.destfile)
- shutil.copy(cfuncs_file, self.cfuncs_destfile + '.c')
+
+ return have_gdb
+
+
+class DebuggerTestCase(unittest.TestCase):
+
+ def setUp(self):
+ """
+ Run gdb and have cygdb import the debug information from the code
+ defined in TestParseTreeTransforms's setUp method
+ """
+ if not test_gdb():
+ return
+
+ self.tempdir = tempfile.mkdtemp()
+ self.destfile = os.path.join(self.tempdir, 'codefile.pyx')
+ self.debug_dest = os.path.join(self.tempdir,
+ 'cython_debug',
+ 'cython_debug_info_codefile')
+ self.cfuncs_destfile = os.path.join(self.tempdir, 'cfuncs')
+
+ self.cwd = os.getcwd()
+ try:
+ os.chdir(self.tempdir)
+
+ shutil.copy(codefile, self.destfile)
+ shutil.copy(cfuncs_file, self.cfuncs_destfile + '.c')
shutil.copy(cfuncs_file.replace('.c', '.h'),
self.cfuncs_destfile + '.h')
-
- compiler = ccompiler.new_compiler()
- compiler.compile(['cfuncs.c'], debug=True, extra_postargs=['-fPIC'])
-
- opts = dict(
- test_directory=self.tempdir,
- module='codefile',
- )
-
- optimization_disabler = build_ext.Optimization()
-
- cython_compile_testcase = runtests.CythonCompileTestCase(
- workdir=self.tempdir,
- # we clean up everything (not only compiled files)
- cleanup_workdir=False,
- tags=runtests.parse_tags(codefile),
- **opts
- )
-
-
- new_stderr = open(os.devnull, 'w')
-
- stderr = sys.stderr
- sys.stderr = new_stderr
-
- optimization_disabler.disable_optimization()
- try:
- 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
- )
- finally:
- optimization_disabler.restore_state()
- sys.stderr = stderr
- new_stderr.close()
-
- # ext = Cython.Distutils.extension.Extension(
- # 'codefile',
- # ['codefile.pyx'],
- # cython_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)
- # )
-
- except:
- os.chdir(self.cwd)
- raise
-
- def tearDown(self):
- if not test_gdb():
- return
- os.chdir(self.cwd)
- shutil.rmtree(self.tempdir)
-
-
-class GdbDebuggerTestCase(DebuggerTestCase):
-
- def setUp(self):
- if not test_gdb():
- return
-
- super(GdbDebuggerTestCase, self).setUp()
-
- prefix_code = textwrap.dedent('''\
- python
-
- import os
- import sys
- import traceback
-
- def excepthook(type, value, tb):
- traceback.print_exception(type, value, tb)
- sys.stderr.flush()
- sys.stdout.flush()
- os._exit(1)
-
- sys.excepthook = excepthook
-
- # Have tracebacks end up on sys.stderr (gdb replaces sys.stderr
- # with an object that calls gdb.write())
- sys.stderr = sys.__stderr__
-
- end
- ''')
-
- code = textwrap.dedent('''\
- python
-
- from Cython.Debugger.Tests import test_libcython_in_gdb
- test_libcython_in_gdb.main(version=%r)
-
- end
- ''' % (sys.version_info[:2],))
-
- self.gdb_command_file = cygdb.make_command_file(self.tempdir,
- prefix_code)
-
- with open(self.gdb_command_file, 'a') as f:
- f.write(code)
-
- args = ['gdb', '-batch', '-x', self.gdb_command_file, '-n', '--args',
- sys.executable, '-c', 'import codefile']
-
- paths = []
- path = os.environ.get('PYTHONPATH')
- if path:
- paths.append(path)
- paths.append(os.path.dirname(os.path.dirname(
- os.path.abspath(Cython.__file__))))
- env = dict(os.environ, PYTHONPATH=os.pathsep.join(paths))
-
- self.p = subprocess.Popen(
- args,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- env=env)
-
- def tearDown(self):
- if not test_gdb():
- return
-
- try:
- super(GdbDebuggerTestCase, self).tearDown()
- if self.p:
- try: self.p.stdout.close()
- except: pass
- try: self.p.stderr.close()
- except: pass
- self.p.wait()
- finally:
- os.remove(self.gdb_command_file)
-
-
-class TestAll(GdbDebuggerTestCase):
-
- def test_all(self):
- if not test_gdb():
- return
-
- out, err = self.p.communicate()
- out = out.decode('UTF-8')
- err = err.decode('UTF-8')
-
- exit_status = self.p.returncode
-
- if exit_status == 1:
- sys.stderr.write(out)
- sys.stderr.write(err)
- elif exit_status >= 2:
- border = u'*' * 30
- start = u'%s v INSIDE GDB v %s' % (border, border)
- stderr = u'%s v STDERR v %s' % (border, border)
- end = u'%s ^ INSIDE GDB ^ %s' % (border, border)
- errmsg = u'\n%s\n%s%s\n%s%s' % (start, out, stderr, err, end)
-
- sys.stderr.write(errmsg)
-
- # FIXME: re-enable this to make the test fail on internal failures
- #self.assertEqual(exit_status, 0)
-
-
-if __name__ == '__main__':
- unittest.main()
+
+ compiler = ccompiler.new_compiler()
+ compiler.compile(['cfuncs.c'], debug=True, extra_postargs=['-fPIC'])
+
+ opts = dict(
+ test_directory=self.tempdir,
+ module='codefile',
+ )
+
+ optimization_disabler = build_ext.Optimization()
+
+ cython_compile_testcase = runtests.CythonCompileTestCase(
+ workdir=self.tempdir,
+ # we clean up everything (not only compiled files)
+ cleanup_workdir=False,
+ tags=runtests.parse_tags(codefile),
+ **opts
+ )
+
+
+ new_stderr = open(os.devnull, 'w')
+
+ stderr = sys.stderr
+ sys.stderr = new_stderr
+
+ optimization_disabler.disable_optimization()
+ try:
+ 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
+ )
+ finally:
+ optimization_disabler.restore_state()
+ sys.stderr = stderr
+ new_stderr.close()
+
+ # ext = Cython.Distutils.extension.Extension(
+ # 'codefile',
+ # ['codefile.pyx'],
+ # cython_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)
+ # )
+
+ except:
+ os.chdir(self.cwd)
+ raise
+
+ def tearDown(self):
+ if not test_gdb():
+ return
+ os.chdir(self.cwd)
+ shutil.rmtree(self.tempdir)
+
+
+class GdbDebuggerTestCase(DebuggerTestCase):
+
+ def setUp(self):
+ if not test_gdb():
+ return
+
+ super(GdbDebuggerTestCase, self).setUp()
+
+ prefix_code = textwrap.dedent('''\
+ python
+
+ import os
+ import sys
+ import traceback
+
+ def excepthook(type, value, tb):
+ traceback.print_exception(type, value, tb)
+ sys.stderr.flush()
+ sys.stdout.flush()
+ os._exit(1)
+
+ sys.excepthook = excepthook
+
+ # Have tracebacks end up on sys.stderr (gdb replaces sys.stderr
+ # with an object that calls gdb.write())
+ sys.stderr = sys.__stderr__
+
+ end
+ ''')
+
+ code = textwrap.dedent('''\
+ python
+
+ from Cython.Debugger.Tests import test_libcython_in_gdb
+ test_libcython_in_gdb.main(version=%r)
+
+ end
+ ''' % (sys.version_info[:2],))
+
+ self.gdb_command_file = cygdb.make_command_file(self.tempdir,
+ prefix_code)
+
+ with open(self.gdb_command_file, 'a') as f:
+ f.write(code)
+
+ args = ['gdb', '-batch', '-x', self.gdb_command_file, '-n', '--args',
+ sys.executable, '-c', 'import codefile']
+
+ paths = []
+ path = os.environ.get('PYTHONPATH')
+ if path:
+ paths.append(path)
+ paths.append(os.path.dirname(os.path.dirname(
+ os.path.abspath(Cython.__file__))))
+ env = dict(os.environ, PYTHONPATH=os.pathsep.join(paths))
+
+ self.p = subprocess.Popen(
+ args,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ env=env)
+
+ def tearDown(self):
+ if not test_gdb():
+ return
+
+ try:
+ super(GdbDebuggerTestCase, self).tearDown()
+ if self.p:
+ try: self.p.stdout.close()
+ except: pass
+ try: self.p.stderr.close()
+ except: pass
+ self.p.wait()
+ finally:
+ os.remove(self.gdb_command_file)
+
+
+class TestAll(GdbDebuggerTestCase):
+
+ def test_all(self):
+ if not test_gdb():
+ return
+
+ out, err = self.p.communicate()
+ out = out.decode('UTF-8')
+ err = err.decode('UTF-8')
+
+ exit_status = self.p.returncode
+
+ if exit_status == 1:
+ sys.stderr.write(out)
+ sys.stderr.write(err)
+ elif exit_status >= 2:
+ border = u'*' * 30
+ start = u'%s v INSIDE GDB v %s' % (border, border)
+ stderr = u'%s v STDERR v %s' % (border, border)
+ end = u'%s ^ INSIDE GDB ^ %s' % (border, border)
+ errmsg = u'\n%s\n%s%s\n%s%s' % (start, out, stderr, err, end)
+
+ sys.stderr.write(errmsg)
+
+ # FIXME: re-enable this to make the test fail on internal failures
+ #self.assertEqual(exit_status, 0)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/contrib/tools/cython/Cython/Debugger/Tests/__init__.py b/contrib/tools/cython/Cython/Debugger/Tests/__init__.py
index 4a2889e8e1..fa81adaff6 100644
--- a/contrib/tools/cython/Cython/Debugger/Tests/__init__.py
+++ b/contrib/tools/cython/Cython/Debugger/Tests/__init__.py
@@ -1 +1 @@
-# empty file
+# empty file
diff --git a/contrib/tools/cython/Cython/Debugger/Tests/cfuncs.c b/contrib/tools/cython/Cython/Debugger/Tests/cfuncs.c
index 263589e77f..ccb42050bf 100644
--- a/contrib/tools/cython/Cython/Debugger/Tests/cfuncs.c
+++ b/contrib/tools/cython/Cython/Debugger/Tests/cfuncs.c
@@ -1,8 +1,8 @@
-void
-some_c_function(void)
-{
- int a, b, c;
-
- a = 1;
- b = 2;
-}
+void
+some_c_function(void)
+{
+ int a, b, c;
+
+ a = 1;
+ b = 2;
+}
diff --git a/contrib/tools/cython/Cython/Debugger/Tests/codefile b/contrib/tools/cython/Cython/Debugger/Tests/codefile
index 5c2b0c2957..6b4c6b6add 100644
--- a/contrib/tools/cython/Cython/Debugger/Tests/codefile
+++ b/contrib/tools/cython/Cython/Debugger/Tests/codefile
@@ -1,50 +1,50 @@
-cdef extern from "stdio.h":
- int puts(char *s)
-
+cdef extern from "stdio.h":
+ int puts(char *s)
+
cdef extern from "cfuncs.h":
- void some_c_function()
-
-import os
-
-cdef int c_var = 12
-python_var = 13
-
-def spam(a=0):
- cdef:
- int b, c
-
- b = c = d = 0
-
- b = 1
- c = 2
- int(10)
- puts("spam")
- os.path.join("foo", "bar")
- some_c_function()
-
-cpdef eggs():
+ void some_c_function()
+
+import os
+
+cdef int c_var = 12
+python_var = 13
+
+def spam(a=0):
+ cdef:
+ int b, c
+
+ b = c = d = 0
+
+ b = 1
+ c = 2
+ int(10)
+ puts("spam")
+ os.path.join("foo", "bar")
+ some_c_function()
+
+cpdef eggs():
pass
-cdef ham():
- pass
-
-cdef class SomeClass(object):
- def spam(self):
- pass
-
-def outer():
- cdef object a = "an object"
- def inner():
- b = 2
- # access closed over variables
- print a, b
- return inner
-
-
-outer()()
-
-spam()
-print "bye!"
-
-def use_ham():
- ham()
+cdef ham():
+ pass
+
+cdef class SomeClass(object):
+ def spam(self):
+ pass
+
+def outer():
+ cdef object a = "an object"
+ def inner():
+ b = 2
+ # access closed over variables
+ print a, b
+ return inner
+
+
+outer()()
+
+spam()
+print "bye!"
+
+def use_ham():
+ ham()
diff --git a/contrib/tools/cython/Cython/Debugger/Tests/test_libcython_in_gdb.py b/contrib/tools/cython/Cython/Debugger/Tests/test_libcython_in_gdb.py
index c4d4ace7c0..bd7608d607 100644
--- a/contrib/tools/cython/Cython/Debugger/Tests/test_libcython_in_gdb.py
+++ b/contrib/tools/cython/Cython/Debugger/Tests/test_libcython_in_gdb.py
@@ -1,496 +1,496 @@
-"""
-Tests that run inside GDB.
-
-Note: debug information is already imported by the file generated by
-Cython.Debugger.Cygdb.make_command_file()
-"""
-
+"""
+Tests that run inside GDB.
+
+Note: debug information is already imported by the file generated by
+Cython.Debugger.Cygdb.make_command_file()
+"""
+
from __future__ import absolute_import
-import os
-import re
-import sys
-import trace
-import inspect
-import warnings
-import unittest
-import textwrap
-import tempfile
-import functools
-import traceback
-import itertools
+import os
+import re
+import sys
+import trace
+import inspect
+import warnings
+import unittest
+import textwrap
+import tempfile
+import functools
+import traceback
+import itertools
#from test import test_support
-
-import gdb
-
+
+import gdb
+
from .. import libcython
from .. import libpython
from . import TestLibCython as test_libcython
from ...Utils import add_metaclass
-
-# for some reason sys.argv is missing in gdb
-sys.argv = ['gdb']
-
-
-def print_on_call_decorator(func):
- @functools.wraps(func)
- def wrapper(self, *args, **kwargs):
- _debug(type(self).__name__, func.__name__)
-
- try:
- return func(self, *args, **kwargs)
+
+# for some reason sys.argv is missing in gdb
+sys.argv = ['gdb']
+
+
+def print_on_call_decorator(func):
+ @functools.wraps(func)
+ def wrapper(self, *args, **kwargs):
+ _debug(type(self).__name__, func.__name__)
+
+ try:
+ return func(self, *args, **kwargs)
except Exception:
_debug("An exception occurred:", traceback.format_exc())
- raise
-
- return wrapper
-
-class TraceMethodCallMeta(type):
-
- def __init__(self, name, bases, dict):
+ raise
+
+ return wrapper
+
+class TraceMethodCallMeta(type):
+
+ def __init__(self, name, bases, dict):
for func_name, func in dict.items():
- if inspect.isfunction(func):
- setattr(self, func_name, print_on_call_decorator(func))
-
-
+ if inspect.isfunction(func):
+ setattr(self, func_name, print_on_call_decorator(func))
+
+
@add_metaclass(TraceMethodCallMeta)
-class DebugTestCase(unittest.TestCase):
- """
- Base class for test cases. On teardown it kills the inferior and unsets
- all breakpoints.
- """
-
- def __init__(self, name):
- super(DebugTestCase, self).__init__(name)
- self.cy = libcython.cy
- self.module = libcython.cy.cython_namespace['codefile']
- self.spam_func, self.spam_meth = libcython.cy.functions_by_name['spam']
- self.ham_func = libcython.cy.functions_by_qualified_name[
- 'codefile.ham']
- self.eggs_func = libcython.cy.functions_by_qualified_name[
- 'codefile.eggs']
-
- def read_var(self, varname, cast_to=None):
- result = gdb.parse_and_eval('$cy_cvalue("%s")' % varname)
- if cast_to:
- result = cast_to(result)
-
- return result
-
- def local_info(self):
- return gdb.execute('info locals', to_string=True)
-
- def lineno_equals(self, source_line=None, lineno=None):
- if source_line is not None:
- lineno = test_libcython.source_to_lineno[source_line]
- frame = gdb.selected_frame()
- self.assertEqual(libcython.cython_info.lineno(frame), lineno)
-
- def break_and_run(self, source_line):
- break_lineno = test_libcython.source_to_lineno[source_line]
- gdb.execute('cy break codefile:%d' % break_lineno, to_string=True)
- gdb.execute('run', to_string=True)
-
- def tearDown(self):
- gdb.execute('delete breakpoints', to_string=True)
- try:
- gdb.execute('kill inferior 1', to_string=True)
- except RuntimeError:
- pass
-
- gdb.execute('set args -c "import codefile"')
-
-
-class TestDebugInformationClasses(DebugTestCase):
-
- def test_CythonModule(self):
- "test that debug information was parsed properly into data structures"
- self.assertEqual(self.module.name, 'codefile')
- global_vars = ('c_var', 'python_var', '__name__',
- '__builtins__', '__doc__', '__file__')
- assert set(global_vars).issubset(self.module.globals)
-
- def test_CythonVariable(self):
- module_globals = self.module.globals
- c_var = module_globals['c_var']
- python_var = module_globals['python_var']
- self.assertEqual(c_var.type, libcython.CObject)
- self.assertEqual(python_var.type, libcython.PythonObject)
- self.assertEqual(c_var.qualified_name, 'codefile.c_var')
-
- def test_CythonFunction(self):
- self.assertEqual(self.spam_func.qualified_name, 'codefile.spam')
- self.assertEqual(self.spam_meth.qualified_name,
- 'codefile.SomeClass.spam')
- self.assertEqual(self.spam_func.module, self.module)
-
- assert self.eggs_func.pf_cname, (self.eggs_func, self.eggs_func.pf_cname)
- assert not self.ham_func.pf_cname
- assert not self.spam_func.pf_cname
- assert not self.spam_meth.pf_cname
-
- self.assertEqual(self.spam_func.type, libcython.CObject)
- self.assertEqual(self.ham_func.type, libcython.CObject)
-
- self.assertEqual(self.spam_func.arguments, ['a'])
- self.assertEqual(self.spam_func.step_into_functions,
- set(['puts', 'some_c_function']))
-
- expected_lineno = test_libcython.source_to_lineno['def spam(a=0):']
- self.assertEqual(self.spam_func.lineno, expected_lineno)
- self.assertEqual(sorted(self.spam_func.locals), list('abcd'))
-
-
-class TestParameters(unittest.TestCase):
-
- def test_parameters(self):
- gdb.execute('set cy_colorize_code on')
- assert libcython.parameters.colorize_code
- gdb.execute('set cy_colorize_code off')
- assert not libcython.parameters.colorize_code
-
-
-class TestBreak(DebugTestCase):
-
- def test_break(self):
- breakpoint_amount = len(gdb.breakpoints() or ())
- gdb.execute('cy break codefile.spam')
-
- self.assertEqual(len(gdb.breakpoints()), breakpoint_amount + 1)
- bp = gdb.breakpoints()[-1]
- self.assertEqual(bp.type, gdb.BP_BREAKPOINT)
- assert self.spam_func.cname in bp.location
- assert bp.enabled
-
- def test_python_break(self):
- gdb.execute('cy break -p join')
- assert 'def join(' in gdb.execute('cy run', to_string=True)
-
- def test_break_lineno(self):
- beginline = 'import os'
- nextline = 'cdef int c_var = 12'
-
- self.break_and_run(beginline)
- self.lineno_equals(beginline)
- step_result = gdb.execute('cy step', to_string=True)
- self.lineno_equals(nextline)
- assert step_result.rstrip().endswith(nextline)
-
-
-class TestKilled(DebugTestCase):
-
- def test_abort(self):
- gdb.execute("set args -c 'import os; os.abort()'")
- output = gdb.execute('cy run', to_string=True)
- assert 'abort' in output.lower()
-
-
-class DebugStepperTestCase(DebugTestCase):
-
- def step(self, varnames_and_values, source_line=None, lineno=None):
- gdb.execute(self.command)
- for varname, value in varnames_and_values:
- self.assertEqual(self.read_var(varname), value, self.local_info())
-
- self.lineno_equals(source_line, lineno)
-
-
-class TestStep(DebugStepperTestCase):
- """
- Test stepping. Stepping happens in the code found in
- Cython/Debugger/Tests/codefile.
- """
-
- def test_cython_step(self):
- gdb.execute('cy break codefile.spam')
-
- gdb.execute('run', to_string=True)
- self.lineno_equals('def spam(a=0):')
-
- gdb.execute('cy step', to_string=True)
- self.lineno_equals('b = c = d = 0')
-
- self.command = 'cy step'
- self.step([('b', 0)], source_line='b = 1')
- self.step([('b', 1), ('c', 0)], source_line='c = 2')
- self.step([('c', 2)], source_line='int(10)')
- self.step([], source_line='puts("spam")')
-
- gdb.execute('cont', to_string=True)
- self.assertEqual(len(gdb.inferiors()), 1)
- self.assertEqual(gdb.inferiors()[0].pid, 0)
-
- def test_c_step(self):
- self.break_and_run('some_c_function()')
- gdb.execute('cy step', to_string=True)
- self.assertEqual(gdb.selected_frame().name(), 'some_c_function')
-
- def test_python_step(self):
- self.break_and_run('os.path.join("foo", "bar")')
-
- result = gdb.execute('cy step', to_string=True)
-
- curframe = gdb.selected_frame()
- self.assertEqual(curframe.name(), 'PyEval_EvalFrameEx')
-
- pyframe = libpython.Frame(curframe).get_pyop()
- # With Python 3 inferiors, pyframe.co_name will return a PyUnicodePtr,
- # be compatible
- frame_name = pyframe.co_name.proxyval(set())
- self.assertEqual(frame_name, 'join')
- assert re.match(r'\d+ def join\(', result), result
-
-
-class TestNext(DebugStepperTestCase):
-
- def test_cython_next(self):
- self.break_and_run('c = 2')
-
- lines = (
- 'int(10)',
- 'puts("spam")',
- 'os.path.join("foo", "bar")',
- 'some_c_function()',
- )
-
- for line in lines:
- gdb.execute('cy next')
- self.lineno_equals(line)
-
-
-class TestLocalsGlobals(DebugTestCase):
-
- def test_locals(self):
- self.break_and_run('int(10)')
-
- result = gdb.execute('cy locals', to_string=True)
- assert 'a = 0', repr(result)
- assert 'b = (int) 1', result
- assert 'c = (int) 2' in result, repr(result)
-
- def test_globals(self):
- self.break_and_run('int(10)')
-
- result = gdb.execute('cy globals', to_string=True)
- assert '__name__ ' in result, repr(result)
- assert '__doc__ ' in result, repr(result)
- assert 'os ' in result, repr(result)
- assert 'c_var ' in result, repr(result)
- assert 'python_var ' in result, repr(result)
-
-
-class TestBacktrace(DebugTestCase):
-
- def test_backtrace(self):
- libcython.parameters.colorize_code.value = False
-
- self.break_and_run('os.path.join("foo", "bar")')
-
- def match_backtrace_output(result):
- assert re.search(r'\#\d+ *0x.* in spam\(\) at .*codefile\.pyx:22',
- result), result
- assert 'os.path.join("foo", "bar")' in result, result
-
- result = gdb.execute('cy bt', to_string=True)
- match_backtrace_output(result)
-
- result = gdb.execute('cy bt -a', to_string=True)
- match_backtrace_output(result)
-
- # Apparently not everyone has main()
- # assert re.search(r'\#0 *0x.* in main\(\)', result), result
-
-
-class TestFunctions(DebugTestCase):
-
- def test_functions(self):
- self.break_and_run('c = 2')
- result = gdb.execute('print $cy_cname("b")', to_string=True)
- assert re.search('__pyx_.*b', result), result
-
- result = gdb.execute('print $cy_lineno()', to_string=True)
- supposed_lineno = test_libcython.source_to_lineno['c = 2']
- assert str(supposed_lineno) in result, (supposed_lineno, result)
-
- result = gdb.execute('print $cy_cvalue("b")', to_string=True)
- assert '= 1' in result
-
-
-class TestPrint(DebugTestCase):
-
- def test_print(self):
- self.break_and_run('c = 2')
- result = gdb.execute('cy print b', to_string=True)
- self.assertEqual('b = (int) 1\n', result)
-
-
-class TestUpDown(DebugTestCase):
-
- def test_updown(self):
- self.break_and_run('os.path.join("foo", "bar")')
- gdb.execute('cy step')
- self.assertRaises(RuntimeError, gdb.execute, 'cy down')
-
- result = gdb.execute('cy up', to_string=True)
- assert 'spam()' in result
- assert 'os.path.join("foo", "bar")' in result
-
-
-class TestExec(DebugTestCase):
-
- def setUp(self):
- super(TestExec, self).setUp()
- self.fd, self.tmpfilename = tempfile.mkstemp()
- self.tmpfile = os.fdopen(self.fd, 'r+')
-
- def tearDown(self):
- super(TestExec, self).tearDown()
-
- try:
- self.tmpfile.close()
- finally:
- os.remove(self.tmpfilename)
-
- def eval_command(self, command):
- gdb.execute('cy exec open(%r, "w").write(str(%s))' %
- (self.tmpfilename, command))
- return self.tmpfile.read().strip()
-
- def test_cython_exec(self):
- self.break_and_run('os.path.join("foo", "bar")')
-
- # test normal behaviour
- self.assertEqual("[0]", self.eval_command('[a]'))
-
- # test multiline code
- result = gdb.execute(textwrap.dedent('''\
- cy exec
- pass
-
- "nothing"
- end
- '''))
- result = self.tmpfile.read().rstrip()
- self.assertEqual('', result)
-
- def test_python_exec(self):
- self.break_and_run('os.path.join("foo", "bar")')
- gdb.execute('cy step')
-
- gdb.execute('cy exec some_random_var = 14')
- self.assertEqual('14', self.eval_command('some_random_var'))
-
-
-class CySet(DebugTestCase):
-
- def test_cyset(self):
- self.break_and_run('os.path.join("foo", "bar")')
-
- gdb.execute('cy set a = $cy_eval("{None: []}")')
- stringvalue = self.read_var("a", cast_to=str)
- self.assertEqual(stringvalue, "{None: []}")
-
-
-class TestCyEval(DebugTestCase):
- "Test the $cy_eval() gdb function."
-
- def test_cy_eval(self):
- # This function leaks a few objects in the GDB python process. This
- # is no biggie
- self.break_and_run('os.path.join("foo", "bar")')
-
- result = gdb.execute('print $cy_eval("None")', to_string=True)
- assert re.match(r'\$\d+ = None\n', result), result
-
- result = gdb.execute('print $cy_eval("[a]")', to_string=True)
- assert re.match(r'\$\d+ = \[0\]', result), result
-
-
-class TestClosure(DebugTestCase):
-
- def break_and_run_func(self, funcname):
- gdb.execute('cy break ' + funcname)
- gdb.execute('cy run')
-
- def test_inner(self):
- self.break_and_run_func('inner')
- self.assertEqual('', gdb.execute('cy locals', to_string=True))
-
- # Allow the Cython-generated code to initialize the scope variable
- gdb.execute('cy step')
-
- self.assertEqual(str(self.read_var('a')), "'an object'")
- print_result = gdb.execute('cy print a', to_string=True).strip()
- self.assertEqual(print_result, "a = 'an object'")
-
- def test_outer(self):
- self.break_and_run_func('outer')
- self.assertEqual('', gdb.execute('cy locals', to_string=True))
-
- # Initialize scope with 'a' uninitialized
- gdb.execute('cy step')
- self.assertEqual('', gdb.execute('cy locals', to_string=True))
-
- # Initialize 'a' to 1
- gdb.execute('cy step')
- print_result = gdb.execute('cy print a', to_string=True).strip()
- self.assertEqual(print_result, "a = 'an object'")
-
-
-_do_debug = os.environ.get('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 run_unittest_in_module(modulename):
- try:
- gdb.lookup_type('PyModuleObject')
- except RuntimeError:
- msg = ("Unable to run tests, Python was not compiled with "
- "debugging information. Either compile python with "
- "-g or get a debug build (configure with --with-pydebug).")
- warnings.warn(msg)
- os._exit(1)
- else:
- m = __import__(modulename, fromlist=[''])
- tests = inspect.getmembers(m, inspect.isclass)
-
- # test_support.run_unittest(tests)
-
- test_loader = unittest.TestLoader()
- suite = unittest.TestSuite(
- [test_loader.loadTestsFromTestCase(cls) for name, cls in tests])
-
- result = unittest.TextTestRunner(verbosity=1).run(suite)
- return result.wasSuccessful()
-
-def runtests():
- """
- Run the libcython and libpython tests. Ensure that an appropriate status is
- returned to the parent test process.
- """
- from Cython.Debugger.Tests import test_libpython_in_gdb
-
- success_libcython = run_unittest_in_module(__name__)
- success_libpython = run_unittest_in_module(test_libpython_in_gdb.__name__)
-
- if not success_libcython or not success_libpython:
- sys.exit(2)
-
-def main(version, trace_code=False):
- global inferior_python_version
-
- inferior_python_version = version
-
- if trace_code:
- tracer = trace.Trace(count=False, trace=True, outfile=sys.stderr,
- ignoredirs=[sys.prefix, sys.exec_prefix])
- tracer.runfunc(runtests)
- else:
- runtests()
+class DebugTestCase(unittest.TestCase):
+ """
+ Base class for test cases. On teardown it kills the inferior and unsets
+ all breakpoints.
+ """
+
+ def __init__(self, name):
+ super(DebugTestCase, self).__init__(name)
+ self.cy = libcython.cy
+ self.module = libcython.cy.cython_namespace['codefile']
+ self.spam_func, self.spam_meth = libcython.cy.functions_by_name['spam']
+ self.ham_func = libcython.cy.functions_by_qualified_name[
+ 'codefile.ham']
+ self.eggs_func = libcython.cy.functions_by_qualified_name[
+ 'codefile.eggs']
+
+ def read_var(self, varname, cast_to=None):
+ result = gdb.parse_and_eval('$cy_cvalue("%s")' % varname)
+ if cast_to:
+ result = cast_to(result)
+
+ return result
+
+ def local_info(self):
+ return gdb.execute('info locals', to_string=True)
+
+ def lineno_equals(self, source_line=None, lineno=None):
+ if source_line is not None:
+ lineno = test_libcython.source_to_lineno[source_line]
+ frame = gdb.selected_frame()
+ self.assertEqual(libcython.cython_info.lineno(frame), lineno)
+
+ def break_and_run(self, source_line):
+ break_lineno = test_libcython.source_to_lineno[source_line]
+ gdb.execute('cy break codefile:%d' % break_lineno, to_string=True)
+ gdb.execute('run', to_string=True)
+
+ def tearDown(self):
+ gdb.execute('delete breakpoints', to_string=True)
+ try:
+ gdb.execute('kill inferior 1', to_string=True)
+ except RuntimeError:
+ pass
+
+ gdb.execute('set args -c "import codefile"')
+
+
+class TestDebugInformationClasses(DebugTestCase):
+
+ def test_CythonModule(self):
+ "test that debug information was parsed properly into data structures"
+ self.assertEqual(self.module.name, 'codefile')
+ global_vars = ('c_var', 'python_var', '__name__',
+ '__builtins__', '__doc__', '__file__')
+ assert set(global_vars).issubset(self.module.globals)
+
+ def test_CythonVariable(self):
+ module_globals = self.module.globals
+ c_var = module_globals['c_var']
+ python_var = module_globals['python_var']
+ self.assertEqual(c_var.type, libcython.CObject)
+ self.assertEqual(python_var.type, libcython.PythonObject)
+ self.assertEqual(c_var.qualified_name, 'codefile.c_var')
+
+ def test_CythonFunction(self):
+ self.assertEqual(self.spam_func.qualified_name, 'codefile.spam')
+ self.assertEqual(self.spam_meth.qualified_name,
+ 'codefile.SomeClass.spam')
+ self.assertEqual(self.spam_func.module, self.module)
+
+ assert self.eggs_func.pf_cname, (self.eggs_func, self.eggs_func.pf_cname)
+ assert not self.ham_func.pf_cname
+ assert not self.spam_func.pf_cname
+ assert not self.spam_meth.pf_cname
+
+ self.assertEqual(self.spam_func.type, libcython.CObject)
+ self.assertEqual(self.ham_func.type, libcython.CObject)
+
+ self.assertEqual(self.spam_func.arguments, ['a'])
+ self.assertEqual(self.spam_func.step_into_functions,
+ set(['puts', 'some_c_function']))
+
+ expected_lineno = test_libcython.source_to_lineno['def spam(a=0):']
+ self.assertEqual(self.spam_func.lineno, expected_lineno)
+ self.assertEqual(sorted(self.spam_func.locals), list('abcd'))
+
+
+class TestParameters(unittest.TestCase):
+
+ def test_parameters(self):
+ gdb.execute('set cy_colorize_code on')
+ assert libcython.parameters.colorize_code
+ gdb.execute('set cy_colorize_code off')
+ assert not libcython.parameters.colorize_code
+
+
+class TestBreak(DebugTestCase):
+
+ def test_break(self):
+ breakpoint_amount = len(gdb.breakpoints() or ())
+ gdb.execute('cy break codefile.spam')
+
+ self.assertEqual(len(gdb.breakpoints()), breakpoint_amount + 1)
+ bp = gdb.breakpoints()[-1]
+ self.assertEqual(bp.type, gdb.BP_BREAKPOINT)
+ assert self.spam_func.cname in bp.location
+ assert bp.enabled
+
+ def test_python_break(self):
+ gdb.execute('cy break -p join')
+ assert 'def join(' in gdb.execute('cy run', to_string=True)
+
+ def test_break_lineno(self):
+ beginline = 'import os'
+ nextline = 'cdef int c_var = 12'
+
+ self.break_and_run(beginline)
+ self.lineno_equals(beginline)
+ step_result = gdb.execute('cy step', to_string=True)
+ self.lineno_equals(nextline)
+ assert step_result.rstrip().endswith(nextline)
+
+
+class TestKilled(DebugTestCase):
+
+ def test_abort(self):
+ gdb.execute("set args -c 'import os; os.abort()'")
+ output = gdb.execute('cy run', to_string=True)
+ assert 'abort' in output.lower()
+
+
+class DebugStepperTestCase(DebugTestCase):
+
+ def step(self, varnames_and_values, source_line=None, lineno=None):
+ gdb.execute(self.command)
+ for varname, value in varnames_and_values:
+ self.assertEqual(self.read_var(varname), value, self.local_info())
+
+ self.lineno_equals(source_line, lineno)
+
+
+class TestStep(DebugStepperTestCase):
+ """
+ Test stepping. Stepping happens in the code found in
+ Cython/Debugger/Tests/codefile.
+ """
+
+ def test_cython_step(self):
+ gdb.execute('cy break codefile.spam')
+
+ gdb.execute('run', to_string=True)
+ self.lineno_equals('def spam(a=0):')
+
+ gdb.execute('cy step', to_string=True)
+ self.lineno_equals('b = c = d = 0')
+
+ self.command = 'cy step'
+ self.step([('b', 0)], source_line='b = 1')
+ self.step([('b', 1), ('c', 0)], source_line='c = 2')
+ self.step([('c', 2)], source_line='int(10)')
+ self.step([], source_line='puts("spam")')
+
+ gdb.execute('cont', to_string=True)
+ self.assertEqual(len(gdb.inferiors()), 1)
+ self.assertEqual(gdb.inferiors()[0].pid, 0)
+
+ def test_c_step(self):
+ self.break_and_run('some_c_function()')
+ gdb.execute('cy step', to_string=True)
+ self.assertEqual(gdb.selected_frame().name(), 'some_c_function')
+
+ def test_python_step(self):
+ self.break_and_run('os.path.join("foo", "bar")')
+
+ result = gdb.execute('cy step', to_string=True)
+
+ curframe = gdb.selected_frame()
+ self.assertEqual(curframe.name(), 'PyEval_EvalFrameEx')
+
+ pyframe = libpython.Frame(curframe).get_pyop()
+ # With Python 3 inferiors, pyframe.co_name will return a PyUnicodePtr,
+ # be compatible
+ frame_name = pyframe.co_name.proxyval(set())
+ self.assertEqual(frame_name, 'join')
+ assert re.match(r'\d+ def join\(', result), result
+
+
+class TestNext(DebugStepperTestCase):
+
+ def test_cython_next(self):
+ self.break_and_run('c = 2')
+
+ lines = (
+ 'int(10)',
+ 'puts("spam")',
+ 'os.path.join("foo", "bar")',
+ 'some_c_function()',
+ )
+
+ for line in lines:
+ gdb.execute('cy next')
+ self.lineno_equals(line)
+
+
+class TestLocalsGlobals(DebugTestCase):
+
+ def test_locals(self):
+ self.break_and_run('int(10)')
+
+ result = gdb.execute('cy locals', to_string=True)
+ assert 'a = 0', repr(result)
+ assert 'b = (int) 1', result
+ assert 'c = (int) 2' in result, repr(result)
+
+ def test_globals(self):
+ self.break_and_run('int(10)')
+
+ result = gdb.execute('cy globals', to_string=True)
+ assert '__name__ ' in result, repr(result)
+ assert '__doc__ ' in result, repr(result)
+ assert 'os ' in result, repr(result)
+ assert 'c_var ' in result, repr(result)
+ assert 'python_var ' in result, repr(result)
+
+
+class TestBacktrace(DebugTestCase):
+
+ def test_backtrace(self):
+ libcython.parameters.colorize_code.value = False
+
+ self.break_and_run('os.path.join("foo", "bar")')
+
+ def match_backtrace_output(result):
+ assert re.search(r'\#\d+ *0x.* in spam\(\) at .*codefile\.pyx:22',
+ result), result
+ assert 'os.path.join("foo", "bar")' in result, result
+
+ result = gdb.execute('cy bt', to_string=True)
+ match_backtrace_output(result)
+
+ result = gdb.execute('cy bt -a', to_string=True)
+ match_backtrace_output(result)
+
+ # Apparently not everyone has main()
+ # assert re.search(r'\#0 *0x.* in main\(\)', result), result
+
+
+class TestFunctions(DebugTestCase):
+
+ def test_functions(self):
+ self.break_and_run('c = 2')
+ result = gdb.execute('print $cy_cname("b")', to_string=True)
+ assert re.search('__pyx_.*b', result), result
+
+ result = gdb.execute('print $cy_lineno()', to_string=True)
+ supposed_lineno = test_libcython.source_to_lineno['c = 2']
+ assert str(supposed_lineno) in result, (supposed_lineno, result)
+
+ result = gdb.execute('print $cy_cvalue("b")', to_string=True)
+ assert '= 1' in result
+
+
+class TestPrint(DebugTestCase):
+
+ def test_print(self):
+ self.break_and_run('c = 2')
+ result = gdb.execute('cy print b', to_string=True)
+ self.assertEqual('b = (int) 1\n', result)
+
+
+class TestUpDown(DebugTestCase):
+
+ def test_updown(self):
+ self.break_and_run('os.path.join("foo", "bar")')
+ gdb.execute('cy step')
+ self.assertRaises(RuntimeError, gdb.execute, 'cy down')
+
+ result = gdb.execute('cy up', to_string=True)
+ assert 'spam()' in result
+ assert 'os.path.join("foo", "bar")' in result
+
+
+class TestExec(DebugTestCase):
+
+ def setUp(self):
+ super(TestExec, self).setUp()
+ self.fd, self.tmpfilename = tempfile.mkstemp()
+ self.tmpfile = os.fdopen(self.fd, 'r+')
+
+ def tearDown(self):
+ super(TestExec, self).tearDown()
+
+ try:
+ self.tmpfile.close()
+ finally:
+ os.remove(self.tmpfilename)
+
+ def eval_command(self, command):
+ gdb.execute('cy exec open(%r, "w").write(str(%s))' %
+ (self.tmpfilename, command))
+ return self.tmpfile.read().strip()
+
+ def test_cython_exec(self):
+ self.break_and_run('os.path.join("foo", "bar")')
+
+ # test normal behaviour
+ self.assertEqual("[0]", self.eval_command('[a]'))
+
+ # test multiline code
+ result = gdb.execute(textwrap.dedent('''\
+ cy exec
+ pass
+
+ "nothing"
+ end
+ '''))
+ result = self.tmpfile.read().rstrip()
+ self.assertEqual('', result)
+
+ def test_python_exec(self):
+ self.break_and_run('os.path.join("foo", "bar")')
+ gdb.execute('cy step')
+
+ gdb.execute('cy exec some_random_var = 14')
+ self.assertEqual('14', self.eval_command('some_random_var'))
+
+
+class CySet(DebugTestCase):
+
+ def test_cyset(self):
+ self.break_and_run('os.path.join("foo", "bar")')
+
+ gdb.execute('cy set a = $cy_eval("{None: []}")')
+ stringvalue = self.read_var("a", cast_to=str)
+ self.assertEqual(stringvalue, "{None: []}")
+
+
+class TestCyEval(DebugTestCase):
+ "Test the $cy_eval() gdb function."
+
+ def test_cy_eval(self):
+ # This function leaks a few objects in the GDB python process. This
+ # is no biggie
+ self.break_and_run('os.path.join("foo", "bar")')
+
+ result = gdb.execute('print $cy_eval("None")', to_string=True)
+ assert re.match(r'\$\d+ = None\n', result), result
+
+ result = gdb.execute('print $cy_eval("[a]")', to_string=True)
+ assert re.match(r'\$\d+ = \[0\]', result), result
+
+
+class TestClosure(DebugTestCase):
+
+ def break_and_run_func(self, funcname):
+ gdb.execute('cy break ' + funcname)
+ gdb.execute('cy run')
+
+ def test_inner(self):
+ self.break_and_run_func('inner')
+ self.assertEqual('', gdb.execute('cy locals', to_string=True))
+
+ # Allow the Cython-generated code to initialize the scope variable
+ gdb.execute('cy step')
+
+ self.assertEqual(str(self.read_var('a')), "'an object'")
+ print_result = gdb.execute('cy print a', to_string=True).strip()
+ self.assertEqual(print_result, "a = 'an object'")
+
+ def test_outer(self):
+ self.break_and_run_func('outer')
+ self.assertEqual('', gdb.execute('cy locals', to_string=True))
+
+ # Initialize scope with 'a' uninitialized
+ gdb.execute('cy step')
+ self.assertEqual('', gdb.execute('cy locals', to_string=True))
+
+ # Initialize 'a' to 1
+ gdb.execute('cy step')
+ print_result = gdb.execute('cy print a', to_string=True).strip()
+ self.assertEqual(print_result, "a = 'an object'")
+
+
+_do_debug = os.environ.get('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 run_unittest_in_module(modulename):
+ try:
+ gdb.lookup_type('PyModuleObject')
+ except RuntimeError:
+ msg = ("Unable to run tests, Python was not compiled with "
+ "debugging information. Either compile python with "
+ "-g or get a debug build (configure with --with-pydebug).")
+ warnings.warn(msg)
+ os._exit(1)
+ else:
+ m = __import__(modulename, fromlist=[''])
+ tests = inspect.getmembers(m, inspect.isclass)
+
+ # test_support.run_unittest(tests)
+
+ test_loader = unittest.TestLoader()
+ suite = unittest.TestSuite(
+ [test_loader.loadTestsFromTestCase(cls) for name, cls in tests])
+
+ result = unittest.TextTestRunner(verbosity=1).run(suite)
+ return result.wasSuccessful()
+
+def runtests():
+ """
+ Run the libcython and libpython tests. Ensure that an appropriate status is
+ returned to the parent test process.
+ """
+ from Cython.Debugger.Tests import test_libpython_in_gdb
+
+ success_libcython = run_unittest_in_module(__name__)
+ success_libpython = run_unittest_in_module(test_libpython_in_gdb.__name__)
+
+ if not success_libcython or not success_libpython:
+ sys.exit(2)
+
+def main(version, trace_code=False):
+ global inferior_python_version
+
+ inferior_python_version = version
+
+ if trace_code:
+ tracer = trace.Trace(count=False, trace=True, outfile=sys.stderr,
+ ignoredirs=[sys.prefix, sys.exec_prefix])
+ tracer.runfunc(runtests)
+ else:
+ runtests()
diff --git a/contrib/tools/cython/Cython/Debugger/Tests/test_libpython_in_gdb.py b/contrib/tools/cython/Cython/Debugger/Tests/test_libpython_in_gdb.py
index 8a2b83419b..6f34cee47b 100644
--- a/contrib/tools/cython/Cython/Debugger/Tests/test_libpython_in_gdb.py
+++ b/contrib/tools/cython/Cython/Debugger/Tests/test_libpython_in_gdb.py
@@ -1,115 +1,115 @@
-# -*- coding: UTF-8 -*-
-
-"""
-Test libpython.py. This is already partly tested by test_libcython_in_gdb and
-Lib/test/test_gdb.py in the Python source. These tests are run in gdb and
-called from test_libcython_in_gdb.main()
-"""
-
-import os
-import sys
-
-import gdb
-
-from Cython.Debugger import libcython
-from Cython.Debugger import libpython
-
+# -*- coding: UTF-8 -*-
+
+"""
+Test libpython.py. This is already partly tested by test_libcython_in_gdb and
+Lib/test/test_gdb.py in the Python source. These tests are run in gdb and
+called from test_libcython_in_gdb.main()
+"""
+
+import os
+import sys
+
+import gdb
+
+from Cython.Debugger import libcython
+from Cython.Debugger import libpython
+
from . import test_libcython_in_gdb
from .test_libcython_in_gdb import _debug, inferior_python_version
-
-
-class TestPrettyPrinters(test_libcython_in_gdb.DebugTestCase):
- """
- Test whether types of Python objects are correctly inferred and that
- the right libpython.PySomeTypeObjectPtr classes are instantiated.
-
- Also test whether values are appropriately formatted (don't be too
- laborious as Lib/test/test_gdb.py already covers this extensively).
-
- Don't take care of decreffing newly allocated objects as a new
- interpreter is started for every test anyway.
- """
-
- def setUp(self):
- super(TestPrettyPrinters, self).setUp()
- self.break_and_run('b = c = d = 0')
-
- def get_pyobject(self, code):
- value = gdb.parse_and_eval(code)
- assert libpython.pointervalue(value) != 0
- return value
-
- def pyobject_fromcode(self, code, gdbvar=None):
- if gdbvar is not None:
- d = {'varname':gdbvar, 'code':code}
- gdb.execute('set $%(varname)s = %(code)s' % d)
- code = '$' + gdbvar
-
- return libpython.PyObjectPtr.from_pyobject_ptr(self.get_pyobject(code))
-
- def get_repr(self, pyobject):
- return pyobject.get_truncated_repr(libpython.MAX_OUTPUT_LEN)
-
- def alloc_bytestring(self, string, gdbvar=None):
- if inferior_python_version < (3, 0):
- funcname = 'PyString_FromStringAndSize'
- else:
- funcname = 'PyBytes_FromStringAndSize'
-
+
+
+class TestPrettyPrinters(test_libcython_in_gdb.DebugTestCase):
+ """
+ Test whether types of Python objects are correctly inferred and that
+ the right libpython.PySomeTypeObjectPtr classes are instantiated.
+
+ Also test whether values are appropriately formatted (don't be too
+ laborious as Lib/test/test_gdb.py already covers this extensively).
+
+ Don't take care of decreffing newly allocated objects as a new
+ interpreter is started for every test anyway.
+ """
+
+ def setUp(self):
+ super(TestPrettyPrinters, self).setUp()
+ self.break_and_run('b = c = d = 0')
+
+ def get_pyobject(self, code):
+ value = gdb.parse_and_eval(code)
+ assert libpython.pointervalue(value) != 0
+ return value
+
+ def pyobject_fromcode(self, code, gdbvar=None):
+ if gdbvar is not None:
+ d = {'varname':gdbvar, 'code':code}
+ gdb.execute('set $%(varname)s = %(code)s' % d)
+ code = '$' + gdbvar
+
+ return libpython.PyObjectPtr.from_pyobject_ptr(self.get_pyobject(code))
+
+ def get_repr(self, pyobject):
+ return pyobject.get_truncated_repr(libpython.MAX_OUTPUT_LEN)
+
+ def alloc_bytestring(self, string, gdbvar=None):
+ if inferior_python_version < (3, 0):
+ funcname = 'PyString_FromStringAndSize'
+ else:
+ funcname = 'PyBytes_FromStringAndSize'
+
assert b'"' not in string
-
- # ensure double quotes
+
+ # ensure double quotes
code = '(PyObject *) %s("%s", %d)' % (funcname, string.decode('iso8859-1'), len(string))
- return self.pyobject_fromcode(code, gdbvar=gdbvar)
-
- def alloc_unicodestring(self, string, gdbvar=None):
- postfix = libpython.get_inferior_unicode_postfix()
+ return self.pyobject_fromcode(code, gdbvar=gdbvar)
+
+ def alloc_unicodestring(self, string, gdbvar=None):
+ postfix = libpython.get_inferior_unicode_postfix()
funcname = 'PyUnicode%s_DecodeUnicodeEscape' % (postfix,)
-
+
data = string.encode("unicode_escape").decode('iso8859-1')
- return self.pyobject_fromcode(
+ return self.pyobject_fromcode(
'(PyObject *) %s("%s", %d, "strict")' % (
funcname, data.replace('"', r'\"').replace('\\', r'\\'), len(data)),
- gdbvar=gdbvar)
-
- def test_bytestring(self):
+ gdbvar=gdbvar)
+
+ def test_bytestring(self):
bytestring = self.alloc_bytestring(b"spam")
-
- if inferior_python_version < (3, 0):
- bytestring_class = libpython.PyStringObjectPtr
+
+ if inferior_python_version < (3, 0):
+ bytestring_class = libpython.PyStringObjectPtr
expected = repr(b"spam")
- else:
- bytestring_class = libpython.PyBytesObjectPtr
- expected = "b'spam'"
-
- self.assertEqual(type(bytestring), bytestring_class)
- self.assertEqual(self.get_repr(bytestring), expected)
-
- def test_unicode(self):
- unicode_string = self.alloc_unicodestring(u"spam ἄλφα")
-
+ else:
+ bytestring_class = libpython.PyBytesObjectPtr
+ expected = "b'spam'"
+
+ self.assertEqual(type(bytestring), bytestring_class)
+ self.assertEqual(self.get_repr(bytestring), expected)
+
+ def test_unicode(self):
+ unicode_string = self.alloc_unicodestring(u"spam ἄλφα")
+
expected = u"'spam ἄλφα'"
- if inferior_python_version < (3, 0):
- expected = 'u' + expected
-
- self.assertEqual(type(unicode_string), libpython.PyUnicodeObjectPtr)
- self.assertEqual(self.get_repr(unicode_string), expected)
-
- def test_int(self):
- if inferior_python_version < (3, 0):
- intval = self.pyobject_fromcode('PyInt_FromLong(100)')
- self.assertEqual(type(intval), libpython.PyIntObjectPtr)
- self.assertEqual(self.get_repr(intval), '100')
-
- def test_long(self):
- longval = self.pyobject_fromcode('PyLong_FromLong(200)',
- gdbvar='longval')
- assert gdb.parse_and_eval('$longval->ob_type == &PyLong_Type')
-
- self.assertEqual(type(longval), libpython.PyLongObjectPtr)
- self.assertEqual(self.get_repr(longval), '200')
-
- def test_frame_type(self):
- frame = self.pyobject_fromcode('PyEval_GetFrame()')
-
- self.assertEqual(type(frame), libpython.PyFrameObjectPtr)
+ if inferior_python_version < (3, 0):
+ expected = 'u' + expected
+
+ self.assertEqual(type(unicode_string), libpython.PyUnicodeObjectPtr)
+ self.assertEqual(self.get_repr(unicode_string), expected)
+
+ def test_int(self):
+ if inferior_python_version < (3, 0):
+ intval = self.pyobject_fromcode('PyInt_FromLong(100)')
+ self.assertEqual(type(intval), libpython.PyIntObjectPtr)
+ self.assertEqual(self.get_repr(intval), '100')
+
+ def test_long(self):
+ longval = self.pyobject_fromcode('PyLong_FromLong(200)',
+ gdbvar='longval')
+ assert gdb.parse_and_eval('$longval->ob_type == &PyLong_Type')
+
+ self.assertEqual(type(longval), libpython.PyLongObjectPtr)
+ self.assertEqual(self.get_repr(longval), '200')
+
+ def test_frame_type(self):
+ frame = self.pyobject_fromcode('PyEval_GetFrame()')
+
+ self.assertEqual(type(frame), libpython.PyFrameObjectPtr)