1 class C: 2 3 "Class providing class and instance attributes." 4 5 def __init__(self): 6 self.a = 1 7 8 def m(self, x): 9 return x 10 11 class D: 12 13 "An alternative class." 14 15 pass 16 17 def getc(): 18 19 "Return an instance of C to test object suitability." 20 21 return C() 22 23 def getd(): 24 25 "Return an instance of D to test object suitability." 26 27 return D() 28 29 def f(obj, i): 30 31 """ 32 Obtain an attribute on 'obj', performing an operation depending on 'i'. 33 This tests attribute access and invocation. 34 """ 35 36 if i: 37 return obj.m(i) # should cause access to an unbound method 38 else: 39 return obj.m 40 41 def g(obj, i): 42 43 """ 44 Obtain an attribute on 'obj', performing an operation depending on 'i'. 45 This tests attribute access and invocation, restricting 'obj' using a guard. 46 """ 47 48 obj.a # only provided by instances of C 49 if i: 50 return obj.m(i) # should use the method directly since obj is an instance 51 else: 52 return obj.m 53 54 def h(obj, fn): 55 56 """ 57 Obtain an attribute on 'obj', performing an operation depending on 'fn'. 58 This tests attribute access and invocation, restricting 'obj' using a guard 59 on a re-assignment of the name. 60 """ 61 62 if fn: 63 obj = fn() 64 obj.a # only provided by instances of C 65 return obj.m(1) 66 else: 67 return obj.m 68 69 # Main program. 70 71 c = C() 72 d = D() 73 74 try: 75 print f(C, 1) # fails 76 except UnboundMethodInvocation: 77 print "f(C, 1): Unbound method is not callable." 78 79 print f(c, 1) # 1 80 81 try: 82 print f(d, 1) # should fail with an error caused by a guard 83 except TypeError: 84 print "f(d, 1): d is not a suitable argument." 85 86 # Get an unbound method, C.m. 87 88 fn = f(C, 0) 89 90 try: 91 print fn(2) # fails 92 except UnboundMethodInvocation: 93 print "fn(2): Unbound method is not callable." 94 95 print get_using(fn, c)(2) # 2 96 97 # Repeat with fn re-evaluated. 98 99 print get_using(f(C, 0), c)(2) # 2 100 101 try: 102 print g(C, 1) # should fail with an error caused by a guard 103 except TypeError: 104 print "g(C, 1): C is not a suitable argument." 105 106 print g(c, 1) # 1 107 print g(c, 0)(3) # 3 108 109 print h(c, getc) # 1 110 print h(c, 0)(4) # 4 111 112 try: 113 print h(c, getd) # should fail with an error caused by a guard 114 except TypeError: 115 print "h(c, getd): getd provides an unsuitable result." 116 117 try: 118 print h(d, 0)(4) # should fail with an error caused by a test 119 except TypeError: 120 print "h(d, 0): d is not a suitable argument." 121 122 try: 123 print g(c, 1)(5) 124 except TypeError: 125 print "g(c, 1)(5): attempt to invoke an integer result from g."