1# mode: run
2# tag: closures
3cdef class Test:
4    cdef int x
5
6cdef class SelfInClosure(object):
7    cdef Test _t
8    cdef int x
9
10    def plain(self):
11        """
12        >>> o = SelfInClosure()
13        >>> o.plain()
14        1
15        """
16        self.x = 1
17        return self.x
18
19    def closure_method(self):
20        """
21        >>> o = SelfInClosure()
22        >>> o.closure_method()() == o
23        True
24        """
25        def nested():
26            return self
27        return nested
28
29    def closure_method_cdef_attr(self, Test t):
30        """
31        >>> o = SelfInClosure()
32        >>> o.closure_method_cdef_attr(Test())()
33        (1, 2)
34        """
35        t.x = 2
36        self._t = t
37        self.x = 1
38        def nested():
39            return self.x, t.x
40        return nested
41
42    def call_closure_method_cdef_attr_c(self, Test t):
43        """
44        >>> o = SelfInClosure()
45        >>> o.call_closure_method_cdef_attr_c(Test())()
46        (1, 2)
47        """
48        return self.closure_method_cdef_attr_c(t)
49
50    cdef closure_method_cdef_attr_c(self, Test t):
51        t.x = 2
52        self._t = t
53        self.x = 1
54        def nested():
55            return self.x, t.x
56        return nested
57