/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-02-18 01:57:45 UTC
  • mto: This revision was merged to the branch mainline in revision 7493.
  • Revision ID: jelmer@jelmer.uk-20200218015745-q2ss9tsk74h4nh61
drop use of future.

Show diffs side-by-side

added added

removed removed

Lines of Context:
83
83
        self.timezone = timezone
84
84
 
85
85
 
 
86
def get_unicode_argv():
 
87
    return sys.argv[1:]
 
88
 
 
89
 
86
90
def make_readonly(filename):
87
91
    """Make a filename read-only."""
88
92
    mod = os.lstat(filename).st_mode
307
311
    return path
308
312
 
309
313
 
 
314
def _posix_path_from_environ(key):
 
315
    """Get unicode path from `key` in environment or None if not present
 
316
 
 
317
    Note that posix systems use arbitrary byte strings for filesystem objects,
 
318
    so a path that raises BadFilenameEncoding here may still be accessible.
 
319
    """
 
320
    return os.environ.get(key, None)
 
321
 
 
322
 
310
323
def _posix_get_home_dir():
311
324
    """Get the home directory of the current user as a unicode path"""
312
325
    path = posixpath.expanduser("~")
417
430
realpath = _posix_realpath
418
431
pathjoin = os.path.join
419
432
normpath = _posix_normpath
 
433
path_from_environ = _posix_path_from_environ
420
434
_get_home_dir = _posix_get_home_dir
421
435
getuser_unicode = _posix_getuser_unicode
422
436
getcwd = _getcwd
474
488
        """Replacer for shutil.rmtree: could remove readonly dirs/files"""
475
489
        return shutil.rmtree(path, ignore_errors, onerror)
476
490
 
 
491
    get_unicode_argv = getattr(win32utils, 'get_unicode_argv', get_unicode_argv)
 
492
    path_from_environ = win32utils.get_environ_unicode
477
493
    _get_home_dir = win32utils.get_home_location
478
494
    getuser_unicode = win32utils.get_user_name
479
495
 
1267
1283
 
1268
1284
    abs_base = abspath(base)
1269
1285
    current = abs_base
 
1286
    _listdir = os.listdir
1270
1287
 
1271
1288
    # use an explicit iterator so we can easily consume the rest on early exit.
1272
1289
    bit_iter = iter(rel.split('/'))
1273
1290
    for bit in bit_iter:
1274
1291
        lbit = bit.lower()
1275
1292
        try:
1276
 
            next_entries = scandir(current)
 
1293
            next_entries = _listdir(current)
1277
1294
        except OSError:  # enoent, eperm, etc
1278
1295
            # We can't find this in the filesystem, so just append the
1279
1296
            # remaining bits.
1280
1297
            current = pathjoin(current, bit, *list(bit_iter))
1281
1298
            break
1282
 
        for entry in next_entries:
1283
 
            if lbit == entry.name.lower():
1284
 
                current = entry.path
 
1299
        for look in next_entries:
 
1300
            if lbit == look.lower():
 
1301
                current = pathjoin(current, look)
1285
1302
                break
1286
1303
        else:
1287
1304
            # got to the end, nothing matched, so we just return the
1362
1379
    return unicode_or_utf8_string.encode('utf-8')
1363
1380
 
1364
1381
 
 
1382
def safe_revision_id(unicode_or_utf8_string):
 
1383
    """Revision ids should now be utf8, but at one point they were unicode.
 
1384
 
 
1385
    :param unicode_or_utf8_string: A possibly Unicode revision_id. (can also be
 
1386
        utf8 or None).
 
1387
    :return: None or a utf8 revision id.
 
1388
    """
 
1389
    if (unicode_or_utf8_string is None
 
1390
            or unicode_or_utf8_string.__class__ == bytes):
 
1391
        return unicode_or_utf8_string
 
1392
    raise TypeError('Unicode revision ids are no longer supported. '
 
1393
                    'Revision id generators should be creating utf8 revision '
 
1394
                    'ids.')
 
1395
 
 
1396
 
 
1397
def safe_file_id(unicode_or_utf8_string):
 
1398
    """File ids should now be utf8, but at one point they were unicode.
 
1399
 
 
1400
    This is the same as safe_utf8, except it uses the cached encode functions
 
1401
    to save a little bit of performance.
 
1402
 
 
1403
    :param unicode_or_utf8_string: A possibly Unicode file_id. (can also be
 
1404
        utf8 or None).
 
1405
    :return: None or a utf8 file id.
 
1406
    """
 
1407
    if (unicode_or_utf8_string is None
 
1408
            or unicode_or_utf8_string.__class__ == bytes):
 
1409
        return unicode_or_utf8_string
 
1410
    raise TypeError('Unicode file ids are no longer supported. '
 
1411
                    'File id generators should be creating utf8 file ids.')
 
1412
 
 
1413
 
1365
1414
_platform_normalizes_filenames = False
1366
1415
if sys.platform == 'darwin':
1367
1416
    _platform_normalizes_filenames = True
