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 fn = f(C, 0) 87 88 try: 89 print fn(2) # fails 90 except UnboundMethodInvocation: 91 print "fn(2): Unbound method is not callable." 92 93 print get_using(fn, c)(2) # 2 94 print get_using(f(C, 0), c)(2) # 2 95 96 try: 97 print g(C, 1) # should fail with an error caused by a guard 98 except TypeError: 99 print "g(C, 1): C is not a suitable argument." 100 101 print g(c, 1) # 1 102 print g(c, 0)(3) # 3 103 104 print h(c, getc) # 1 105 print h(c, 0)(4) # 4 106 107 try: 108 print h(c, getd) # should fail with an error caused by a guard 109 except TypeError: 110 print "h(c, getd): getd provides an unsuitable result." 111 112 try: 113 print h(d, 0)(4) # should fail with an error caused by a test 114 except TypeError: 115 print "h(d, 0): d is not a suitable argument." 116 117 try: 118 print g(c, 1)(5) 119 except TypeError: 120 print "g(c, 1)(5): attempt to invoke an integer result from g."