File: test_apiset.py

package info (click to toggle)
pypy3 7.3.11%2Bdfsg-2%2Bdeb12u3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 201,024 kB
  • sloc: python: 1,950,308; ansic: 517,580; sh: 21,417; asm: 14,419; cpp: 4,263; makefile: 4,228; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 11; awk: 4
file content (131 lines) | stat: -rw-r--r-- 4,138 bytes parent folder | download
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import pytest
import operator
from rpython.rtyper.lltypesystem import lltype
from pypy.module._hpy_universal import llapi
from pypy.module._hpy_universal.apiset import APISet

class TestAPISet(object):

    @pytest.fixture
    def api(self):
        return APISet(llapi.cts, is_debug=False)

    def test_parse_signature(self, api):
        sig = 'HPy HPyNumber_Add(HPyContext *ctx, HPy x, HPy y)'
        name, FUNC, ll_errval = api.parse_signature(sig, error_value=None)
        assert name == 'HPyNumber_Add'
        assert FUNC.TO.ARGS == (llapi.HPyContext, llapi.HPy, llapi.HPy)
        assert FUNC.TO.RESULT == llapi.HPy
        assert ll_errval == 0

    def test_func(self, api):
        @api.func('double divide(long a, long b)', error_value=-1.0)
        def divide(space, a, b):
            return float(a)/b
        #
        assert divide(None, 5, 2) == 2.5
        assert api.all_functions == [divide]

    def test_func_with_func_name(self, api):
        def make_binary(name, op):
            @api.func('double func(long a, long b)', func_name=name, error_value=-1.0)
            def func(space, a, b):
                return op(a, b)
            return func
        #
        add = make_binary('add', operator.add)
        sub = make_binary('sub', operator.sub)
        assert add.__name__ == 'add'
        assert sub.__name__ == 'sub'
        assert add(None, 8, 5) == 13
        assert sub(None, 12, 3) == 9
        assert api.all_functions == [add, sub]

    def test_basename(self, api):
        @api.func('void HPyFoo_Bar(void)')
        def HPyFoo_Bar(space):
            return None
        @api.func('void _HPyFoo_Internal(void)')
        def _HPyFoo_Internal(space):
            return None

        assert HPyFoo_Bar.basename == 'Foo_Bar'
        assert _HPyFoo_Internal.basename == 'Foo_Internal'

    def test_llhelper(self, api):
        class FakeState:
            def get_handle_manager(self, *args):
                return 'fake manager'

        class FakeSpace:
            @staticmethod
            def fromcache(cls):
                return FakeState()

        @api.func('double divide(long a, long b)', error_value=-1.0)
        def divide(space, handles, a, b):
            assert space is fakespace
            assert handles == 'fake manager'
            return float(a)/b
        #
        fakespace = FakeSpace()
        lldivide = divide.get_llhelper(fakespace)
        assert lldivide(5, 2) == 2.5

    def test_freeze(self, api):
        @api.func('void foo(void)')
        def foo(space):
            return None
        #
        api._freeze_()
        with pytest.raises(RuntimeError) as exc:
            @api.func('void bar(void)')
            def bar(space):
                return None
        assert 'Too late to call' in str(exc)

    def test_gil_acquire(self, api):
        from rpython.rtyper.debug import FatalError
        class FakeState:
            def get_handle_manager(self, *args):
                return 'fake manager'

        class FakeSpace:
            @staticmethod
            def fromcache(cls):
                return FakeState()

        fakespace = FakeSpace()
        @api.func('void foo(void)')
        def foo(space, handles):
            from rpython.rlib import rgil
            return rgil.am_I_holding_the_GIL()

        llfoo = foo.get_llhelper(fakespace)

        @api.func('void getgil(void)', gil="acquire")
        def getgil(space, handles):
            return None

        llgetgil = getgil.get_llhelper(fakespace)

        @api.func('void dropgil(void)', gil="release")
        def dropgil(space, handles):
            return None

        lldropgil = dropgil.get_llhelper(fakespace)

        # Try to acquire the GIL when it is already held
        with pytest.raises(FatalError) as exc:
            llgetgil()
        assert 'GIL deadlock detected' in str(exc)
        
        # Make sure the GIL is held automatically even if it was released
        lldropgil()
        assert llfoo()

        # Try to release the GIL twice
        with pytest.raises(FatalError) as exc:
            lldropgil()
        assert 'GIL not held' in str(exc)