Lichen

internal_tests/branches.py

934:2989aab1b4f7
13 months ago Paul Boddie Renamed the utf8string class to unicode, eliminating the unicode function. This means that the simple case of merely returning an object if it is already a Unicode object no longer occurs when using the unicode callable, but such behaviour might be better supported with more general customised instantiation functionality.
     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