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