1663
1712
_WIN32_ERROR_DIRECTORY = 267  # Similar to errno.ENOTDIR
1664
1713
 
1665
1714
 
1666
 
try:
1667
 
    scandir = os.scandir
1668
 
except AttributeError:  # Python < 3
1669
 
    lazy_import(globals(), """\
1670
 
from scandir import scandir
1671
 
""")
1672
 
 
1673
 
 
1674
1715
def _is_error_enotdir(e):
1675
1716
    """Check if this exception represents ENOTDIR.
1676
1717
 
1730
1771
    # depending on top and prefix - i.e. ./foo and foo as a pair leads to
1731
1772
    # potentially confusing output. We should make this more robust - but
1732
1773
    # not at a speed cost. RBC 20060731
 
1774
    _lstat = os.lstat
1733
1775
    _directory = _directory_kind
 
1776
    _listdir = os.listdir
 
1777
    _kind_from_mode = file_kind_from_stat_mode
1734
1778
    pending = [(safe_unicode(prefix), "", _directory, None, safe_unicode(top))]
1735
1779
    while pending:
1736
1780
        # 0 - relpath, 1- basename, 2- kind, 3- stat, 4-toppath
1742
1786
        top_slash = top + u'/'
1743
1787
 
1744
1788
        dirblock = []
 
1789
        append = dirblock.append
1745
1790
        try:
1746
 
            for entry in scandir(top):
1747
 
                name = decode_filename(entry.name)
1748
 
                statvalue = entry.stat(follow_symlinks=False)
1749
 
                kind = file_kind_from_stat_mode(statvalue.st_mode)
1750
 
                dirblock.append((relprefix + name, name, kind, statvalue, entry.path))
 
1791
            names = sorted(map(decode_filename, _listdir(top)))
1751
1792
        except OSError as e:
1752
1793
            if not _is_error_enotdir(e):
1753
1794
                raise
1754
 
        except UnicodeDecodeError as e:
1755
 
            raise errors.BadFilenameEncoding(e.object, _fs_enc)
1756
 
        dirblock.sort()
 
1795
        else:
 
1796
            for name in names:
 
1797
                abspath = top_slash + name
 
1798
                statvalue = _lstat(abspath)
 
1799
                kind = _kind_from_mode(statvalue.st_mode)
 
1800
                append((relprefix + name, name, kind, statvalue, abspath))
1757
1801
        yield (relroot, top), dirblock
1758
1802
 
1759
1803
        # push the user specified dirs from dirblock
1869
1913
        def _fs_decode(s): return s.decode(_fs_enc)
1870
1914
 
1871
1915
        def _fs_encode(s): return s.encode(_fs_enc)
 
1916
        _lstat = os.lstat
 
1917
        _listdir = os.listdir
 
1918
        _kind_from_mode = file_kind_from_stat_mode
1872
1919
 
1873
1920
        if prefix:
1874
1921
            relprefix = prefix + b'/'
1878
1925
 
1879
1926
        dirblock = []
1880
1927
        append = dirblock.append
1881
 
        for entry in scandir(safe_utf8(top)):
 
1928
        for name_native in _listdir(top.encode('utf-8')):
1882
1929
            try:
1883
 
                name = _fs_decode(entry.name)
 
1930
                name = _fs_decode(name_native)
1884
1931
            except UnicodeDecodeError:
1885
1932
                raise errors.BadFilenameEncoding(
1886
 
                    relprefix + entry.name, _fs_enc)
 
1933
                    relprefix + name_native, _fs_enc)
 
1934
            name_utf8 = _utf8_encode(name)[0]
1887
1935
            abspath = top_slash + name
1888
 
            name_utf8 = _utf8_encode(name)[0]
1889
 
            statvalue = entry.stat(follow_symlinks=False)
1890
 
            kind = file_kind_from_stat_mode(statvalue.st_mode)
 
1936
            statvalue = _lstat(abspath)
 
1937
            kind = _kind_from_mode(statvalue.st_mode)
1891
1938
            append((relprefix + name_utf8, name_utf8, kind, statvalue, abspath))
1892
1939
        return sorted(dirblock)
1893
1940
 
2537
2584
            raise exception_class(path)
2538
2585
 
2539
2586
 
 
2587
def is_environment_error(evalue):
 
2588
    """True if exception instance is due to a process environment issue
 
2589
 
 
2590
    This includes OSError and IOError, but also other errors that come from
 
2591
    the operating system or core libraries but are not subclasses of those.
 
2592
    """
 
2593
    if isinstance(evalue, (EnvironmentError, select.error)):
 
2594
        return True
 
2595
    if sys.platform == "win32" and win32utils._is_pywintypes_error(evalue):
 
2596
        return True
 
2597
    return False
 
2598
 
 
2599
 
2540
2600
def read_mtab(path):
2541
2601
    """Read an fstab-style file and extract mountpoint+filesystem information.
2542
2602