File: test_call.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 (110 lines) | stat: -rw-r--r-- 3,885 bytes parent folder | download | duplicates (2)
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
from .support import HPyTest


class TestCall(HPyTest):
    def argument_combinations(self, **items):
        """ Returns all possible ways of expressing the given items as
            arguments to a function.
        """
        items = list(items.items())
        for i in range(len(items) + 1):
            args = tuple(item[1] for item in items[:i])
            kw = dict(items[i:])
            yield {"args": args, "kw": kw}
            if not args:
                yield {"kw": kw}
            if not kw:
                yield {"args": args}
            if not args and not kw:
                yield {}

    def test_hpy_calltupledict(self):
        import pytest
        mod = self.make_module("""
            HPyDef_METH(call, "call", call_impl, HPyFunc_KEYWORDS)
            static HPy call_impl(HPyContext *ctx, HPy self,
                                 HPy *args, HPy_ssize_t nargs, HPy kw)
            {

                HPy f, result;
                HPy f_args = HPy_NULL;
                HPy f_kw = HPy_NULL;
                HPyTracker ht;
                static const char *kwlist[] = { "f", "args", "kw", NULL };
                if (!HPyArg_ParseKeywords(ctx, &ht, args, nargs, kw, "O|OO",
                                          kwlist, &f, &f_args, &f_kw)) {
                    return HPy_NULL;
                }
                result = HPy_CallTupleDict(ctx, f, f_args, f_kw);
                HPyTracker_Close(ctx, ht);
                return result;
            }
            @EXPORT(call)
            @INIT
        """)

        def f(a, b):
            return a + b

        def g():
            return "this is g"

        # test passing arguments with handles of the correct type --
        # i.e. args is a tuple or a null handle, kw is a dict or a null handle.
        for d in self.argument_combinations(a=1, b=2):
            assert mod.call(f, **d) == 3
        for d in self.argument_combinations(a=1):
            with pytest.raises(TypeError):
                mod.call(f, **d)
        for d in self.argument_combinations():
            with pytest.raises(TypeError):
                mod.call(f, **d)
        for d in self.argument_combinations():
            assert mod.call(g, **d) == "this is g"
        for d in self.argument_combinations(object=2):
            assert mod.call(str, **d) == "2"
        for d in self.argument_combinations():
            with pytest.raises(TypeError):
                mod.call("not callable", **d)
        for d in self.argument_combinations(unknown=2):
            with pytest.raises(TypeError):
                mod.call("not callable", **d)

        # test passing handles of the incorrect type as arguments
        with pytest.raises(TypeError):
            mod.call(f, args=[1, 2])
        with pytest.raises(TypeError):
            mod.call(f, args="string")
        with pytest.raises(TypeError):
            mod.call(f, args=1)
        with pytest.raises(TypeError):
            mod.call(f, args=None)
        with pytest.raises(TypeError):
            mod.call(f, kw=[1, 2])
        with pytest.raises(TypeError):
            mod.call(f, kw="string")
        with pytest.raises(TypeError):
            mod.call(f, kw=1)
        with pytest.raises(TypeError):
            mod.call(f, kw=None)

    def test_hpycallable_check(self):
        mod = self.make_module("""
            HPyDef_METH(f, "f", f_impl, HPyFunc_O)
            static HPy f_impl(HPyContext *ctx, HPy self, HPy arg)
            {
                if (HPyCallable_Check(ctx, arg))
                    return HPy_Dup(ctx, ctx->h_True);
                return HPy_Dup(ctx, ctx->h_False);
            }
            @EXPORT(f)
            @INIT
        """)

        def f():
            return "this is f"

        assert mod.f(f) is True
        assert mod.f(str) is True
        assert mod.f("a") is False
        assert mod.f(3) is False