/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/osutils.py

  • Committer: Jelmer Vernooij
  • Date: 2020-03-22 01:35:14 UTC
  • mfrom: (7490.7.6 work)
  • mto: This revision was merged to the branch mainline in revision 7499.
  • Revision ID: jelmer@jelmer.uk-20200322013514-7vw1ntwho04rcuj3
merge lp:brz/3.1.

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
 
 
19
17
import errno
20
18
import os
21
19
import re
52
50
from breezy.i18n import gettext
53
51
""")
54
52
 
55
 
from .sixish import (
56
 
    PY3,
57
 
    text_type,
58
 
    )
59
 
 
60
53
from hashlib import (
61
54
    md5,
62
55
    sha1 as sha,
91
84
 
92
85
 
93
86
def get_unicode_argv():
94
 
    if PY3:
95
 
        return sys.argv[1:]
96
 
    try:
97
 
        user_encoding = get_user_encoding()
98
 
        return [a.decode(user_encoding) for a in sys.argv[1:]]
99
 
    except UnicodeDecodeError:
100
 
        raise errors.BzrError(gettext("Parameter {0!r} encoding is unsupported by {1} "
101
 
                                      "application locale.").format(a, user_encoding))
 
87
    return sys.argv[1:]
102
88
 
103
89
 
104
90
def make_readonly(filename):
331
317
    Note that posix systems use arbitrary byte strings for filesystem objects,
332
318
    so a path that raises BadFilenameEncoding here may still be accessible.
333
319
    """
334
 
    val = os.environ.get(key, None)
335
 
    if PY3 or val is None:
336
 
        return val
337
 
    try:
338
 
        return val.decode(_fs_enc)
339
 
    except UnicodeDecodeError:
340
 
        # GZ 2011-12-12:Ideally want to include `key` in the exception message
341
 
        raise errors.BadFilenameEncoding(val, _fs_enc)
 
320
    return os.environ.get(key, None)
342
321
 
343
322
 
344
323
def _posix_get_home_dir():
354
333
 
355
334
def _posix_getuser_unicode():
356
335
    """Get username from environment or password database as unicode"""
357
 
    name = getpass.getuser()
358
 
    if PY3:
359
 
        return name
360
 
    user_encoding = get_user_encoding()
361
 
    try:
362
 
        return name.decode(user_encoding)
363
 
    except UnicodeDecodeError:
364
 
        raise errors.BzrError("Encoding of username %r is unsupported by %s "
365
 
                              "application locale." % (name, user_encoding))
 
336
    return getpass.getuser()
366
337
 
367
338
 
368
339
def _win32_fixdrive(path):
447
418
    return _rename_wrapper
448
419
 
449
420
 
450
 
if sys.version_info > (3,):
451
 
    _getcwd = os.getcwd
452
 
else:
453
 
    _getcwd = os.getcwdu
 
421
_getcwd = os.getcwd
454
422
 
455
423
 
456
424
# Default rename wraps os.rename()
738
706
 
739
707
# GZ 2017-09-16: Makes sense in general for hexdigest() result to be text, but
740
708
# used as bytes through most interfaces so encode with this wrapper.
741
 
if PY3:
742
 
    def _hexdigest(hashobj):
743
 
        return hashobj.hexdigest().encode()
744
 
else:
745
 
    def _hexdigest(hashobj):
746
 
        return hashobj.hexdigest()
 
709
def _hexdigest(hashobj):
 
710
    return hashobj.hexdigest().encode()
747
711
 
748
712
 
749
713
def sha_file(f):
895
859
    (date_fmt, tt, offset_str) = \
896
860
        _format_date(t, offset, timezone, date_fmt, show_offset)
897
861
    date_str = time.strftime(date_fmt, tt)
898
 
    if not isinstance(date_str, text_type):
 
862
    if not isinstance(date_str, str):
899
863
        date_str = date_str.decode(get_user_encoding(), 'replace')
900
864
    return date_str + offset_str
901
865
 
1012
976
    """
1013
977
    s = ''
1014
978
    for raw_byte in rand_bytes(num):
1015
 
        if not PY3:
1016
 
            s += ALNUM[ord(raw_byte) % 36]
1017
 
        else:
1018
 
            s += ALNUM[raw_byte % 36]
 
979
        s += ALNUM[raw_byte % 36]
1019
980
    return s
1020
981
 
1021
982
 
1322
1283
 
1323
1284
    abs_base = abspath(base)
1324
1285
    current = abs_base
1325
 
    _listdir = os.listdir
1326
1286
 
1327
1287
    # use an explicit iterator so we can easily consume the rest on early exit.
1328
1288
    bit_iter = iter(rel.split('/'))
1329
1289
    for bit in bit_iter:
1330
1290
        lbit = bit.lower()
1331
1291
        try:
1332
 
            next_entries = _listdir(current)
 
1292
            next_entries = scandir(current)
1333
1293
        except OSError:  # enoent, eperm, etc
1334
1294
            # We can't find this in the filesystem, so just append the
1335
1295
            # remaining bits.
1336
1296
            current = pathjoin(current, bit, *list(bit_iter))
1337
1297
            break
1338
 
        for look in next_entries:
1339
 
            if lbit == look.lower():
1340
 
                current = pathjoin(current, look)
 
1298
        for entry in next_entries:
 
1299
            if lbit == entry.name.lower():
 
1300
                current = entry.path
1341
1301
                break
1342
1302
        else:
1343
1303
            # got to the end, nothing matched, so we just return the
1376
1336
    Otherwise it is decoded from the the filesystem's encoding. If decoding
1377
1337
    fails, a errors.BadFilenameEncoding exception is raised.
1378
1338
    """
1379
 
    if isinstance(filename, text_type):
 
