1# mode: run
2
3# __getattribute__ and __getattr__ special methods for a single class.
4
5
6cdef class just_getattribute:
7    """
8    >>> a = just_getattribute()
9    >>> a.called
10    1
11    >>> a.called
12    2
13    >>> a.bar
14    'bar'
15    >>> a.called
16    4
17    >>> a.invalid
18    Traceback (most recent call last):
19    AttributeError
20    >>> a.called
21    6
22    """
23    cdef readonly int called
24    def __getattribute__(self,n):
25        self.called += 1
26        if n == 'bar':
27            return n
28        elif n == 'called':
29            return self.called
30        else:
31            raise AttributeError
32
33
34cdef class just_getattr:
35    """
36    >>> a = just_getattr()
37    >>> a.called
38    0
39    >>> a.called
40    0
41    >>> a.foo
42    10
43    >>> a.called
44    0
45    >>> a.bar
46    'bar'
47    >>> a.called
48    1
49    >>> a.invalid
50    Traceback (most recent call last):
51    AttributeError
52    >>> a.called
53    2
54    """
55    cdef readonly int called
56    cdef readonly int foo
57    def __init__(self):
58        self.foo = 10
59    def __getattr__(self,n):
60        self.called += 1
61        if n == 'bar':
62            return n
63        else:
64            raise AttributeError
65
66
67cdef class both:
68    """
69    >>> a = both()
70    >>> (a.called_getattr, a.called_getattribute)
71    (0, 2)
72    >>> a.foo
73    10
74    >>> (a.called_getattr, a.called_getattribute)
75    (0, 5)
76    >>> a.bar
77    'bar'
78    >>> (a.called_getattr, a.called_getattribute)
79    (1, 8)
80    >>> a.invalid
81    Traceback (most recent call last):
82    AttributeError
83    >>> (a.called_getattr, a.called_getattribute)
84    (2, 11)
85    """
86    cdef readonly int called_getattribute
87    cdef readonly int called_getattr
88    cdef readonly int foo
89    def __init__(self):
90        self.foo = 10
91
92    def __getattribute__(self,n):
93        self.called_getattribute += 1
94        if n == 'foo':
95            return self.foo
96        elif n == 'called_getattribute':
97            return self.called_getattribute
98        elif n == 'called_getattr':
99            return self.called_getattr
100        else:
101            raise AttributeError
102
103    def __getattr__(self,n):
104        self.called_getattr += 1
105        if n == 'bar':
106            return n
107        else:
108            raise AttributeError
109