Rev 4102: (robertc) Refactor profiling exception handling support to clear in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue Mar 10 03:35:27 GMT 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 4102
revision-id: pqm at pqm.ubuntu.com-20090310033520-f2ynw0fprjw433m2
parent: pqm at pqm.ubuntu.com-20090310024432-0g561n9wf23vph9f
parent: robertc at robertcollins.net-20090310015146-c2hbo20adx7tarc5
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2009-03-10 03:35:20 +0000
message:
  (robertc) Refactor profiling exception handling support to clear
  	layers up and provide the same support for coverage and
  	non-lsprof profiling. (Robert Collins)
modified:
  bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
  bzrlib/lsprof.py               lsprof.py-20051208071030-833790916798ceed
    ------------------------------------------------------------
    revno: 4084.6.3
    revision-id: robertc at robertcollins.net-20090310015146-c2hbo20adx7tarc5
    parent: robertc at robertcollins.net-20090310003511-pvtygbimxywwton0
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: integration
    timestamp: Tue 2009-03-10 12:51:46 +1100
    message:
      Disagreement on trailing whitespace with the test suite.
    modified:
      bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
    ------------------------------------------------------------
    revno: 4084.6.2
    revision-id: robertc at robertcollins.net-20090310003511-pvtygbimxywwton0
    parent: robertc at robertcollins.net-20090308061806-uvu37ccjrrzuspei
    parent: pqm at pqm.ubuntu.com-20090309084556-9i2m12qlud2qcrtw
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: integration
    timestamp: Tue 2009-03-10 11:35:11 +1100
    message:
      Merge bzr.dev, commands.py was conflicting.
    added:
      bzrlib/tests/test_debug.py     test_debug.py-20090303053802-01e8mlv24odmpgix-1
      doc/en/user-guide/organizing_your_workspace.txt organizing_your_work-20090226112520-bc2njq3kwvpeo814-1
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/check.py                check.py-20050309040759-f3a679400c06bcc1
      bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
      bzrlib/debug.py                debug.py-20061102062349-vdhrw9qdpck8cl35-1
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/fetch.py                fetch.py-20050818234941-26fea6105696365d
      bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/help_topics/en/configuration.txt configuration.txt-20060314161707-868350809502af01
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/multiparent.py          __init__.py-20070410133617-n1jdhcc1n1mibarp-1
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/shelf.py                prepare_shelf.py-20081005181341-n74qe6gu1e65ad4v-1
      bzrlib/shelf_ui.py             shelver.py-20081005210102-33worgzwrtdw0yrm-1
      bzrlib/smart/branch.py         branch.py-20061124031907-mzh3pla28r83r97f-1
      bzrlib/smart/bzrdir.py         bzrdir.py-20061122024551-ol0l0o0oofsu9b3t-1
      bzrlib/smart/medium.py         medium.py-20061103051856-rgu2huy59fkz902q-1
      bzrlib/smart/message.py        message.py-20080222013625-ncqmh3nrxjkxab87-1
      bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/tag.py                  tag.py-20070212110532-91cw79inah2cfozx-1
      bzrlib/tests/EncodingAdapter.py EncodingAdapter.py-20060113032051-4d7e1d8c1e38b4a1
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/__init__.py __init__.py-20051128053524-eba30d8255e08dc3
      bzrlib/tests/blackbox/test_branch.py test_branch.py-20060524161337-noms9gmcwqqrfi8y-1
      bzrlib/tests/blackbox/test_merge.py test_merge.py-20060323225809-9bc0459c19917f41
      bzrlib/tests/blackbox/test_non_ascii.py test_non_ascii.py-20060105214030-68010be784a5d854
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
      bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
      bzrlib/tests/branch_implementations/test_hooks.py test_hooks.py-20070129154855-blhpwxmvjs07waei-1
      bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
      bzrlib/tests/branch_implementations/test_tags.py test_tags.py-20070212110545-w2s799hm2jlbsmg5-1
      bzrlib/tests/bzrdir_implementations/__init__.py __init__.py-20060131065642-34c39b54f42dd048
      bzrlib/tests/interrepository_implementations/__init__.py __init__.py-20060220054744-baf49a1f88f17b1a
      bzrlib/tests/intertree_implementations/__init__.py __init__.py-20060724101752-09ysswo1a92uqyoz-3
      bzrlib/tests/inventory_implementations/__init__.py __init__.py-20070821044532-olbadbokgv3qv1yd-1
      bzrlib/tests/inventory_implementations/basics.py basics.py-20070903044446-kdjwbiu1p1zi9phs-1
      bzrlib/tests/per_interbranch/__init__.py __init__.py-20090225010018-l7w4uvvt73ea2vj9-1
      bzrlib/tests/per_lock/__init__.py __init__.py-20070314201444-u92yjsqrkh2m3qcb-1
      bzrlib/tests/per_repository/__init__.py __init__.py-20060131092037-9564957a7d4a841b
      bzrlib/tests/per_repository_reference/__init__.py __init__.py-20080220025549-nnm2s80it1lvcwnc-2
      bzrlib/tests/test__chunks_to_lines.py test__chunks_to_line-20081211024848-6uc3mtuje8j14l60-2
      bzrlib/tests/test_btree_index.py test_index.py-20080624222253-p0x5f92uyh5hw734-13
      bzrlib/tests/test_bzrdir.py    test_bzrdir.py-20060131065654-deba40eef51cf220
      bzrlib/tests/test_graph.py     test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
      bzrlib/tests/test_http.py      testhttp.py-20051018020158-b2eef6e867c514d9
      bzrlib/tests/test_merge.py     testmerge.py-20050905070950-c1b5aa49ff911024
      bzrlib/tests/test_msgeditor.py test_msgeditor.py-20051202041359-920315ec6011ee51
      bzrlib/tests/test_osutils.py   test_osutils.py-20051201224856-e48ee24c12182989
      bzrlib/tests/test_pack_repository.py test_pack_repository-20080801043947-eaw0e6h2gu75kwmy-1
      bzrlib/tests/test_read_bundle.py test_read_bundle.py-20060615211421-ud8cwr1ulgd914zf-1
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
      bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
      bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
      bzrlib/tests/test_tag.py       test_tag.py-20070212110532-91cw79inah2cfozx-2
      bzrlib/tests/test_transport_implementations.py test_transport_implementations.py-20051227111451-f97c5c7d5c49fce7
      bzrlib/tests/test_upgrade_stacked.py test_upgrade_stacked-20080804072225-jd13yami19nskns5-1
      bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
      bzrlib/tests/tree_implementations/__init__.py __init__.py-20060717075546-420s7b0bj9hzeowi-2
      bzrlib/tests/workingtree_implementations/__init__.py __init__.py-20060203003124-b2aa5aca21a8bfad
      bzrlib/ui/__init__.py          ui.py-20050824083933-8cf663c763ba53a9
      bzrlib/xml8.py                 xml5.py-20050907032657-aac8f960815b66b1
      doc/developers/HACKING.txt     HACKING-20050805200004-2a5dc975d870f78c
      doc/en/user-guide/branching_a_project.txt branching_a_project.-20071122141511-0knao2lklsdsvb1q-2
      doc/en/user-guide/index.txt    index.txt-20060622101119-tgwtdci8z769bjb9-2
      doc/en/user-guide/publishing_a_branch.txt publishing_a_branch.-20071123055134-k5x4ekduci2lbn36-2
      doc/en/user-guide/shared_repository_layouts.txt shared_repository_la-20070502152030-bagewuqs18ns24o7-1
      setup.py                       setup.py-20050314065409-02f8a0a6e3f9bc70
    ------------------------------------------------------------
    revno: 4084.6.1
    revision-id: robertc at robertcollins.net-20090308061806-uvu37ccjrrzuspei
    parent: pqm at pqm.ubuntu.com-20090306030219-enauehb3achqqq7c
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: lsprof
    timestamp: Sun 2009-03-08 17:18:06 +1100
    message:
      Refactor profiling exception handling to restore clear layers - command handling in commands.py, profiling in lsprof.py.
    modified:
      bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
      bzrlib/lsprof.py               lsprof.py-20051208071030-833790916798ceed
