123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- # -*- 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'
- assert b'"' not in string
- # 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()
- funcname = 'PyUnicode%s_DecodeUnicodeEscape' % (postfix,)
- data = string.encode("unicode_escape").decode('iso8859-1')
- return self.pyobject_fromcode(
- '(PyObject *) %s("%s", %d, "strict")' % (
- funcname, data.replace('"', r'\"').replace('\\', r'\\'), len(data)),
- gdbvar=gdbvar)
- def test_bytestring(self):
- bytestring = self.alloc_bytestring(b"spam")
- 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 ἄλφα")
- 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)
|