Rev 4688: (mbp) warnings if extensions can't be loaded in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Mon Sep 14 04:01:27 BST 2009
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 4688 [merge]
revision-id: pqm at pqm.ubuntu.com-20090914030125-wichbbiuuk4260y4
parent: pqm at pqm.ubuntu.com-20090914014819-4yshlf6ooeeqznfs
parent: mbp at sourcefrog.net-20090914014828-ydr9rlkdfq2sv57z
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2009-09-14 04:01:25 +0100
message:
(mbp) warnings if extensions can't be loaded
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/__init__.py __init__.py-20050309040759-33e65acf91bbcd5d
bzrlib/annotate.py annotate.py-20050922133147-7c60541d2614f022
bzrlib/bencode.py bencode.py-20070806220735-j75g4ebfnado2i60-2
bzrlib/btree_index.py index.py-20080624222253-p0x5f92uyh5hw734-7
bzrlib/chk_map.py chk_map.py-20081001014447-ue6kkuhofvdecvxa-1
bzrlib/commands.py bzr.py-20050309040720-d10f4714595cf8c3
bzrlib/dirstate.py dirstate.py-20060728012006-d6mvoihjb3je9peu-1
bzrlib/graph.py graph_walker.py-20070525030359-y852guab65d4wtn0-1
bzrlib/groupcompress.py groupcompress.py-20080705181503-ccbxd6xuy1bdnrpu-8
bzrlib/knit.py knit.py-20051212171256-f056ac8f0fbe1bd9
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/rio.py rio.py-20051128032247-770b120b34dfff60
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
=== modified file 'NEWS'
--- a/NEWS 2009-09-11 14:23:16 +0000
+++ b/NEWS 2009-09-14 01:48:28 +0000
@@ -6,8 +6,8 @@
.. contents:: List of Releases
:depth: 1
-In Development
-##############
+2.1 series (not released yet)
+#############################
Compatibility Breaks
********************
@@ -77,6 +77,14 @@
Improvements
************
+* Bazaar gives a warning before exiting, and writes into ``.bzr.log``, if
+ compiled extensions can't be loaded. This typically indicates a
+ packaging or installation problem. In this case Bazaar will keep
+ running using pure-Python versions, but this may be substantially
+ slower. The warning can be disabled by setting
+ ``ignore_missing_extensions = True`` in ``bazaar.conf``.
+ (Martin Pool, #406113)
+
Documentation
*************
=== modified file 'bzrlib/__init__.py'
--- a/bzrlib/__init__.py 2009-08-30 21:34:42 +0000
+++ b/bzrlib/__init__.py 2009-09-14 01:48:28 +0000
@@ -55,6 +55,7 @@
# API compatibility version: bzrlib is currently API compatible with 1.15.
api_minimum_version = (1, 17, 0)
+
def _format_version_tuple(version_info):
"""Turn a version number 2, 3 or 5-tuple into a short string.
=== modified file 'bzrlib/annotate.py'
--- a/bzrlib/annotate.py 2009-08-17 18:52:01 +0000
+++ b/bzrlib/annotate.py 2009-09-14 01:48:28 +0000
@@ -458,5 +458,6 @@
try:
from bzrlib._annotator_pyx import Annotator
-except ImportError:
+except ImportError, e:
+ osutils.failed_to_load_extension(e)
from bzrlib._annotator_py import Annotator
=== modified file 'bzrlib/bencode.py'
--- a/bzrlib/bencode.py 2009-06-03 14:14:31 +0000
+++ b/bzrlib/bencode.py 2009-09-11 06:36:50 +0000
@@ -16,7 +16,10 @@
"""Wrapper around the bencode pyrex and python implementation"""
+from bzrlib import osutils
+
try:
from bzrlib._bencode_pyx import bdecode, bdecode_as_tuple, bencode, Bencached
-except ImportError:
+except ImportError, e:
+ osutils.failed_to_load_extension(e)
from bzrlib.util._bencode_py import bdecode, bdecode_as_tuple, bencode, Bencached
=== modified file 'bzrlib/btree_index.py'
--- a/bzrlib/btree_index.py 2009-08-17 22:11:06 +0000
+++ b/bzrlib/btree_index.py 2009-09-14 01:48:28 +0000
@@ -1526,5 +1526,6 @@
try:
from bzrlib import _btree_serializer_pyx as _btree_serializer
-except ImportError:
+except ImportError, e:
+ osutils.failed_to_load_extension(e)
from bzrlib import _btree_serializer_py as _btree_serializer
=== modified file 'bzrlib/chk_map.py'
--- a/bzrlib/chk_map.py 2009-08-04 14:10:09 +0000
+++ b/bzrlib/chk_map.py 2009-09-14 01:48:28 +0000
@@ -1640,7 +1640,8 @@
_deserialise_leaf_node,
_deserialise_internal_node,
)
-except ImportError:
+except ImportError, e:
+ osutils.failed_to_load_extension(e)
from bzrlib._chk_map_py import (
_search_key_16,
_search_key_255,
=== modified file 'bzrlib/commands.py'
--- a/bzrlib/commands.py 2009-09-09 17:51:19 +0000
+++ b/bzrlib/commands.py 2009-09-14 01:48:28 +0000
@@ -1107,6 +1107,7 @@
argv = new_argv
ret = run_bzr_catch_errors(argv)
trace.mutter("return code %d", ret)
+ osutils.report_extension_load_failures()
return ret
=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py 2009-08-28 05:00:33 +0000
+++ b/bzrlib/dirstate.py 2009-09-14 01:48:28 +0000
@@ -3969,7 +3969,8 @@
ProcessEntryC as _process_entry,
update_entry as update_entry,
)
-except ImportError:
+except ImportError, e:
+ osutils.failed_to_load_extension(e)
from bzrlib._dirstate_helpers_py import (
_read_dirblocks,
bisect_dirblock,
=== modified file 'bzrlib/graph.py'
--- a/bzrlib/graph.py 2009-08-17 18:36:14 +0000
+++ b/bzrlib/graph.py 2009-09-14 01:48:28 +0000
@@ -19,6 +19,7 @@
from bzrlib import (
debug,
errors,
+ osutils,
revision,
trace,
)
@@ -1681,5 +1682,6 @@
_counters = [0,0,0,0,0,0,0]
try:
from bzrlib._known_graph_pyx import KnownGraph
-except ImportError:
+except ImportError, e:
+ osutils.failed_to_load_extension(e)
from bzrlib._known_graph_py import KnownGraph
=== modified file 'bzrlib/groupcompress.py'
--- a/bzrlib/groupcompress.py 2009-09-09 13:05:33 +0000
+++ b/bzrlib/groupcompress.py 2009-09-14 01:48:28 +0000
@@ -2066,6 +2066,7 @@
decode_base128_int,
)
GroupCompressor = PyrexGroupCompressor
-except ImportError:
+except ImportError, e:
+ osutils.failed_to_load_extension(e)
GroupCompressor = PythonGroupCompressor
=== modified file 'bzrlib/knit.py'
--- a/bzrlib/knit.py 2009-09-09 13:05:33 +0000
+++ b/bzrlib/knit.py 2009-09-14 01:48:28 +0000
@@ -3700,5 +3700,6 @@
try:
from bzrlib._knit_load_data_pyx import _load_data_c as _load_data
-except ImportError:
+except ImportError, e:
+ osutils.failed_to_load_extension(e)
from bzrlib._knit_load_data_py import _load_data_py as _load_data
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py 2009-07-23 16:01:17 +0000
+++ b/bzrlib/osutils.py 2009-09-11 06:39:56 +0000
@@ -21,6 +21,7 @@
S_ISCHR, S_ISBLK, S_ISFIFO, S_ISSOCK)
import sys
import time
+import warnings
from bzrlib.lazy_import import lazy_import
lazy_import(globals(), """
@@ -881,9 +882,56 @@
return parents
+_extension_load_failures = []
+
+
+def failed_to_load_extension(exception):
+ """Handle failing to load a binary extension.
+
+ This should be called from the ImportError block guarding the attempt to
+ import the native extension. If this function returns, the pure-Python
+ implementation should be loaded instead::
+
+ >>> try:
+ >>> import bzrlib._fictional_extension_pyx
+ >>> except ImportError, e:
+ >>> bzrlib.osutils.failed_to_load_extension(e)
+ >>> import bzrlib._fictional_extension_py
+ """
+ # NB: This docstring is just an example, not a doctest, because doctest
+ # currently can't cope with the use of lazy imports in this namespace --
+ # mbp 20090729
+
+ # This currently doesn't report the failure at the time it occurs, because
+ # they tend to happen very early in startup when we can't check config
+ # files etc, and also we want to report all failures but not spam the user
+ # with 10 warnings.
+ from bzrlib import trace
+ exception_str = str(exception)
+ if exception_str not in _extension_load_failures:
+ trace.mutter("failed to load compiled extension: %s" % exception_str)
+ _extension_load_failures.append(exception_str)
+
+
+def report_extension_load_failures():
+ if not _extension_load_failures:
+ return
+ from bzrlib.config import GlobalConfig
+ if GlobalConfig().get_user_option_as_bool('ignore_missing_extensions'):
+ return
+ # the warnings framework should by default show this only once
+ warnings.warn(
+ "bzr: warning: Failed to load compiled extensions:\n"
+ " %s\n"
+ " Bazaar can run, but performance may be reduced.\n"
+ " Check Bazaar is correctly installed or set ignore_missing_extensions"
+ % '\n '.join(_extension_load_failures,))
+
+
try:
from bzrlib._chunks_to_lines_pyx import chunks_to_lines
-except ImportError:
+except ImportError, e:
+ failed_to_load_extension(e)
from bzrlib._chunks_to_lines_py import chunks_to_lines
@@ -1466,7 +1514,8 @@
try:
from bzrlib._readdir_pyx import UTF8DirReader
_selected_dir_reader = UTF8DirReader()
- except ImportError:
+ except ImportError, e:
+ failed_to_load_extension(e)
pass
if _selected_dir_reader is None:
@@ -1778,7 +1827,8 @@
try:
from bzrlib._readdir_pyx import UTF8DirReader
file_kind_from_stat_mode = UTF8DirReader().kind_from_mode
- except ImportError:
+ except ImportError, e:
+ failed_to_load_extension(e)
from bzrlib._readdir_py import (
_kind_from_mode as file_kind_from_stat_mode
)
=== modified file 'bzrlib/rio.py'
--- a/bzrlib/rio.py 2009-06-10 03:56:49 +0000
+++ b/bzrlib/rio.py 2009-09-11 06:36:50 +0000
@@ -32,6 +32,7 @@
import re
+from bzrlib import osutils
from bzrlib.iterablefile import IterableFile
# XXX: some redundancy is allowing to write stanzas in isolation as well as
@@ -377,7 +378,8 @@
_read_stanza_unicode,
_valid_tag,
)
-except ImportError:
+except ImportError, e:
+ osutils.failed_to_load_extension(e)
from bzrlib._rio_py import (
_read_stanza_utf8,
_read_stanza_unicode,
=== modified file 'bzrlib/tests/test_osutils.py'
--- a/bzrlib/tests/test_osutils.py 2009-07-23 16:01:17 +0000
+++ b/bzrlib/tests/test_osutils.py 2009-09-11 06:36:50 +0000
@@ -1798,3 +1798,33 @@
def test_local_concurrency(self):
concurrency = osutils.local_concurrency()
self.assertIsInstance(concurrency, int)
+
+
+class TestFailedToLoadExtension(tests.TestCase):
+
+ def _try_loading(self):
+ try:
+ import bzrlib._fictional_extension_py
+ except ImportError, e:
+ osutils.failed_to_load_extension(e)
+ return True
+
+ def setUp(self):
+ super(TestFailedToLoadExtension, self).setUp()
+ self.saved_failures = osutils._extension_load_failures[:]
+ del osutils._extension_load_failures[:]
+ self.addCleanup(self.restore_failures)
+
+ def restore_failures(self):
+ osutils._extension_load_failures = self.saved_failures
+
+ def test_failure_to_load(self):
+ self._try_loading()
+ self.assertLength(1, osutils._extension_load_failures)
+ self.assertEquals(osutils._extension_load_failures[0],
+ "No module named _fictional_extension_py")
+
+ def test_report_extension_load_failures(self):
+ self.assertTrue(self._try_loading())
+ warnings, result = self.callCatchWarnings(osutils.report_extension_load_failures)
+ self.assertLength(1, warnings)
More information about the bazaar-commits
mailing list