aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/cython/Cython/Debugger/Tests/test_libpython_in_gdb.py
blob: 8a2b83419b5573bc3d51ecfef93ebf6e8959474b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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 
 
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)