cython
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
101
11>>> a.called
122
13>>> a.bar
14'bar'
15>>> a.called
164
17>>> try: a.invalid
18... except AttributeError: pass
19... else: print("NOT RAISED!")
20>>> a.called
216
22"""
23cdef readonly int called
24def __getattribute__(self,n):
25self.called += 1
26if n == 'bar':
27return n
28elif n == 'called':
29return self.called
30else:
31raise AttributeError
32
33
34cdef class just_getattr:
35"""
36>>> a = just_getattr()
37>>> a.called
380
39>>> a.called
400
41>>> a.foo
4210
43>>> a.called
440
45>>> a.bar
46'bar'
47>>> a.called
481
49>>> try: a.invalid
50... except AttributeError: pass
51... else: print("NOT RAISED!")
52>>> a.called
532
54"""
55cdef readonly int called
56cdef readonly int foo
57def __init__(self):
58self.foo = 10
59def __getattr__(self,n):
60self.called += 1
61if n == 'bar':
62return n
63else:
64raise AttributeError
65
66
67cdef class both:
68"""
69>>> a = both()
70>>> (a.called_getattr, a.called_getattribute)
71(0, 2)
72>>> a.foo
7310
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>>> try: a.invalid
81... except AttributeError: pass
82... else: print("NOT RAISED!")
83>>> (a.called_getattr, a.called_getattribute)
84(2, 11)
85"""
86cdef readonly int called_getattribute
87cdef readonly int called_getattr
88cdef readonly int foo
89def __init__(self):
90self.foo = 10
91
92def __getattribute__(self,n):
93self.called_getattribute += 1
94if n == 'foo':
95return self.foo
96elif n == 'called_getattribute':
97return self.called_getattribute
98elif n == 'called_getattr':
99return self.called_getattr
100else:
101raise AttributeError
102
103def __getattr__(self,n):
104self.called_getattr += 1
105if n == 'bar':
106return n
107else:
108raise AttributeError
109