~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

Merge lp:bzr.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
                  S_ISCHR, S_ISBLK, S_ISFIFO, S_ISSOCK)
22
22
import sys
23
23
import time
 
24
import warnings
24
25
 
25
26
from bzrlib.lazy_import import lazy_import
26
27
lazy_import(globals(), """
881
882
    return parents
882
883
 
883
884
 
 
885
_extension_load_failures = []
 
886
 
 
887
 
 
888
def failed_to_load_extension(exception):
 
889
    """Handle failing to load a binary extension.
 
890
 
 
891
    This should be called from the ImportError block guarding the attempt to
 
892
    import the native extension.  If this function returns, the pure-Python
 
893
    implementation should be loaded instead::
 
894
 
 
895
    >>> try:
 
896
    >>>     import bzrlib._fictional_extension_pyx
 
897
    >>> except ImportError, e:
 
898
    >>>     bzrlib.osutils.failed_to_load_extension(e)
 
899
    >>>     import bzrlib._fictional_extension_py
 
900
    """
 
901
    # NB: This docstring is just an example, not a doctest, because doctest
 
902
    # currently can't cope with the use of lazy imports in this namespace --
 
903
    # mbp 20090729
 
904
    
 
905
    # This currently doesn't report the failure at the time it occurs, because
 
906
    # they tend to happen very early in startup when we can't check config
 
907
    # files etc, and also we want to report all failures but not spam the user
 
908
    # with 10 warnings.
 
909
    from bzrlib import trace
 
910
    exception_str = str(exception)
 
911
    if exception_str not in _extension_load_failures:
 
912
        trace.mutter("failed to load compiled extension: %s" % exception_str)
 
913
        _extension_load_failures.append(exception_str)
 
914
 
 
915
 
 
916
def report_extension_load_failures():
 
917
    if not _extension_load_failures:
 
918
        return
 
919
    from bzrlib.config import GlobalConfig
 
920
    if GlobalConfig().get_user_option_as_bool('ignore_missing_extensions'):
 
921
        return
 
922
    # the warnings framework should by default show this only once
 
923
    from bzrlib.trace import warning
 
924
    warning(
 
925
        "bzr: warning: some compiled extensions could not be loaded; "
 
926
        "see <https://answers.launchpad.net/bzr/+faq/703>")
 
927
    # we no longer show the specific missing extensions here, because it makes
 
928
    # the message too long and scary - see
 
929
    # https://bugs.launchpad.net/bzr/+bug/430529
 
930
 
 
931
 
884
932
try:
885
933
    from bzrlib._chunks_to_lines_pyx import chunks_to_lines
886
 
except ImportError:
 
934
except ImportError, e:
 
935
    failed_to_load_extension(e)
887
936
    from bzrlib._chunks_to_lines_py import chunks_to_lines
888
937
 
889
938
 
1083
1132
    bit_iter = iter(rel.split('/'))
1084
1133
    for bit in bit_iter:
1085
1134
        lbit = bit.lower()
1086
 
        for look in _listdir(current):
 
1135
        try:
 
1136
            next_entries = _listdir(current)
 
1137
        except OSError: # enoent, eperm, etc
 
1138
            # We can't find this in the filesystem, so just append the
 
1139
            # remaining bits.
 
1140
            current = pathjoin(current, bit, *list(bit_iter))
 
1141
            break
 
1142
        for look in next_entries:
1087
1143
            if lbit == look.lower():
1088
1144
                current = pathjoin(current, look)
1089
1145
                break
1093
1149
            # the target of a move, for example).
1094
1150
            current = pathjoin(current, bit, *list(bit_iter))
1095
1151
            break
1096
 
    return current[len(abs_base)+1:]
 
1152
    return current[len(abs_base):].lstrip('/')
1097
1153
 
1098
1154
# XXX - TODO - we need better detection/integration of case-insensitive
1099
1155
# file-systems; Linux often sees FAT32 devices (or NFS-mounted OSX
1466
1522
            try:
1467
1523
                from bzrlib._readdir_pyx import UTF8DirReader
1468
1524
                _selected_dir_reader = UTF8DirReader()
1469
 
            except ImportError:
 
1525
            except ImportError, e:
 
1526
                failed_to_load_extension(e)
1470
1527
                pass
1471
1528
 
1472
1529
    if _selected_dir_reader is None:
1778
1835
        try:
1779
1836
            from bzrlib._readdir_pyx import UTF8DirReader
1780
1837
            file_kind_from_stat_mode = UTF8DirReader().kind_from_mode
1781
 
        except ImportError:
 
1838
        except ImportError, e:
 
1839
            # This is one time where we won't warn that an extension failed to
 
1840
            # load. The extension is never available on Windows anyway.
1782
1841
            from bzrlib._readdir_py import (
1783
1842
                _kind_from_mode as file_kind_from_stat_mode
1784
1843
                )