Lichen

tests/methods_unbound.py

1027:dd0745ab8b8a
5 months ago Paul Boddie Reordered GCC arguments to prevent linking failures. Someone decided to change the GCC invocation or linking semantics at some point, meaning that libraries specified "too early" in the argument list no longer provide the symbols required by the program objects, whereas specifying them at the end of the argument list allows those symbols to be found and obtained.
     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."