Lichen

internal_tests/branches.py

1034:2df62f615d0c
5 months ago Paul Boddie Avoid creating zero-length temporary arrays. value-replacement
     1 #!/usr/bin/env python     2      3 import branching     4      5 def simple_usage(assignment):     6     d = {}     7     for name, usages in assignment.get_usage().items():     8         l = []     9         for usage in usages:    10             if not usage:    11                 l.append(usage)    12             else:    13                 l2 = []    14                 for t in usage:    15                     attrname, invocation, assignment = t    16                     l2.append(attrname)    17                 l.append(tuple(l2))    18         d[name] = set(l)    19     return d    20     21 names = []    22     23 # Equivalent to...    24 #    25 # y = ...    26 # while cond0:    27 #   if cond1:    28 #     y.a1    29 #   elif cond2:    30 #     y = ...    31 #     y.a2    32 #   else:    33 #     y.a3    34     35 bt = branching.BranchTracker()    36 y1 = bt.assign_names(["y"])    37 bt.new_branchpoint(True)            # begin    38 bt.new_branch(True)                 # while ...    39 bt.new_branchpoint()                # begin    40 bt.new_branch()                     # if ...    41 ya1 = bt.use_attribute("y", "a1")    42 bt.shelve_branch()    43 bt.new_branch()                     # elif ...    44 y2 = bt.assign_names(["y"])    45 ya2 = bt.use_attribute("y", "a2")    46 bt.shelve_branch()    47 bt.new_branch()                     # else    48 ya1 = bt.use_attribute("y", "a3")    49 bt.shelve_branch()    50 bt.merge_branches()                 # end    51 bt.resume_continuing_branches()    52 bt.shelve_branch(True)    53 bt.new_branch()                     # (null)    54 bt.shelve_branch()    55 bt.merge_branches()                 # end    56 bt.resume_broken_branches()    57     58 print simple_usage(y1) == \    59     {'y' : set([(), ('a1',), ('a3',)])}, \    60     simple_usage(y1)    61 print simple_usage(y2) == \    62     {'y' : set([('a2',)])}, \    63     simple_usage(y2)    64 print bt.get_assignment_positions_for_branches("y", ya1) == [0, 1], \    65     bt.get_assignment_positions_for_branches("y", ya1)    66 print bt.get_assignment_positions_for_branches("y", ya2) == [1], \    67     bt.get_assignment_positions_for_branches("y", ya2)    68 names.append(bt.assignments["y"])    69     70 # Equivalent to...    71 #    72 # a = ...    73 # a.p    74 # if ...:    75 #   a = ...    76 #   a.x    77 # else:    78 #   ...    79 # a.q    80     81 bt = branching.BranchTracker()    82 a1 = bt.assign_names(["a"])    83 bt.use_attribute("a", "p")    84 bt.new_branchpoint()                # begin    85 bt.new_branch()                     # if ...    86 a2 = bt.assign_names(["a"])         # a = ...    87 ax = bt.use_attribute("a", "x")    88 bt.shelve_branch()    89 bt.new_branch()                     # else    90 bt.shelve_branch()    91 bt.merge_branches()                 # end    92 aq = bt.use_attribute("a", "q")    93     94 print simple_usage(a1) == \    95     {'a' : set([('p',), ('p', 'q')])}, \    96     simple_usage(a1)    97 print simple_usage(a2) == \    98     {'a' : set([('q', 'x')])}, \    99     simple_usage(a2)   100 print bt.get_assignment_positions_for_branches("a", ax) == [1], \   101     bt.get_assignment_positions_for_branches("a", ax)   102 print bt.get_assignment_positions_for_branches("a", aq) == [0, 1], \   103     bt.get_assignment_positions_for_branches("a", aq)   104 names.append(bt.assignments["a"])   105    106 # Equivalent to...   107 #   108 # a = ...   109 # a.p   110 # if ...:   111 #   a.x   112 # elif ...:   113 #   a.y; a.z   114 # else:   115 #   ...   116 # a.q   117    118 bt = branching.BranchTracker()   119 a = bt.assign_names(["a"])   120 bt.use_attribute("a", "p")   121 bt.new_branchpoint()                # begin   122 bt.new_branch()                     # if ...   123 ax = bt.use_attribute("a", "x")   124 bt.shelve_branch()   125 bt.new_branch()                     # elif ...   126 ay = bt.use_attribute("a", "y")   127 az = bt.use_attribute("a", "z")   128 bt.shelve_branch()   129 bt.new_branch()                     # else   130 bt.shelve_branch()   131 bt.merge_branches()                 # end   132 bt.use_attribute("a", "q")   133    134 print simple_usage(a) == \   135     {'a' : set([('p', 'q'), ('p', 'q', 'x'), ('p', 'q', 'y', 'z')])}, \   136     simple_usage(a)   137 print bt.get_assignment_positions_for_branches("a", ax) == [0], \   138     bt.get_assignment_positions_for_branches("a", ax)   139 print bt.get_assignment_positions_for_branches("a", ay) == [0], \   140     bt.get_assignment_positions_for_branches("a", ay)   141 print bt.get_assignment_positions_for_branches("a", az) == [0], \   142     bt.get_assignment_positions_for_branches("a", az)   143 names.append(bt.assignments["a"])   144    145 # Equivalent to...   146 #   147 # a = ...   148 # a.p   149 # while ...:   150 #   a.x   151 # a.q   152    153 bt = branching.BranchTracker()   154 a = bt.assign_names(["a"])   155 bt.use_attribute("a", "p")   156 bt.new_branchpoint(True)            # begin   157 bt.new_branch(True)                 # while ...   158 ax = bt.use_attribute("a", "x")   159 bt.resume_continuing_branches()   160 bt.shelve_branch(True)   161 bt.new_branch()                     # (null)   162 bt.shelve_branch()   163 bt.merge_branches()                 # end   164 bt.resume_broken_branches()   165 bt.use_attribute("a", "q")   166    167 print simple_usage(a) == \   168     {'a' : set([('p', 'q'), ('p', 'q', 'x')])}, simple_usage(a)   169 print bt.get_assignment_positions_for_branches("a", ax) == [0], \   170     bt.get_assignment_positions_for_branches("a", ax)   171 names.append(bt.assignments["a"])   172    173 # Equivalent to...   174 #   175 # a = ...   176 # a.p   177 # while ...:   178 #   if ...:   179 #     a.x   180 #   else ...:   181 #     a.y   182 # a.q   183    184 bt = branching.BranchTracker()   185 a = bt.assign_names(["a"])   186 bt.use_attribute("a", "p")   187 bt.new_branchpoint(True)            # begin   188 bt.new_branch(True)                 # while ...   189 bt.new_branchpoint()                # begin   190 bt.new_branch()                     # if ...   191 ax = bt.use_attribute("a", "x")   192 bt.shelve_branch()   193 bt.new_branch()   194 ay = bt.use_attribute("a", "y")   195 bt.shelve_branch()   196 bt.merge_branches()                 # end   197 bt.resume_continuing_branches()   198 bt.shelve_branch(True)   199 bt.new_branch()                     # (null)   200 bt.shelve_branch()   201 bt.merge_branches()                 # end   202 bt.resume_broken_branches()   203 bt.use_attribute("a", "q")   204    205 print simple_usage(a) == \   206     {'a' : set([('p', 'q'), ('p', 'q', 'x'), ('p', 'q', 'y')])}, \   207     simple_usage(a)   208 print bt.get_assignment_positions_for_branches("a", ax) == [0], \   209     bt.get_assignment_positions_for_branches("a", ax)   210 print bt.get_assignment_positions_for_branches("a", ay) == [0], \   211     bt.get_assignment_positions_for_branches("a", ay)   212 names.append(bt.assignments["a"])   213    214 # Equivalent to...   215 #   216 # a = ...   217 # a.p   218 # while ...:   219 #   if ...:   220 #     a = ...   221 #     a.x   222 #   else ...:   223 #     a.y   224 # a.q   225    226 bt = branching.BranchTracker()   227 a1 = bt.assign_names(["a"])   228 bt.use_attribute("a", "p")   229 bt.new_branchpoint(True)            # begin   230 bt.new_branch(True)                 # while ...   231 bt.new_branchpoint()                # begin   232 bt.new_branch()                     # if ...   233 a2 = bt.assign_names(["a"])         # a = ...   234 ax = bt.use_attribute("a", "x")   235 bt.shelve_branch()   236 bt.new_branch()   237 ay = bt.use_attribute("a", "y")   238 bt.shelve_branch()   239 bt.merge_branches()                 # end   240 bt.resume_continuing_branches()   241 bt.shelve_branch(True)   242 bt.new_branch()                     # (null)   243 bt.shelve_branch()   244 bt.merge_branches()                 # end   245 bt.resume_broken_branches()   246 bt.use_attribute("a", "q")   247    248 print simple_usage(a1) == \   249     {'a' : set([('p', 'q'), ('p', 'q', 'y'), ('p',)])}, simple_usage(a1)   250 print simple_usage(a2) == \   251     {'a' : set([('q', 'x')])}, simple_usage(a2)   252 print bt.get_assignment_positions_for_branches("a", ax) == [1], \   253     bt.get_assignment_positions_for_branches("a", ax)   254 print bt.get_assignment_positions_for_branches("a", ay) == [0, 1], \   255     bt.get_assignment_positions_for_branches("a", ay)   256 names.append(bt.assignments["a"])   257    258 # Equivalent to...   259 #   260 # a = ...   261 # a.p   262 # while ...:   263 #   if ...:   264 #     a.y   265 #   else ...:   266 #     a = ...   267 #     a.x   268 # a.q   269    270 bt = branching.BranchTracker()   271 a1 = bt.assign_names(["a"])   272 bt.use_attribute("a", "p")   273 bt.new_branchpoint(True)            # begin   274 bt.new_branch(True)                 # while ...   275 bt.new_branchpoint()                # begin   276 bt.new_branch()                     # if ...   277 ay = bt.use_attribute("a", "y")   278 bt.shelve_branch()   279 bt.new_branch()   280 a2 = bt.assign_names(["a"])         # a = ...   281 ax = bt.use_attribute("a", "x")   282 bt.shelve_branch()   283 bt.merge_branches()                 # end   284 bt.resume_continuing_branches()   285 bt.shelve_branch(True)   286 bt.new_branch()                     # (null)   287 bt.shelve_branch()   288 bt.merge_branches()                 # end   289 bt.resume_broken_branches()   290 bt.use_attribute("a", "q")   291    292 print simple_usage(a1) == \   293     {'a' : set([('p', 'q'), ('p', 'q', 'y'), ('p',)])}, simple_usage(a1)   294 print simple_usage(a2) == \   295     {'a' : set([('q', 'x')])}, simple_usage(a2)   296 print bt.get_assignment_positions_for_branches("a", ax) == [1], \   297     bt.get_assignment_positions_for_branches("a", ax)   298 print bt.get_assignment_positions_for_branches("a", ay) == [0, 1], \   299     bt.get_assignment_positions_for_branches("a", ay)   300 names.append(bt.assignments["a"])   301    302 # Equivalent to...   303 #   304 # a = ...   305 # a.p   306 # while ...:   307 #   a = ...   308 #   a.x   309 # a.q   310    311 bt = branching.BranchTracker()   312 a1 = bt.assign_names(["a"])   313 ap = bt.use_attribute("a", "p")   314 bt.new_branchpoint(True)            # begin   315 bt.new_branch(True)                 # while ...   316 a2 = bt.assign_names(["a"])         # a = ...   317 ax = bt.use_attribute("a", "x")   318 bt.resume_continuing_branches()   319 bt.shelve_branch(True)   320 bt.new_branch()                     # (null)   321 bt.shelve_branch()   322 bt.merge_branches()                 # end   323 bt.resume_broken_branches()   324 aq = bt.use_attribute("a", "q")   325    326 print simple_usage(a1) == \   327     {'a' : set([('p', 'q'), ('p',)])}, simple_usage(a1)   328 print simple_usage(a2) == \   329     {'a' : set([('q', 'x')])}, simple_usage(a2)   330 print bt.get_assignment_positions_for_branches("a", ax) == [1], \   331     bt.get_assignment_positions_for_branches("a", ax)   332 print bt.get_assignment_positions_for_branches("a", ap) == [0], \   333     bt.get_assignment_positions_for_branches("a", ap)   334 print bt.get_assignment_positions_for_branches("a", aq) == [0, 1], \   335     bt.get_assignment_positions_for_branches("a", aq)   336 names.append(bt.assignments["a"])   337    338 # Equivalent to...   339 #   340 # a = ...   341 # a.p   342 # while ...:   343 #   if ...:   344 #     break   345 #   a.q   346 # a.r   347    348 bt = branching.BranchTracker()   349 a1 = bt.assign_names(["a"])   350 bt.use_attribute("a", "p")   351 bt.new_branchpoint(True)            # begin   352 bt.new_branch(True)                 # while ...   353 bt.new_branchpoint()                # begin   354 bt.new_branch()                     # if ...   355 bt.suspend_broken_branch()          # break   356 bt.shelve_branch()   357 bt.new_branch()                     # (null)   358 bt.shelve_branch()   359 bt.merge_branches()                 # end   360 bt.use_attribute("a", "q")   361 bt.resume_continuing_branches()   362 bt.shelve_branch(True)   363 bt.merge_branches()                 # end   364 bt.resume_broken_branches()   365 bt.use_attribute("a", "r")   366    367 print simple_usage(a1) == \   368     {'a' : set([('p', 'q', 'r'), ('p', 'r')])}, simple_usage(a1)   369 names.append(bt.assignments["a"])   370    371 # Equivalent to...   372 #   373 # a = ...   374 # a.p and a.q and a.r   375    376 bt = branching.BranchTracker()   377 a1 = bt.assign_names(["a"])   378 bt.new_branchpoint()                # begin   379 bt.new_branch()   380 bt.use_attribute("a", "p")   381 bt.new_branchpoint()                # begin   382 bt.new_branch()   383 bt.use_attribute("a", "q")   384 bt.new_branchpoint()                # begin   385 bt.new_branch()   386 bt.use_attribute("a", "r")   387 bt.shelve_branch()   388 bt.new_branch()                     # (null)   389 bt.shelve_branch()   390 bt.merge_branches()                 # end   391 bt.shelve_branch()   392 bt.new_branch()                     # (null)   393 bt.shelve_branch()   394 bt.merge_branches()                 # end   395 bt.shelve_branch()   396 bt.merge_branches()                 # end   397    398 print simple_usage(a1) == \   399     {'a' : set([('p', 'q', 'r'), ('p', 'q'), ('p',)])}, simple_usage(a1)   400 names.append(bt.assignments["a"])   401    402 # Equivalent to...   403 #   404 # a = ...   405 # if ...:   406 #   a.p   407 #   return   408 # a.q   409    410 bt = branching.BranchTracker()   411 a1 = bt.assign_names(["a"])   412 bt.new_branchpoint()                # begin   413 bt.new_branch()                     # if ...   414 bt.use_attribute("a", "p")   415 bt.abandon_returning_branch()   416 bt.shelve_branch()   417 bt.new_branch()                     # (null)   418 bt.shelve_branch()   419 bt.merge_branches()                 # end   420 bt.use_attribute("a", "q")   421    422 print simple_usage(a1) == \   423     {'a' : set([('p',), ('q',)])}, simple_usage(a1)   424 names.append(bt.assignments["a"])   425    426 # Equivalent to...   427 #   428 # a = ...   429 # try:   430 #   if ...:   431 #     a.p   432 #     return   433 #   a.q   434 # except:   435 #   a.r   436    437 bt = branching.BranchTracker()   438 a1 = bt.assign_names(["a"])   439 bt.new_branchpoint()                # begin (try)   440 bt.new_branchpoint()                # begin   441 bt.new_branch()                     # if ...   442 bt.use_attribute("a", "p")   443 bt.abandon_returning_branch()   444 bt.shelve_branch()                  # ... if   445 bt.new_branch()                     # (null)   446 bt.shelve_branch()   447 bt.merge_branches()                 # end   448 bt.use_attribute("a", "q")   449 bt.resume_abandoned_branches()      # except   450 bt.use_attribute("a", "r")   451 bt.shelve_branch()   452 bt.merge_branches()                 # end   453    454 print simple_usage(a1) == \   455     {'a' : set([('p',), ('q', 'r')])}, simple_usage(a1)   456 names.append(bt.assignments["a"])   457    458 # Equivalent to...   459 #   460 # a = ...   461 # if ...:   462 #   a.p   463 # a = ...   464 # if ...:   465 #   a.q   466    467 bt = branching.BranchTracker()   468 a1 = bt.assign_names(["a"])   469 bt.new_branchpoint()                # begin   470 bt.new_branch()                     # if ...   471 ap = bt.use_attribute("a", "p")   472 bt.abandon_branch()   473 bt.shelve_branch()                  # ... if   474 bt.new_branch()                     # (null)   475 bt.shelve_branch()   476 bt.merge_branches()                 # end   477 a2 = bt.assign_names(["a"])   478 bt.new_branchpoint()                # begin   479 bt.new_branch()                     # if ...   480 aq = bt.use_attribute("a", "q")   481 bt.abandon_branch()   482 bt.shelve_branch()                  # ... if   483 bt.new_branch()                     # (null)   484 bt.shelve_branch()   485 bt.merge_branches()                 # end   486    487 print simple_usage(a1) == \   488     {'a' : set([('p',), ()])}, simple_usage(a1)   489 print simple_usage(a2) == \   490     {'a' : set([('q',), ()])}, simple_usage(a2)   491 print bt.get_assignment_positions_for_branches("a", ap) == [0], \   492     bt.get_assignment_positions_for_branches("a", ap)   493 print bt.get_assignment_positions_for_branches("a", aq) == [1], \   494     bt.get_assignment_positions_for_branches("a", aq)   495 names.append(bt.assignments["a"])   496    497 # Equivalent to...   498 #   499 # a = {}   500 # a.p   501 # if ...:   502 #   a = ...   503 #   a.x   504 # else:   505 #   ...   506 # a.q   507    508 bt = branching.BranchTracker()   509 a1 = bt.assign_names(["a"], ["<instance>:__builtins__.dict.dict"])   510 ap = bt.use_attribute("a", "p")   511 bt.new_branchpoint()                # begin   512 bt.new_branch()                     # if ...   513 a2 = bt.assign_names(["a"])         # a = ...   514 ax = bt.use_attribute("a", "x")   515 bt.shelve_branch()   516 bt.new_branch()                     # else   517 bt.shelve_branch()   518 bt.merge_branches()                 # end   519 aq = bt.use_attribute("a", "q")   520    521 print simple_usage(a1) == \   522     {'a' : set([('p',), ('p', 'q')])}, \   523     simple_usage(a1)   524 print simple_usage(a2) == \   525     {'a' : set([('q', 'x')])}, \   526     simple_usage(a2)   527 print bt.get_assignment_positions_for_branches("a", ap) == [0], \   528     bt.get_assignment_positions_for_branches("a", ap)   529 print bt.get_assignment_positions_for_branches("a", ax) == [1], \   530     bt.get_assignment_positions_for_branches("a", ax)   531 print bt.get_assignment_positions_for_branches("a", aq) == [0, 1], \   532     bt.get_assignment_positions_for_branches("a", aq)   533 names.append(bt.assignments["a"])   534    535 # Equivalent to...   536 #   537 # if ...:   538 #   a = ...   539 #   a.x   540 # else:   541 #   ...   542 # a.q   543    544 bt = branching.BranchTracker()   545 bt.new_branchpoint()                # begin   546 bt.new_branch()                     # if ...   547 a1 = bt.assign_names(["a"])         # a = ...   548 ax = bt.use_attribute("a", "x")   549 bt.shelve_branch()   550 bt.new_branch()                     # else   551 bt.shelve_branch()   552 bt.merge_branches()                 # end   553 aq = bt.use_attribute("a", "q")   554    555 print simple_usage(a1) == \   556     {'a' : set([('q', 'x')])}, \   557     simple_usage(a1)   558 print bt.get_assignment_positions_for_branches("a", aq) == [None, 0], \   559     bt.get_assignment_positions_for_branches("a", aq)   560 names.append(bt.assignments["a"])   561    562 # Equivalent to...   563 #   564 # if ...:   565 #   a = ...   566 #   return   567 # a.q   568    569 bt = branching.BranchTracker()   570 bt.new_branchpoint()                # begin   571 bt.new_branch()                     # if ...   572 a1 = bt.assign_names(["a"])   573 bt.abandon_returning_branch()   574 bt.shelve_branch()   575 bt.new_branch()                     # (null)   576 bt.shelve_branch()   577 bt.merge_branches()                 # end   578 aq = bt.use_attribute("a", "q")   579    580 print simple_usage(a1) == \   581     {'a' : set([()])}, simple_usage(a1)   582 print bt.get_assignment_positions_for_branches("a", aq) == [None], \   583     bt.get_assignment_positions_for_branches("a", aq)   584 names.append(bt.assignments["a"])   585    586 # Equivalent to...   587 #   588 # a = ...   589 # try:   590 #   if ...:   591 #     a.p   592 #     return   593 #   a.q   594 # finally:   595 #   a.r   596    597 bt = branching.BranchTracker()   598 a1 = bt.assign_names(["a"])   599 bt.new_branchpoint()                # begin   600 bt.new_branch()                     # if ...   601 bt.use_attribute("a", "p")   602 bt.abandon_returning_branch()   603 bt.shelve_branch()                  # ... if   604 bt.new_branch()                     # (null)   605 bt.shelve_branch()   606 bt.merge_branches()                 # end   607 bt.use_attribute("a", "q")   608 branches = bt.resume_all_abandoned_branches()   609 bt.use_attribute("a", "r")   610 bt.restore_active_branches(branches)   611    612 print simple_usage(a1) == \   613     {'a' : set([('p', 'r'), ('q', 'r')])}, simple_usage(a1)   614 names.append(bt.assignments["a"])   615    616 # Equivalent to...   617 #   618 # a = ...   619 # try:   620 #   if ...:   621 #     a = ...   622 #     a.p   623 #     return   624 #   a.q   625 # finally:   626 #   a.r   627    628 bt = branching.BranchTracker()   629 a1 = bt.assign_names(["a"])   630 bt.new_branchpoint()                # begin   631 bt.new_branch()                     # if ...   632 a2 = bt.assign_names(["a"])   633 bt.use_attribute("a", "p")   634 bt.abandon_returning_branch()   635 bt.shelve_branch()                  # ... if   636 bt.new_branch()                     # (null)   637 bt.shelve_branch()   638 bt.merge_branches()                 # end   639 aq = bt.use_attribute("a", "q")   640 branches = bt.resume_all_abandoned_branches()   641 ar = bt.use_attribute("a", "r")   642 bt.restore_active_branches(branches)   643    644 print simple_usage(a1) == \   645     {'a' : set([(), ('q', 'r')])}, simple_usage(a1)   646 print simple_usage(a2) == \   647     {'a' : set([('p', 'r')])}, simple_usage(a2)   648 print bt.get_assignment_positions_for_branches("a", ar) == [0, 1], \   649     bt.get_assignment_positions_for_branches("a", ar)   650 names.append(bt.assignments["a"])   651    652 # Equivalent to...   653 #   654 # a = ...   655 # try:   656 #   if ...:   657 #     a = ...   658 #     a.p   659 #     return   660 #   a.q   661 # except:   662 #   a.r   663    664 bt = branching.BranchTracker()   665 a1 = bt.assign_names(["a"])   666 bt.new_branchpoint()                # begin (try)   667 bt.new_branchpoint()                # begin   668 bt.new_branch()                     # if ...   669 a2 = bt.assign_names(["a"])   670 bt.use_attribute("a", "p")   671 bt.abandon_returning_branch()   672 bt.shelve_branch()                  # ... if   673 bt.new_branch()                     # (null)   674 bt.shelve_branch()   675 bt.merge_branches()                 # end   676 bt.use_attribute("a", "q")   677 bt.resume_abandoned_branches()      # except   678 ar = bt.use_attribute("a", "r")   679 bt.shelve_branch()   680 bt.merge_branches()                 # end   681    682 print simple_usage(a1) == \   683     {'a' : set([(), ('q', 'r')])}, simple_usage(a1)   684 print simple_usage(a2) == \   685     {'a' : set([('p',)])}, simple_usage(a2)   686 print bt.get_assignment_positions_for_branches("a", ar) == [0, 1], \   687     bt.get_assignment_positions_for_branches("a", ar)   688 names.append(bt.assignments["a"])   689    690 # This demonstrates why the assignment in a "for" loop construct must appear   691 # outside the inner "try" body: null usage escapes the loop via the exception   692 # handler and the raise statement, even though the assignment would only be   693 # valid otherwise.   694    695 # Equivalent to...   696 #   697 # try:   698 #   while ...:   699 #     try:   700 #       a = ...   701 #     except:   702 #       raise ...   703 #     a.p   704 # except:   705 #   pass   706    707 bt = branching.BranchTracker()   708 bt.new_branchpoint()                # begin (try)   709 bt.new_branchpoint(True)            # begin (while)   710 bt.new_branch(True)                 # while ...   711 bt.new_branchpoint()                # begin (try)   712 a = bt.assign_names(["a"])   713 bt.resume_abandoned_branches()      # except   714 bt.abandon_branch()                 # raise   715 bt.shelve_branch()   716 bt.new_branch()                     # (null)   717 bt.shelve_branch()   718 bt.merge_branches()                 # end (try)   719 ap = bt.use_attribute("a", "p")   720 bt.resume_continuing_branches()   721 bt.shelve_branch(True)   722 bt.new_branch()                     # (null)   723 bt.shelve_branch()   724 bt.merge_branches()                 # end (while)   725 bt.resume_broken_branches()   726 bt.resume_abandoned_branches()      # except   727 bt.shelve_branch()   728 bt.new_branch()                     # (null)   729 bt.shelve_branch()   730 bt.merge_branches()                 # end (try)   731    732 print simple_usage(a) == \   733     {'a' : set([('p',), ()])}, simple_usage(a)   734 print bt.get_assignment_positions_for_branches("a", ap) == [0], \   735     bt.get_assignment_positions_for_branches("a", ap)   736 names.append(bt.assignments["a"])   737    738 # Equivalent to...   739 #   740 # b = ...   741 # while ...:   742 #   a = ...   743 #   a.p   744    745 bt = branching.BranchTracker()   746 bt.new_branchpoint(True)            # begin   747 b = bt.assign_names(["b"])   748 bt.new_branch(True)                 # while ...   749 a = bt.assign_names(["a"])   750 ap = bt.use_attribute("a", "p")   751 bt.resume_continuing_branches()   752 bt.shelve_branch(True)   753 bt.new_branch()                     # (null)   754 bt.shelve_branch()   755 bt.merge_branches()                 # end   756    757 print simple_usage(a) == \   758     {'a' : set([('p',)])}, simple_usage(a)   759 print bt.get_assignment_positions_for_branches("a", ap) == [0], \   760     bt.get_assignment_positions_for_branches("a", ap)   761 names.append(bt.assignments["a"])   762    763 # vim: tabstop=4 expandtab shiftwidth=4