test_libpython_in_gdb.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # -*- coding: UTF-8 -*-
  2. """
  3. Test libpython.py. This is already partly tested by test_libcython_in_gdb and
  4. Lib/test/test_gdb.py in the Python source. These tests are run in gdb and
  5. called from test_libcython_in_gdb.main()
  6. """
  7. import os
  8. import sys
  9. import gdb
  10. from Cython.Debugger import libcython
  11. from Cython.Debugger import libpython
  12. from . import test_libcython_in_gdb
  13. from .test_libcython_in_gdb import _debug, inferior_python_version
  14. class TestPrettyPrinters(test_libcython_in_gdb.DebugTestCase):
  15. """
  16. Test whether types of Python objects are correctly inferred and that
  17. the right libpython.PySomeTypeObjectPtr classes are instantiated.
  18. Also test whether values are appropriately formatted (don't be too
  19. laborious as Lib/test/test_gdb.py already covers this extensively).
  20. Don't take care of decreffing newly allocated objects as a new
  21. interpreter is started for every test anyway.
  22. """
  23. def setUp(self):
  24. super(TestPrettyPrinters, self).setUp()
  25. self.break_and_run('b = c = d = 0')
  26. def get_pyobject(self, code):
  27. value = gdb.parse_and_eval(code)
  28. assert libpython.pointervalue(value) != 0
  29. return value
  30. def pyobject_fromcode(self, code, gdbvar=None):
  31. if gdbvar is not None:
  32. d = {'varname':gdbvar, 'code':code}
  33. gdb.execute('set $%(varname)s = %(code)s' % d)
  34. code = '$' + gdbvar
  35. return libpython.PyObjectPtr.from_pyobject_ptr(self.get_pyobject(code))
  36. def get_repr(self, pyobject):
  37. return pyobject.get_truncated_repr(libpython.MAX_OUTPUT_LEN)
  38. def alloc_bytestring(self, string, gdbvar=None):
  39. if inferior_python_version < (3, 0):
  40. funcname = 'PyString_FromStringAndSize'
  41. else:
  42. funcname = 'PyBytes_FromStringAndSize'
  43. assert b'"' not in string
  44. # ensure double quotes
  45. code = '(PyObject *) %s("%s", %d)' % (funcname, string.decode('iso8859-1'), len(string))
  46. return self.pyobject_fromcode(code, gdbvar=gdbvar)
  47. def alloc_unicodestring(self, string, gdbvar=None):
  48. postfix = libpython.get_inferior_unicode_postfix()
  49. funcname = 'PyUnicode%s_DecodeUnicodeEscape' % (postfix,)
  50. data = string.encode("unicode_escape").decode('iso8859-1')
  51. return self.pyobject_fromcode(
  52. '(PyObject *) %s("%s", %d, "strict")' % (
  53. funcname, data.replace('"', r'\"').replace('\\', r'\\'), len(data)),
  54. gdbvar=gdbvar)
  55. def test_bytestring(self):
  56. bytestring = self.alloc_bytestring(b"spam")
  57. if inferior_python_version < (3, 0):
  58. bytestring_class = libpython.PyStringObjectPtr
  59. expected = repr(b"spam")
  60. else:
  61. bytestring_class = libpython.PyBytesObjectPtr
  62. expected = "b'spam'"
  63. self.assertEqual(type(bytestring), bytestring_class)
  64. self.assertEqual(self.get_repr(bytestring), expected)
  65. def test_unicode(self):
  66. unicode_string = self.alloc_unicodestring(u"spam ἄλφα")
  67. expected = u"'spam ἄλφα'"
  68. if inferior_python_version < (3, 0):
  69. expected = 'u' + expected
  70. self.assertEqual(type(unicode_string), libpython.PyUnicodeObjectPtr)
  71. self.assertEqual(self.get_repr(unicode_string), expected)
  72. def test_int(self):
  73. if inferior_python_version < (3, 0):
  74. intval = self.pyobject_fromcode('PyInt_FromLong(100)')
  75. self.assertEqual(type(intval), libpython.PyIntObjectPtr)
  76. self.assertEqual(self.get_repr(intval), '100')
  77. def test_long(self):
  78. longval = self.pyobject_fromcode('PyLong_FromLong(200)',
  79. gdbvar='longval')
  80. assert gdb.parse_and_eval('$longval->ob_type == &PyLong_Type')
  81. self.assertEqual(type(longval), libpython.PyLongObjectPtr)
  82. self.assertEqual(self.get_repr(longval), '200')
  83. def test_frame_type(self):
  84. frame = self.pyobject_fromcode('PyEval_GetFrame()')
  85. self.assertEqual(type(frame), libpython.PyFrameObjectPtr)