=== modified file 'bzrlib/commands.py'
--- a/bzrlib/commands.py	2009-03-08 23:11:57 +0000
+++ b/bzrlib/commands.py	2009-03-10 01:51:46 +0000
@@ -672,12 +672,13 @@
     tracer = trace.Trace(count=1, trace=0)
     sys.settrace(tracer.globaltrace)
 
-    ret = the_callable(*args, **kwargs)
-
-    sys.settrace(None)
-    results = tracer.results()
-    results.write_results(show_missing=1, summary=False,
-                          coverdir=dirname)
+    try:
+        return exception_to_return_code(the_callable, *args, **kwargs)
+    finally:
+        sys.settrace(None)
+        results = tracer.results()
+        results.write_results(show_missing=1, summary=False,
+                              coverdir=dirname)
 
 
 def apply_profiled(the_callable, *args, **kwargs):
@@ -688,7 +689,8 @@
     try:
         prof = hotshot.Profile(pfname)
         try:
-            ret = prof.runcall(the_callable, *args, **kwargs) or 0
+            ret = prof.runcall(exception_to_return_code, the_callable, *args,
+                **kwargs) or 0
         finally:
             prof.close()
         stats = hotshot.stats.load(pfname)
@@ -703,9 +705,50 @@
         os.remove(pfname)
 
 
