~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: Jelmer Vernooij
  • Date: 2012-01-05 16:03:11 UTC
  • mfrom: (6432 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6433.
  • Revision ID: jelmer@samba.org-20120105160311-12o5p67kin1v3zps
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
 
17
from __future__ import absolute_import
 
18
 
17
19
import errno
18
20
import os
19
21
import re
26
28
lazy_import(globals(), """
27
29
from datetime import datetime
28
30
import getpass
 
31
import locale
29
32
import ntpath
30
33
import posixpath
31
34
import select
52
55
""")
53
56
 
54
57
from bzrlib.symbol_versioning import (
 
58
    DEPRECATED_PARAMETER,
55
59
    deprecated_function,
56
60
    deprecated_in,
 
61
    deprecated_passed,
 
62
    warn as warn_deprecated,
57
63
    )
58
64
 
59
65
from hashlib import (
943
949
    return os.fstat(f.fileno())[stat.ST_SIZE]
944
950
 
945
951
 
946
 
# Define rand_bytes based on platform.
947
 
try:
948
 
    # Python 2.4 and later have os.urandom,
949
 
    # but it doesn't work on some arches
950
 
    os.urandom(1)
951
 
    rand_bytes = os.urandom
952
 
except (NotImplementedError, AttributeError):
953
 
    # If python doesn't have os.urandom, or it doesn't work,
954
 
    # then try to first pull random data from /dev/urandom
 
952
# Alias os.urandom to support platforms (which?) without /dev/urandom and 
 
953
# override if it doesn't work. Avoid checking on windows where there is
 
954
# significant initialisation cost that can be avoided for some bzr calls.
 
955
 
 
956
rand_bytes = os.urandom
 
957
 
 
958
if rand_bytes.__module__ != "nt":
955
959
    try:
956
 
        rand_bytes = file('/dev/urandom', 'rb').read
957
 
    # Otherwise, use this hack as a last resort
958
 
    except (IOError, OSError):
 
960
        rand_bytes(1)
 
961
    except NotImplementedError:
959
962
        # not well seeded, but better than nothing
960
963
        def rand_bytes(n):
961
964
            import random
1977
1980
_cached_user_encoding = None
1978
1981
 
1979
1982
 
1980
 
def get_user_encoding(use_cache=True):
 
1983
def get_user_encoding(use_cache=DEPRECATED_PARAMETER):
1981
1984
    """Find out what the preferred user encoding is.
1982
1985
 
1983
1986
    This is generally the encoding that is used for command line parameters
1984
1987
    and file contents. This may be different from the terminal encoding
1985
1988
    or the filesystem encoding.
1986
1989
 
1987
 
    :param  use_cache:  Enable cache for detected encoding.
1988
 
                        (This parameter is turned on by default,
1989
 
                        and required only for selftesting)
1990
 
 
1991
1990
    :return: A string defining the preferred user encoding
1992
1991
    """
1993
1992
    global _cached_user_encoding
1994
 
    if _cached_user_encoding is not None and use_cache:
 
1993
    if deprecated_passed(use_cache):
 
1994
        warn_deprecated("use_cache should only have been used for tests",
 
1995
            DeprecationWarning, stacklevel=2) 
 
1996
    if _cached_user_encoding is not None:
1995
1997
        return _cached_user_encoding
1996
1998
 
1997
 
    if sys.platform == 'darwin':
1998
 
        # python locale.getpreferredencoding() always return
1999
 
        # 'mac-roman' on darwin. That's a lie.
2000
 
        sys.platform = 'posix'
2001
 
        try:
2002
 
            if os.environ.get('LANG', None) is None:
2003
 
                # If LANG is not set, we end up with 'ascii', which is bad
2004
 
                # ('mac-roman' is more than ascii), so we set a default which
2005
 
                # will give us UTF-8 (which appears to work in all cases on
2006
 
                # OSX). Users are still free to override LANG of course, as
2007
 
                # long as it give us something meaningful. This work-around
2008
 
                # *may* not be needed with python 3k and/or OSX 10.5, but will
2009
 
                # work with them too -- vila 20080908
2010
 
                os.environ['LANG'] = 'en_US.UTF-8'
2011
 
            import locale
2012
 
        finally:
2013
 
            sys.platform = 'darwin'
 
1999
    if os.name == 'posix' and getattr(locale, 'CODESET', None) is not None:
 
2000
        # Use the existing locale settings and call nl_langinfo directly
 
2001
        # rather than going through getpreferredencoding. This avoids
 
2002
        # <http://bugs.python.org/issue6202> on OSX Python 2.6 and the
 
2003
        # possibility of the setlocale call throwing an error.
 
2004
        user_encoding = locale.nl_langinfo(locale.CODESET)
2014
2005
    else:
2015
 
        import locale
 
2006
        # GZ 2011-12-19: On windows could call GetACP directly instead.
 
2007
        user_encoding = locale.getpreferredencoding(False)
2016
2008
 
2017
2009
    try:
2018
 
        user_encoding = locale.getpreferredencoding()
2019
 
    except locale.Error, e:
2020
 
        sys.stderr.write('bzr: warning: %s\n'
2021
 
                         '  Could not determine what text encoding to use.\n'
2022
 
                         '  This error usually means your Python interpreter\n'
2023
 
                         '  doesn\'t support the locale set by $LANG (%s)\n'
2024
 
                         "  Continuing with ascii encoding.\n"
2025
 
                         % (e, os.environ.get('LANG')))
2026
 
        user_encoding = 'ascii'
2027
 
 
2028
 
    # Windows returns 'cp0' to indicate there is no code page. So we'll just
2029
 
    # treat that as ASCII, and not support printing unicode characters to the
2030
 
    # console.
2031
 
    #
2032
 
    # For python scripts run under vim, we get '', so also treat that as ASCII
2033
 
    if user_encoding in (None, 'cp0', ''):
2034
 
        user_encoding = 'ascii'
2035
 
    else:
2036
 
        # check encoding
2037
 
        try:
2038
 
            codecs.lookup(user_encoding)
2039
 
        except LookupError:
 
2010
        user_encoding = codecs.lookup(user_encoding).name
 
2011
    except LookupError:
 
2012
        if user_encoding not in ("", "cp0"):
2040
2013
            sys.stderr.write('bzr: warning:'
2041
2014
                             ' unknown encoding %s.'
2042
2015
                             ' Continuing with ascii encoding.\n'
2043
2016
                             % user_encoding
2044
2017
                            )
2045
 
            user_encoding = 'ascii'
2046
 
 
2047
 
    if use_cache:
2048
 
        _cached_user_encoding = user_encoding
2049
 
 
 
2018
        user_encoding = 'ascii'
 
2019
    else:
 
2020
        # Get 'ascii' when setlocale has not been called or LANG=C or unset.
 
2021
        if user_encoding == 'ascii':
 
2022
            if sys.platform == 'darwin':
 
2023
                # OSX is special-cased in Python to have a UTF-8 filesystem
 
2024
                # encoding and previously had LANG set here if not present.
 
2025
                user_encoding = 'utf-8'
 
2026
            # GZ 2011-12-19: Maybe UTF-8 should be the default in this case
 
2027
            #                for some other posix platforms as well.
 
2028
 
 
2029
    _cached_user_encoding = user_encoding
2050
2030
    return user_encoding
2051
2031
 
2052
2032
 
2054
2034
    return get_terminal_encoding()
2055
2035
 
2056
2036
 
2057
 
_message_encoding = None
2058
 
 
2059
 
 
2060
 
def get_message_encoding():
2061
 
    """Return the encoding used for messages
2062
 
 
2063
 
    While the message encoding is a general setting it should usually only be
2064
 
    needed for decoding system error strings such as from OSError instances.
2065
 
    """
2066
 
    global _message_encoding
2067
 
    if _message_encoding is None:
2068
 
        if os.name == "posix":
2069
 
            import locale
2070
 
            # This is a process-global setting that can change, but should in
2071
 
            # general just get set once at process startup then be constant.
2072
 
            _message_encoding = locale.getlocale(locale.LC_MESSAGES)[1]
2073
 
        else:
2074
 
            # On windows want the result of GetACP() which this boils down to.
2075
 
            _message_encoding = get_user_encoding()
2076
 
    return _message_encoding or "ascii"
2077
 
        
2078
 
 
2079
2037
def get_host_name():
2080
2038
    """Return the current unicode host name.
2081
2039
 
2083
2041
    behaves inconsistently on different platforms.
2084
2042
    """
2085
2043
    if sys.platform == "win32":
2086
 
        import win32utils
2087
2044
        return win32utils.get_host_name()
2088
2045
    else:
2089
2046
        import socket
2325
2282
 
2326
2283
 
2327
2284
if sys.platform == "win32":
2328
 
    import msvcrt
2329
2285
    def getchar():
 
2286
        import msvcrt
2330
2287
        return msvcrt.getch()
2331
2288
else:
2332
 
    import tty
2333
 
    import termios
2334
2289
    def getchar():
 
2290
        import tty
 
2291
        import termios
2335
2292
        fd = sys.stdin.fileno()
2336
2293
        settings = termios.tcgetattr(fd)
2337
2294
        try: