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