+def exception_to_return_code(the_callable, *args, **kwargs):
+    """UI level helper for profiling and coverage.
+
+    This transforms exceptions into a return value of 3. As such its only
+    relevant to the UI layer, and should never be called where catching
+    exceptions may be desirable.
+    """
+    try:
+        return the_callable(*args, **kwargs)
+    except (KeyboardInterrupt, Exception), e:
+        # used to handle AssertionError and KeyboardInterrupt
+        # specially here, but hopefully they're handled ok by the logger now
+        exc_info = sys.exc_info()
+        exitcode = trace.report_exception(exc_info, sys.stderr)
+        if os.environ.get('BZR_PDB'):
+            print '**** entering debugger'
+            tb = exc_info[2]
+            import pdb
+            if sys.version_info[:2] < (2, 6):
+                # XXX: we want to do
+                #    pdb.post_mortem(tb)
+                # but because pdb.post_mortem gives bad results for tracebacks
+                # from inside generators, we do it manually.
+                # (http://bugs.python.org/issue4150, fixed in Python 2.6)
+
+                # Setup pdb on the traceback
+                p = pdb.Pdb()
+                p.reset()
+                p.setup(tb.tb_frame, tb)
+                # Point the debugger at the deepest frame of the stack
+                p.curindex = len(p.stack) - 1
+                p.curframe = p.stack[p.curindex][0]
+                # Start the pdb prompt.
+                p.print_stack_entry(p.stack[p.curindex])
+                p.execRcLines()
+                p.cmdloop()
+            else:
+                pdb.post_mortem(tb)
+        return exitcode
+
+
 def apply_lsprofiled(filename, the_callable, *args, **kwargs):
     from bzrlib.lsprof import profile
-    ret, stats = profile(the_callable, *args, **kwargs)
+    ret, stats = profile(exception_to_return_code, the_callable, *args, **kwargs)
     stats.sort()
     if filename is None:
         stats.pprint()
@@ -917,40 +960,12 @@
 
 
 def run_bzr_catch_errors(argv):
-    # Note: The except clause logic below should be kept in sync with the
-    # profile() routine in lsprof.py.
-    try:
-        return run_bzr(argv)
-    except (KeyboardInterrupt, Exception), e:
-        # used to handle AssertionError and KeyboardInterrupt
-        # specially here, but hopefully they're handled ok by the logger now
-        exc_info = sys.exc_info()
-        exitcode = trace.report_exception(exc_info, sys.stderr)
-        if os.environ.get('BZR_PDB'):
-            print '**** entering debugger'
-            tb = exc_info[2]
-            import pdb
-            if sys.version_info[:2] < (2, 6):
-                # XXX: we want to do
-                #    pdb.post_mortem(tb)
-                # but because pdb.post_mortem gives bad results for tracebacks
-                # from inside generators, we do it manually.
-                # (http://bugs.python.org/issue4150, fixed in Python 2.6)
+    """Run a bzr command with parameters as described by argv.
 
-                # Setup pdb on the traceback
-                p = pdb.Pdb()
-                p.reset()
-                p.setup(tb.tb_frame, tb)
-                # Point the debugger at the deepest frame of the stack
-                p.curindex = len(p.stack) - 1
-                p.curframe = p.stack[p.curindex][0]
-                # Start the pdb prompt.
-                p.print_stack_entry(p.stack[p.curindex])
-                p.execRcLines()
-                p.cmdloop()
-            else:
-                pdb.post_mortem(tb)
-        return exitcode
+    This function assumed that that UI layer is setup, that symbol deprecations
+    are already applied, and that unicode decoding has already been performed on argv.
+    """
+    return exception_to_return_code(run_bzr, argv)
 
 
 def run_bzr_catch_user_errors(argv):

=== modified file 'bzrlib/lsprof.py'
--- a/bzrlib/lsprof.py	2009-01-17 01:30:58 +0000
+++ b/bzrlib/lsprof.py	2009-03-08 06:18:06 +0000
@@ -29,23 +29,18 @@
 def profile(f, *args, **kwds):
     """Run a function profile.
 
+    Exceptions are not caught: If you need stats even when exceptions are to be
+    raised, passing in a closure that will catch the exceptions and transform
+    them appropriately for your driver function.
+
     :return: The functions return value and a stats object.
     """
     global _g_threadmap
     p = Profiler()
     p.enable(subcalls=True)
     threading.setprofile(_thread_profile)
-    # Note: The except clause is needed below so that profiling data still
-    # gets dumped even when exceptions are encountered. The except clause code
-    # is taken straight from run_bzr_catch_errrors() in commands.py and ought
-    # to be kept in sync with it.
     try:
-        try:
-            ret = f(*args, **kwds)
-        except (KeyboardInterrupt, Exception), e:
-            import bzrlib.trace
-            bzrlib.trace.report_exception(sys.exc_info(), sys.stderr)
-            ret = 3
+        ret = f(*args, **kwds)
     finally:
         p.disable()
         for pp in _g_threadmap.values():




More information about the bazaar-commits mailing list