Lichen

tests/chain.py

360:209dc7a270fd
2016-12-09 Paul Boddie Added support for dynamic attribute access using getattr and hasattr, employing a special attribute on strings to hold the object table code and position for any attribute having the same name as the represented string.
     1 class C:     2     class D:     3         class E:     4             def m(self, x):     5                 self.x = x     6                 l = self.x.__len__     7                 s = self.o     8                 return self.o.__len__     9             n = 123    10             o = "123"    11     12         p = "456"    13         q = 789    14     15         class F(E):    16             def r(self, y):    17                 s = self.o    18                 C.D.F.t = 234    19                 return self.o.__len__    20             t = 123    21             def u(self):    22                 return self.o    23             def v(self):    24                 return self.u().__len__    25     26 def static():    27     c = C    28     d = C.D    29     e = C.D.E    30     f = C.D.E.m    31     g = C.D.E.n    32     h = C.D.p    33     34     print c                                 # __main__.C    35     print d                                 # __main__.C.D    36     print e                                 # __main__.C.D.E    37     print f                                 # __main__.C.D.E.m    38     print g                                 # 123    39     print h                                 # "456"    40     41 def static_via_constant():    42     i = C.D.p.__len__    43     44     print i                                 # __builtins__.str.basestring.__len__    45     46 def assign():    47     C.D.q = 987    48     49 def indirect():    50     e = C.D.E    51     inst = e()    52     method = inst.m    53     return method("5")    54     55 def broken():    56     inst2 = C.D.F()    57     l = inst2.u().__len__    58     return l    59     60 static()    61 static_via_constant()    62 assign()    63 print indirect()                            # __builtins__.str.basestring.__len__    64 print indirect()()                          # 3    65 print broken()                              # __builtins__.str.basestring.__len__    66 print broken()()                            # 3    67     68 print C.D.q                                 # 987    69     70 # Static chains.    71     72 c = C    73 d = C.D    74 e = C.D.E    75 f = C.D.E.m    76 g = C.D.E.n    77 h = C.D.p    78     79 print c                                     # __main__.C    80 print d                                     # __main__.C.D    81 print e                                     # __main__.C.D.E    82 print f                                     # __main__.C.D.E.m    83 print g                                     # 123    84 print h                                     # "456"    85     86 # Static via constant.    87     88 i = C.D.p.__len__    89     90 print i                                     # __builtins__.str.basestring.__len__    91 print i()                                   # 3    92     93 # Static assignment.    94     95 C.D.q = 654    96     97 print C.D.q                                 # 654    98     99 # Indirect accesses.   100    101 inst = e()   102 method = inst.m   103 print method("5")                           # __builtins__.str.basestring.__len__   104 print method("5")()                         # 3   105    106 # Broken chains.   107    108 inst2 = C.D.F()   109 l = inst2.u().__len__   110 print l                                     # __builtins__.str.basestring.__len__   111 print l()                                   # 3