1339
    if isinstance(filename, str):
1380
1340
        return filename
1381
1341
    try:
1382
1342
        return filename.decode(_fs_enc)
1391
1351
    Otherwise it is decoded from utf-8. If decoding fails, the exception is
1392
1352
    wrapped in a BzrBadParameterNotUnicode exception.
1393
1353
    """
1394
 
    if isinstance(unicode_or_utf8_string, text_type):
 
1354
    if isinstance(unicode_or_utf8_string, str):
1395
1355
        return unicode_or_utf8_string
1396
1356
    try:
1397
1357
        return unicode_or_utf8_string.decode('utf8')
1730
1690
        if orig_val is not None:
1731
1691
            del os.environ[env_variable]
1732
1692
    else:
1733
 
        if not PY3 and isinstance(value, text_type):
1734
 
            value = value.encode(get_user_encoding())
1735
1693
        os.environ[env_variable] = value
1736
1694
    return orig_val
1737
1695
 
1753
1711
_WIN32_ERROR_DIRECTORY = 267  # Similar to errno.ENOTDIR
1754
1712
 
1755
1713
 
 
1714
try:
 
1715
    scandir = os.scandir
 
1716
except AttributeError:  # Python < 3
 
1717
    lazy_import(globals(), """\
 
1718
from scandir import scandir
 
1719
""")
 
1720
 
 
1721
 
1756
1722
def _is_error_enotdir(e):
1757
1723
    """Check if this exception represents ENOTDIR.
1758
1724
 
1812
1778
    # depending on top and prefix - i.e. ./foo and foo as a pair leads to
1813
1779
    # potentially confusing output. We should make this more robust - but
1814
1780
    # not at a speed cost. RBC 20060731
1815
 
    _lstat = os.lstat
1816
1781
    _directory = _directory_kind
1817
 
    _listdir = os.listdir
1818
 
    _kind_from_mode = file_kind_from_stat_mode
1819
1782
    pending = [(safe_unicode(prefix), "", _directory, None, safe_unicode(top))]
1820
1783
    while pending:
1821
1784
        # 0 - relpath, 1- basename, 2- kind, 3- stat, 4-toppath
1827
1790
        top_slash = top + u'/'
1828
1791
 
1829
1792
        dirblock = []
1830
 
        append = dirblock.append
1831
1793
        try:
1832
 
            names = sorted(map(decode_filename, _listdir(top)))
 
1794
            for entry in scandir(top):
 
1795
                name = decode_filename(entry.name)
 
1796
                statvalue = entry.stat(follow_symlinks=False)
 
1797
                kind = file_kind_from_stat_mode(statvalue.st_mode)
 
1798
                dirblock.append((relprefix + name, name, kind, statvalue, entry.path))
1833
1799
        except OSError as e:
1834
1800
            if not _is_error_enotdir(e):
1835
1801
                raise
1836
 
        else:
1837
 
            for name in names:
1838
 
                abspath = top_slash + name
1839
 
                statvalue = _lstat(abspath)
1840
 
                kind = _kind_from_mode(statvalue.st_mode)
1841
 
                append((relprefix + name, name, kind, statvalue, abspath))
 
1802
        except UnicodeDecodeError as e:
 
1803
            raise errors.BadFilenameEncoding(e.object, _fs_enc)
 
1804
        dirblock.sort()
1842
1805
        yield (relroot, top), dirblock
1843
1806
 
1844
1807
        # push the user specified dirs from dirblock
1954
1917
        def _fs_decode(s): return s.decode(_fs_enc)
1955
1918
 
1956
1919
        def _fs_encode(s): return s.encode(_fs_enc)
1957
 
        _lstat = os.lstat
1958
 
        _listdir = os.listdir
1959
 
        _kind_from_mode = file_kind_from_stat_mode
1960
1920
 
1961
1921
        if prefix:
1962
1922
            relprefix = prefix + b'/'
1966
1926
 
1967
1927
        dirblock = []
1968
1928
        append = dirblock.append
1969
 
        for name_native in _listdir(top.encode('utf-8')):
 
1929
        for entry in scandir(safe_utf8(top)):
1970
1930
            try:
1971
 
                name = _fs_decode(name_native)
 
1931
                name = _fs_decode(entry.name)
1972
1932
            except UnicodeDecodeError:
1973
1933
                raise errors.BadFilenameEncoding(
1974
 
                    relprefix + name_native, _fs_enc)
 
1934
                    relprefix + entry.name, _fs_enc)
 
1935
            abspath = top_slash + name
1975
1936
            name_utf8 = _utf8_encode(name)[0]
1976
 
            abspath = top_slash + name
1977
 
            statvalue = _lstat(abspath)
1978
 
            kind = _kind_from_mode(statvalue.st_mode)
 
1937
            statvalue = entry.stat(follow_symlinks=False)
 
1938
            kind = file_kind_from_stat_mode(statvalue.st_mode)
1979
1939
            append((relprefix + name_utf8, name_utf8, kind, statvalue, abspath))
1980
1940
        return sorted(dirblock)
1981
1941
 
2126
2086
        return win32utils.get_host_name()
2127
2087
    else:
2128
2088
        import socket
2129
 
        if PY3:
2130
 
            return socket.gethostname()
2131
 
        return socket.gethostname().decode(get_user_encoding())
 
2089
        return socket.gethostname()
2132
2090
 
2133
2091
 
2134
2092
# We must not read/write any more than 64k at a time from/to a socket so we
2713
2671
    return _FILESYSTEM_FINDER.find(path)
2714
2672
 
2715
2673
 
2716
 
if PY3:
2717
 
    perf_counter = time.perf_counter
2718
 
else:
2719
 
    perf_counter = time.clock
 
2674
perf_counter = time.perf_counter