/breezy/unstable

To get this branch, use:
bzr branch https://code.breezy-vcs.org/breezy/unstable

« back to all changes in this revision

Viewing changes to breezy/osutils.py

  • Committer: Jelmer Vernooij
  • Date: 2017-05-24 01:39:33 UTC
  • mfrom: (3815.3776.6)
  • Revision ID: jelmer@jelmer.uk-20170524013933-ir4y4tqtrsiz2ka2
New upstream snapshot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
import time
25
25
import codecs
26
26
 
27
 
from bzrlib.lazy_import import lazy_import
 
27
from .lazy_import import lazy_import
28
28
lazy_import(globals(), """
29
29
from datetime import datetime
 
30
from datetime import timedelta
30
31
import getpass
31
32
import locale
32
33
import ntpath
44
45
from tempfile import mkdtemp
45
46
import unicodedata
46
47
 
47
 
from bzrlib import (
 
48
from breezy import (
48
49
    cache_utf8,
49
50
    config,
50
51
    errors,
51
52
    trace,
52
53
    win32utils,
53
54
    )
54
 
from bzrlib.i18n import gettext
 
55
from breezy.i18n import gettext
55
56
""")
56
57
 
57
 
from bzrlib.symbol_versioning import (
 
58
from .sixish import (
 
59
    PY3,
 
60
    text_type,
 
61
    )
 
62
from .symbol_versioning import (
58
63
    DEPRECATED_PARAMETER,
59
64
    deprecated_function,
60
65
    deprecated_in,
68
73
    )
69
74
 
70
75
 
71
 
import bzrlib
72
 
from bzrlib import symbol_versioning, _fs_enc
 
76
import breezy
 
77
from . import symbol_versioning, _fs_enc
73
78
 
74
79
 
75
80
# Cross platform wall-clock time functionality with decent resolution.
93
98
 
94
99
 
95
100
def get_unicode_argv():
 
101
    if PY3:
 
102
        return sys.argv[1:]
96
103
    try:
97
104
        user_encoding = get_user_encoding()
98
105
        return [a.decode(user_encoding) for a in sys.argv[1:]]
105
112
    """Make a filename read-only."""
106
113
    mod = os.lstat(filename).st_mode
107
114
    if not stat.S_ISLNK(mod):
108
 
        mod = mod & 0777555
 
115
        mod = mod & 0o777555
109
116
        chmod_if_possible(filename, mod)
110
117
 
111
118
 
112
119
def make_writable(filename):
113
120
    mod = os.lstat(filename).st_mode
114
121
    if not stat.S_ISLNK(mod):
115
 
        mod = mod | 0200
 
122
        mod = mod | 0o200
116
123
        chmod_if_possible(filename, mod)
117
124
 
118
125
 
124
131
        # It is probably faster to just do the chmod, rather than
125
132
        # doing a stat, and then trying to compare
126
133
        os.chmod(filename, mode)
127
 
    except (IOError, OSError),e:
 
134
    except (IOError, OSError) as e:
128
135
        # Permission/access denied seems to commonly happen on smbfs; there's
129
136
        # probably no point warning about it.
130
137
        # <https://bugs.launchpad.net/bzr/+bug/606537>
213
220
            stat = getattr(os, 'lstat', os.stat)
214
221
            stat(f)
215
222
            return True
216
 
        except OSError, e:
 
223
        except OSError as e:
217
224
            if e.errno == errno.ENOENT:
218
225
                return False;
219
226
            else:
247
254
    file_existed = False
248
255
    try:
249
256
        rename_func(new, tmp_name)
250
 
    except (errors.NoSuchFile,), e:
 
257
    except (errors.NoSuchFile,) as e:
251
258
        pass
252
 
    except IOError, e:
 
259
    except IOError as e:
253
260
        # RBC 20060103 abstraction leakage: the paramiko SFTP clients rename
254
261
        # function raises an IOError with errno is None when a rename fails.
255
262
        # This then gets caught here.
256
263
        if e.errno not in (None, errno.ENOENT, errno.ENOTDIR):
257
264
            raise
258
 
    except Exception, e:
 
265
    except Exception as e:
259
266
        if (getattr(e, 'errno', None) is None
260
267
            or e.errno not in (errno.ENOENT, errno.ENOTDIR)):
261
268
            raise
262
269
    else:
263
270
        file_existed = True
264
271
 
265
 
    failure_exc = None
266
272
    success = False
267
273
    try:
268
 
        try:
269
 
            # This may throw an exception, in which case success will
270
 
            # not be set.
271
 
            rename_func(old, new)
272
 
            success = True
273
 
        except (IOError, OSError), e:
274
 
            # source and target may be aliases of each other (e.g. on a
275
 
            # case-insensitive filesystem), so we may have accidentally renamed
276
 
            # source by when we tried to rename target
277
 
            failure_exc = sys.exc_info()
278
 
            if (file_existed and e.errno in (None, errno.ENOENT)
279
 
                and old.lower() == new.lower()):
280
 
                # source and target are the same file on a case-insensitive
281
 
                # filesystem, so we don't generate an exception
282
 
                failure_exc = None
 
274
        # This may throw an exception, in which case success will
 
275
        # not be set.
 
276
        rename_func(old, new)
 
277
        success = True
 
278
    except (IOError, OSError) as e:
 
279
        # source and target may be aliases of each other (e.g. on a
 
280
        # case-insensitive filesystem), so we may have accidentally renamed
 
281
        # source by when we tried to rename target
 
282
        if (file_existed and e.errno in (None, errno.ENOENT)
 
283
            and old.lower() == new.lower()):
 
284
            # source and target are the same file on a case-insensitive
 
285
            # filesystem, so we don't generate an exception
 
286
            pass
 
287
        else:
 
288
            raise
283
289
    finally:
284
290
        if file_existed:
285
291
            # If the file used to exist, rename it back into place
288
294
                unlink_func(tmp_name)
289
295
            else:
290
296
                rename_func(tmp_name, new)
291
 
    if failure_exc is not None:
292
 
        try:
293
 
            raise failure_exc[0], failure_exc[1], failure_exc[2]
294
 
        finally:
295
 
            del failure_exc
296
297
 
297
298
 
298
299
# In Python 2.4.2 and older, os.path.abspath and os.path.realpath
347
348
    path = posixpath.expanduser("~")
348
349
    try:
349
350
        return path.decode(_fs_enc)
 
351
    except AttributeError:
 
352
        return path
350
353
    except UnicodeDecodeError:
351
354
        raise errors.BadFilenameEncoding(path, _fs_enc)
352
355
 
396
399
    # check for absolute path
397
400
    drive = ntpath.splitdrive(path)[0]
398
401
    if drive == '' and path[:2] not in('//','\\\\'):
399
 
        cwd = os.getcwdu()
 
402
        cwd = _getcwd()
400
403
        # we cannot simply os.path.join cwd and path
401
404
        # because os.path.join('C:','/path') produce '/path'
402
405
        # and this is incorrect
421
424
 
422
425
 
423
426
def _win32_getcwd():
424
 
    return _win32_fixdrive(os.getcwdu().replace('\\', '/'))
 
427
    return _win32_fixdrive(_getcwd().replace('\\', '/'))
425
428
 
426
429
 
427
430
def _win32_mkdtemp(*args, **kwargs):
436
439
    """
437
440
    try:
438
441
        fancy_rename(old, new, rename_func=os.rename, unlink_func=os.unlink)
439
 
    except OSError, e:
 
442
    except OSError as e:
440
443
        if e.errno in (errno.EPERM, errno.EACCES, errno.EBUSY, errno.EINVAL):
441
444
            # If we try to rename a non-existant file onto cwd, we get
442
445
            # EPERM or EACCES instead of ENOENT, this will raise ENOENT
447
450
 
448
451
 
449
452
def _mac_getcwd():
450
 
    return unicodedata.normalize('NFC', os.getcwdu())
 
453
    return unicodedata.normalize('NFC', _getcwd())
451
454
 
452
455
 
453
456
def _rename_wrap_exception(rename_func):
460
463
    def _rename_wrapper(old, new):
461
464
        try:
462
465
            rename_func(old, new)
463
 
        except OSError, e:
 
466
        except OSError as e:
464
467
            detailed_error = OSError(e.errno, e.strerror +
465
468
                                " [occurred when renaming '%s' to '%s']" %
466
469
                                (old, new))
470
473
 
471
474
    return _rename_wrapper
472
475
 
 
476
 
 
477
if sys.version_info > (3,):
 
478
    _getcwd = os.getcwd
 
479
else:
 
480
    _getcwd = os.getcwdu
 
481
 
 
482
 
473
483
# Default rename wraps os.rename()
474
484
rename = _rename_wrap_exception(os.rename)
475
485
 
482
492
path_from_environ = _posix_path_from_environ
483
493
_get_home_dir = _posix_get_home_dir
484
494
getuser_unicode = _posix_getuser_unicode
485
 
getcwd = os.getcwdu
 
495
getcwd = _getcwd
486
496
dirname = os.path.dirname
487
497
basename = os.path.basename
488
498
split = os.path.split
512
522
    mkdtemp = _win32_mkdtemp
513
523
    rename = _rename_wrap_exception(_win32_rename)
514
524
    try:
515
 
        from bzrlib import _walkdirs_win32
 
525
        from . import _walkdirs_win32
516
526
    except ImportError:
517
527
        pass
518
528
    else:
565
575
 
566
576
    :param trace: If True trace the selected encoding via mutter().
567
577
    """
568
 
    from bzrlib.trace import mutter
 
578
    from .trace import mutter
569
579
    output_encoding = getattr(sys.stdout, 'encoding', None)
570
580
    if not output_encoding:
571
581
        input_encoding = getattr(sys.stdin, 'encoding', None)
593
603
    try:
594
604
        codecs.lookup(output_encoding)
595
605
    except LookupError:
596
 
        sys.stderr.write('bzr: warning:'
 
606
        sys.stderr.write('brz: warning:'
597
607
                         ' unknown terminal encoding %s.\n'
598
608
                         '  Using encoding %s instead.\n'
599
609
                         % (output_encoding, get_user_encoding())
827
837
            return True
828
838
 
829
839
 
 
840
def gmtime(seconds=None):
 
841
    """Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a.
 
842
    GMT). When 'seconds' is not passed in, convert the current time instead.
 
843
    Handy replacement for time.gmtime() buggy on Windows and 32-bit platforms.
 
844
    """
 
845
    if seconds is None:
 
846
        seconds = time.time()
 
847
    return (datetime(1970, 1, 1) + timedelta(seconds=seconds)).timetuple()
 
848
 
 
849
 
830
850
def local_time_offset(t=None):
831
851
    """Return offset of local zone from GMT, either at present or at time t."""
832
852
    if t is None:
872
892
    """
873
893
    if offset is None:
874
894
        offset = 0
875
 
    tt = time.gmtime(t + offset)
 
895
    tt = gmtime(t + offset)
876
896
    date_fmt = _default_format_by_weekday_num[tt[6]]
877
897
    date_str = time.strftime(date_fmt, tt)
878
898
    offset_str = _cache.get(offset, None)
897
917
    (date_fmt, tt, offset_str) = \
898
918
               _format_date(t, offset, timezone, date_fmt, show_offset)
899
919
    date_str = time.strftime(date_fmt, tt)
900
 
    if not isinstance(date_str, unicode):
 
920
    if not isinstance(date_str, text_type):
901
921
        date_str = date_str.decode(get_user_encoding(), 'replace')
902
922
    return date_str + offset_str
903
923
 
904
924
 
905
925
def _format_date(t, offset, timezone, date_fmt, show_offset):
906
926
    if timezone == 'utc':
907
 
        tt = time.gmtime(t)
 
927
        tt = gmtime(t)
908
928
        offset = 0
909
929
    elif timezone == 'original':
910
930
        if offset is None:
911
931
            offset = 0
912
 
        tt = time.gmtime(t + offset)
 
932
        tt = gmtime(t + offset)
913
933
    elif timezone == 'local':
914
934
        tt = time.localtime(t)
915
935
        offset = local_time_offset(t)
925
945
 
926
946
 
927
947
def compact_date(when):
928
 
    return time.strftime('%Y%m%d%H%M%S', time.gmtime(when))
 
948
    return time.strftime('%Y%m%d%H%M%S', gmtime(when))
929
949
 
930
950
 
931
951
def format_delta(delta):
1066
1086
    implementation should be loaded instead::
1067
1087
 
1068
1088
    >>> try:
1069
 
    >>>     import bzrlib._fictional_extension_pyx
 
1089
    >>>     import breezy._fictional_extension_pyx
1070
1090
    >>> except ImportError, e:
1071
 
    >>>     bzrlib.osutils.failed_to_load_extension(e)
1072
 
    >>>     import bzrlib._fictional_extension_py
 
1091
    >>>     breezy.osutils.failed_to_load_extension(e)
 
1092
    >>>     import breezy._fictional_extension_py
1073
1093
    """
1074
1094
    # NB: This docstring is just an example, not a doctest, because doctest
1075
1095
    # currently can't cope with the use of lazy imports in this namespace --
1091
1111
    if config.GlobalStack().get('ignore_missing_extensions'):
1092
1112
        return
1093
1113
    # the warnings framework should by default show this only once
1094
 
    from bzrlib.trace import warning
 
1114
    from .trace import warning
1095
1115
    warning(
1096
 
        "bzr: warning: some compiled extensions could not be loaded; "
 
1116
        "brz: warning: some compiled extensions could not be loaded; "
1097
1117
        "see <https://answers.launchpad.net/bzr/+faq/703>")
1098
1118
    # we no longer show the specific missing extensions here, because it makes
1099
1119
    # the message too long and scary - see
1101
1121
 
1102
1122
 
1103
1123
try:
1104
 
    from bzrlib._chunks_to_lines_pyx import chunks_to_lines
1105
 
except ImportError, e:
 
1124
    from ._chunks_to_lines_pyx import chunks_to_lines
 
1125
except ImportError as e:
1106
1126
    failed_to_load_extension(e)
1107
 
    from bzrlib._chunks_to_lines_py import chunks_to_lines
 
1127
    from ._chunks_to_lines_py import chunks_to_lines
1108
1128
 
1109
1129
 
1110
1130
def split_lines(s):
1141
1161
        return
1142
1162
    try:
1143
1163
        os.link(src, dest)
1144
 
    except (OSError, IOError), e:
 
1164
    except (OSError, IOError) as e:
1145
1165
        if e.errno != errno.EXDEV:
1146
1166
            raise
1147
1167
        shutil.copyfile(src, dest)
1154
1174
    """
1155
1175
    try:
1156
1176
       _delete_file_or_dir(path)
1157
 
    except (OSError, IOError), e:
 
1177
    except (OSError, IOError) as e:
1158
1178
        if e.errno in (errno.EPERM, errno.EACCES):
1159
1179
            # make writable and try again
1160
1180
            try:
1352
1372
    Otherwise it is decoded from the the filesystem's encoding. If decoding
1353
1373
    fails, a errors.BadFilenameEncoding exception is raised.
1354
1374
    """
1355
 
    if type(filename) is unicode:
 
1375
    if isinstance(filename, text_type):
1356
1376
        return filename
1357
1377
    try:
1358
1378
        return filename.decode(_fs_enc)
1367
1387
    Otherwise it is decoded from utf-8. If decoding fails, the exception is
1368
1388
    wrapped in a BzrBadParameterNotUnicode exception.
1369
1389
    """
1370
 
    if isinstance(unicode_or_utf8_string, unicode):
 
1390
    if isinstance(unicode_or_utf8_string, text_type):
1371
1391
        return unicode_or_utf8_string
1372
1392
    try:
1373
1393
        return unicode_or_utf8_string.decode('utf8')
1540
1560
    None is returned if the width can't established precisely.
1541
1561
 
1542
1562
    The rules are:
1543
 
    - if BZR_COLUMNS is set, returns its value
 
1563
    - if BRZ_COLUMNS is set, returns its value
1544
1564
    - if there is no controlling terminal, returns None
1545
1565
    - query the OS, if the queried size has changed since the last query,
1546
1566
      return its value,
1561
1581
    # Note to implementors: if changing the rules for determining the width,
1562
1582
    # make sure you've considered the behaviour in these cases:
1563
1583
    #  - M-x shell in emacs, where $COLUMNS is set and TIOCGWINSZ returns 0,0.
1564
 
    #  - bzr log | less, in bash, where $COLUMNS not set and TIOCGWINSZ returns
 
1584
    #  - brz log | less, in bash, where $COLUMNS not set and TIOCGWINSZ returns
1565
1585
    #    0,0.
1566
1586
    #  - (add more interesting cases here, if you find any)
1567
1587
    # Some programs implement "Use $COLUMNS (if set) until SIGWINCH occurs",
1571
1591
    # time so we can notice if the reported size has changed, which should have
1572
1592
    # a similar effect.
1573
1593
 
1574
 
    # If BZR_COLUMNS is set, take it, user is always right
 
1594
    # If BRZ_COLUMNS is set, take it, user is always right
1575
1595
    # Except if they specified 0 in which case, impose no limit here
1576
1596
    try:
1577
 
        width = int(os.environ['BZR_COLUMNS'])
 
1597
        width = int(os.environ['BRZ_COLUMNS'])
1578
1598
    except (KeyError, ValueError):
1579
1599
        width = None
1580
1600
    if width is not None:
1585
1605
 
1586
1606
    isatty = getattr(sys.stdout, 'isatty', None)
1587
1607
    if isatty is None or not isatty():
1588
 
        # Don't guess, setting BZR_COLUMNS is the recommended way to override.
 
1608
        # Don't guess, setting BRZ_COLUMNS is the recommended way to override.
1589
1609
        return None
1590
1610
 
1591
1611
    # Query the OS
1679
1699
        if orig_val is not None:
1680
1700
            del os.environ[env_variable]
1681
1701
    else:
1682
 
        if isinstance(value, unicode):
 
1702
        if not PY3 and isinstance(value, text_type):
1683
1703
            value = value.encode(get_user_encoding())
1684
1704
        os.environ[env_variable] = value
1685
1705
    return orig_val
1778
1798
        append = dirblock.append
1779
1799
        try:
1780
1800
            names = sorted(map(decode_filename, _listdir(top)))
1781
 
        except OSError, e:
 
1801
        except OSError as e:
1782
1802
            if not _is_error_enotdir(e):
1783
1803
                raise
1784
1804
        else:
1844
1864
            #       but that gets a bit tricky, and requires custom compiling
1845
1865
            #       for win98 anyway.
1846
1866
            try:
1847
 
                from bzrlib._walkdirs_win32 import Win32ReadDir
 
1867
                from ._walkdirs_win32 import Win32ReadDir
1848
1868
                _selected_dir_reader = Win32ReadDir()
1849
1869
            except ImportError:
1850
1870
                pass
1851
1871
        elif _fs_enc in ('utf-8', 'ascii'):
1852
1872
            try:
1853
 
                from bzrlib._readdir_pyx import UTF8DirReader
 
1873
                from ._readdir_pyx import UTF8DirReader
1854
1874
                _selected_dir_reader = UTF8DirReader()
1855
 
            except ImportError, e:
 
1875
            except ImportError as e:
1856
1876
                failed_to_load_extension(e)
1857
1877
                pass
1858
1878
 
1988
2008
    try:
1989
2009
        s = os.stat(src)
1990
2010
        chown(dst, s.st_uid, s.st_gid)
1991
 
    except OSError, e:
 
2011
    except OSError as e:
1992
2012
        trace.warning(
1993
2013
            'Unable to copy ownership from "%s" to "%s". '
1994
2014
            'You may want to set it manually.', src, dst)
2043
2063
        user_encoding = codecs.lookup(user_encoding).name
2044
2064
    except LookupError:
2045
2065
        if user_encoding not in ("", "cp0"):
2046
 
            sys.stderr.write('bzr: warning:'
 
2066
            sys.stderr.write('brz: warning:'
2047
2067
                             ' unknown encoding %s.'
2048
2068
                             ' Continuing with ascii encoding.\n'
2049
2069
                             % user_encoding
2102
2122
    empty string rather than raise an error), and repeats the recv if
2103
2123
    interrupted by a signal.
2104
2124
    """
2105
 
    while 1:
 
2125
    while True:
2106
2126
        try:
2107
2127
            bytes = sock.recv(max_read_size)
2108
 
        except socket.error, e:
 
2128
        except socket.error as e:
2109
2129
            eno = e.args[0]
2110
2130
            if eno in _end_of_stream_errors:
2111
2131
                # The connection was closed by the other side.  Callers expect
2158
2178
    while sent_total < byte_count:
2159
2179
        try:
2160
2180
            sent = sock.send(buffer(bytes, sent_total, MAX_SOCKET_CHUNK))
2161
 
        except (socket.error, IOError), e:
 
2181
        except (socket.error, IOError) as e:
2162
2182
            if e.args[0] in _end_of_stream_errors:
2163
2183
                raise errors.ConnectionReset(
2164
2184
                    "Error trying to write to socket", e)
2189
2209
            sock.connect(sa)
2190
2210
            return sock
2191
2211
 
2192
 
        except socket.error, err:
 
2212
        except socket.error as err:
2193
2213
            # 'err' is now the most recent error
2194
2214
            if sock is not None:
2195
2215
                sock.close()
2218
2238
def resource_string(package, resource_name):
2219
2239
    """Load a resource from a package and return it as a string.
2220
2240
 
2221
 
    Note: Only packages that start with bzrlib are currently supported.
 
2241
    Note: Only packages that start with breezy are currently supported.
2222
2242
 
2223
2243
    This is designed to be a lightweight implementation of resource
2224
2244
    loading in a way which is API compatible with the same API from
2227
2247
    If and when pkg_resources becomes a standard library, this routine
2228
2248
    can delegate to it.
2229
2249
    """
2230
 
    # Check package name is within bzrlib
2231
 
    if package == "bzrlib":
 
2250
    # Check package name is within breezy
 
2251
    if package == "breezy":
2232
2252
        resource_relpath = resource_name
2233
 
    elif package.startswith("bzrlib."):
2234
 
        package = package[len("bzrlib."):].replace('.', os.sep)
 
2253
    elif package.startswith("breezy."):
 
2254
        package = package[len("breezy."):].replace('.', os.sep)
2235
2255
        resource_relpath = pathjoin(package, resource_name)
2236
2256
    else:
2237
 
        raise errors.BzrError('resource package %s not in bzrlib' % package)
 
2257
        raise errors.BzrError('resource package %s not in breezy' % package)
2238
2258
 
2239
2259
    # Map the resource to a file and read its contents
2240
 
    base = dirname(bzrlib.__file__)
 
2260
    base = dirname(breezy.__file__)
2241
2261
    if getattr(sys, 'frozen', None):    # bzr.exe
2242
2262
        base = abspath(pathjoin(base, '..', '..'))
2243
2263
    f = file(pathjoin(base, resource_relpath), "rU")
2250
2270
    global file_kind_from_stat_mode
2251
2271
    if file_kind_from_stat_mode is file_kind_from_stat_mode_thunk:
2252
2272
        try:
2253
 
            from bzrlib._readdir_pyx import UTF8DirReader
 
2273
            from ._readdir_pyx import UTF8DirReader
2254
2274
            file_kind_from_stat_mode = UTF8DirReader().kind_from_mode
2255
 
        except ImportError, e:
 
2275
        except ImportError as e:
2256
2276
            # This is one time where we won't warn that an extension failed to
2257
2277
            # load. The extension is never available on Windows anyway.
2258
 
            from bzrlib._readdir_py import (
 
2278
            from ._readdir_py import (
2259
2279
                _kind_from_mode as file_kind_from_stat_mode
2260
2280
                )
2261
2281
    return file_kind_from_stat_mode(mode)
2265
2285
    try:
2266
2286
        # XXX cache?
2267
2287
        return _lstat(f)
2268
 
    except OSError, e:
 
2288
    except OSError as e:
2269
2289
        if getattr(e, 'errno', None) in (errno.ENOENT, errno.ENOTDIR):
2270
2290
            raise errors.NoSuchFile(f)
2271
2291
        raise
2284
2304
    Keep in mind that this is not a complete solution to EINTR.  There is
2285
2305
    probably code in the Python standard library and other dependencies that
2286
2306
    may encounter EINTR if a signal arrives (and there is signal handler for
2287
 
    that signal).  So this function can reduce the impact for IO that bzrlib
 
2307
    that signal).  So this function can reduce the impact for IO that breezy
2288
2308
    directly controls, but it is not a complete solution.
2289
2309
    """
2290
2310
    # Borrowed from Twisted's twisted.python.util.untilConcludes function.
2291
2311
    while True:
2292
2312
        try:
2293
2313
            return f(*a, **kw)
2294
 
        except (IOError, OSError), e:
 
2314
        except (IOError, OSError) as e:
2295
2315
            if e.errno == errno.EINTR:
2296
2316
                continue
2297
2317
            raise
2313
2333
        re_obj = re.compile(re_string, flags)
2314
2334
        re_obj.search("")
2315
2335
        return re_obj
2316
 
    except errors.InvalidPattern, e:
 
2336
    except errors.InvalidPattern as e:
2317
2337
        if where:
2318
2338
            where = ' in ' + where
2319
2339
        # despite the name 'error' is a type
2379
2399
    if _cached_local_concurrency is not None and use_cache:
2380
2400
        return _cached_local_concurrency
2381
2401
 
2382
 
    concurrency = os.environ.get('BZR_CONCURRENCY', None)
 
2402
    concurrency = os.environ.get('BRZ_CONCURRENCY', None)
2383
2403
    if concurrency is None:
2384
2404
        try:
2385
2405
            import multiprocessing
2409
2429
        self.encode = encode
2410
2430
 
2411
2431
    def write(self, object):
2412
 
        if type(object) is str:
 
2432
        if isinstance(object, str):
2413
2433
            self.stream.write(object)
2414
2434
        else:
2415
2435
            data, _ = self.encode(object, self.errors)
2533
2553
    try:
2534
2554
        # Special meaning of unix kill: just check if it's there.
2535
2555
        os.kill(pid, 0)
2536
 
    except OSError, e:
 
2556
    except OSError as e:
2537
2557
        if e.errno == errno.ESRCH:
2538
2558
            # On this machine, and really not found: as sure as we can be
2539
2559
            # that it's dead.
2569
2589
    if fn is not None:
2570
2590
        try:
2571
2591
            fn(fileno)
2572
 
        except IOError, e:
 
2592
        except IOError as e:
2573
2593
            # See bug #1075108, on some platforms fdatasync exists, but can
2574
2594
            # raise ENOTSUP. However, we are calling fdatasync to be helpful
2575
2595
            # and reduce the chance of corruption-on-powerloss situations. It
2587
2607
    """
2588
2608
    try:
2589
2609
        os.mkdir(path)
2590
 
    except OSError, e:
 
2610
    except OSError as e:
2591
2611
        if e.errno != errno.EEXIST:
2592
2612
            raise
2593
2613
        if os.listdir(path) != []: