70
72
from bzrlib import symbol_versioning
75
# Cross platform wall-clock time functionality with decent resolution.
76
# On Linux ``time.clock`` returns only CPU time. On Windows, ``time.time()``
77
# only has a resolution of ~15ms. Note that ``time.clock()`` is not
78
# synchronized with ``time.time()``, this is only meant to be used to find
79
# delta times by subtracting from another call to this function.
80
timer_func = time.time
81
if sys.platform == 'win32':
82
timer_func = time.clock
73
84
# On win32, O_BINARY is used to indicate the file should
74
85
# be opened in binary mode, rather than text mode.
75
86
# On other platforms, O_BINARY doesn't exist, because
234
246
# source and target may be aliases of each other (e.g. on a
235
247
# case-insensitive filesystem), so we may have accidentally renamed
236
248
# source by when we tried to rename target
237
if not (file_existed and e.errno in (None, errno.ENOENT)):
249
failure_exc = sys.exc_info()
250
if (file_existed and e.errno in (None, errno.ENOENT)
251
and old.lower() == new.lower()):
252
# source and target are the same file on a case-insensitive
253
# filesystem, so we don't generate an exception
241
257
# If the file used to exist, rename it back into place
706
726
date_str = time.strftime(date_fmt, tt)
707
727
return date_str + offset_str
730
# Cache of formatted offset strings
734
def format_date_with_offset_in_original_timezone(t, offset=0,
735
_cache=_offset_cache):
736
"""Return a formatted date string in the original timezone.
738
This routine may be faster then format_date.
740
:param t: Seconds since the epoch.
741
:param offset: Timezone offset in seconds east of utc.
745
tt = time.gmtime(t + offset)
746
date_fmt = _default_format_by_weekday_num[tt[6]]
747
date_str = time.strftime(date_fmt, tt)
748
offset_str = _cache.get(offset, None)
749
if offset_str is None:
750
offset_str = ' %+03d%02d' % (offset / 3600, (offset / 60) % 60)
751
_cache[offset] = offset_str
752
return date_str + offset_str
709
755
def format_local_date(t, offset=0, timezone='original', date_fmt=None,
710
756
show_offset=True):
711
757
"""Return an unicode date string formatted according to the current locale.
931
_extension_load_failures = []
934
def failed_to_load_extension(exception):
935
"""Handle failing to load a binary extension.
937
This should be called from the ImportError block guarding the attempt to
938
import the native extension. If this function returns, the pure-Python
939
implementation should be loaded instead::
942
>>> import bzrlib._fictional_extension_pyx
943
>>> except ImportError, e:
944
>>> bzrlib.osutils.failed_to_load_extension(e)
945
>>> import bzrlib._fictional_extension_py
947
# NB: This docstring is just an example, not a doctest, because doctest
948
# currently can't cope with the use of lazy imports in this namespace --
951
# This currently doesn't report the failure at the time it occurs, because
952
# they tend to happen very early in startup when we can't check config
953
# files etc, and also we want to report all failures but not spam the user
955
from bzrlib import trace
956
exception_str = str(exception)
957
if exception_str not in _extension_load_failures:
958
trace.mutter("failed to load compiled extension: %s" % exception_str)
959
_extension_load_failures.append(exception_str)
962
def report_extension_load_failures():
963
if not _extension_load_failures:
965
from bzrlib.config import GlobalConfig
966
if GlobalConfig().get_user_option_as_bool('ignore_missing_extensions'):
968
# the warnings framework should by default show this only once
969
from bzrlib.trace import warning
971
"bzr: warning: some compiled extensions could not be loaded; "
972
"see <https://answers.launchpad.net/bzr/+faq/703>")
973
# we no longer show the specific missing extensions here, because it makes
974
# the message too long and scary - see
975
# https://bugs.launchpad.net/bzr/+bug/430529
885
979
from bzrlib._chunks_to_lines_pyx import chunks_to_lines
980
except ImportError, e:
981
failed_to_load_extension(e)
887
982
from bzrlib._chunks_to_lines_py import chunks_to_lines
1238
1340
normalized_filename = _inaccessible_normalized_filename
1343
default_terminal_width = 80
1344
"""The default terminal width for ttys.
1346
This is defined so that higher levels can share a common fallback value when
1347
terminal_width() returns None.
1241
1351
def terminal_width():
1242
"""Return estimated terminal width."""
1243
if sys.platform == 'win32':
1244
return win32utils.get_console_size()[0]
1352
"""Return terminal width.
1354
None is returned if the width can't established precisely.
1357
- if BZR_COLUMNS is set, returns its value
1358
- if there is no controlling terminal, returns None
1359
- if COLUMNS is set, returns its value,
1361
From there, we need to query the OS to get the size of the controlling
1365
- get termios.TIOCGWINSZ
1366
- if an error occurs or a negative value is obtained, returns None
1370
- win32utils.get_console_size() decides,
1371
- returns None on error (provided default value)
1374
# If BZR_COLUMNS is set, take it, user is always right
1376
return int(os.environ['BZR_COLUMNS'])
1377
except (KeyError, ValueError):
1380
isatty = getattr(sys.stdout, 'isatty', None)
1381
if isatty is None or not isatty():
1382
# Don't guess, setting BZR_COLUMNS is the recommended way to override.
1385
# If COLUMNS is set, take it, the terminal knows better (even inside a
1386
# given terminal, the application can decide to set COLUMNS to a lower
1387
# value (splitted screen) or a bigger value (scroll bars))
1389
return int(os.environ['COLUMNS'])
1390
except (KeyError, ValueError):
1393
width, height = _terminal_size(None, None)
1395
# Consider invalid values as meaning no width
1401
def _win32_terminal_size(width, height):
1402
width, height = win32utils.get_console_size(defaultx=width, defaulty=height)
1403
return width, height
1406
def _ioctl_terminal_size(width, height):
1247
1408
import struct, fcntl, termios
1248
1409
s = struct.pack('HHHH', 0, 0, 0, 0)
1249
1410
x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
1250
width = struct.unpack('HHHH', x)[1]
1411
height, width = struct.unpack('HHHH', x)[0:2]
1412
except (IOError, AttributeError):
1255
width = int(os.environ['COLUMNS'])
1414
return width, height
1416
_terminal_size = None
1417
"""Returns the terminal size as (width, height).
1419
:param width: Default value for width.
1420
:param height: Default value for height.
1422
This is defined specifically for each OS and query the size of the controlling
1423
terminal. If any error occurs, the provided default values should be returned.
1425
if sys.platform == 'win32':
1426
_terminal_size = _win32_terminal_size
1428
_terminal_size = _ioctl_terminal_size
1431
def _terminal_size_changed(signum, frame):
1432
"""Set COLUMNS upon receiving a SIGnal for WINdow size CHange."""
1433
width, height = _terminal_size(None, None)
1434
if width is not None:
1435
os.environ['COLUMNS'] = str(width)
1437
if sys.platform == 'win32':
1438
# Martin (gz) mentioned WINDOW_BUFFER_SIZE_RECORD from ReadConsoleInput but
1439
# I've no idea how to plug that in the current design -- vila 20091216
1442
signal.signal(signal.SIGWINCH, _terminal_size_changed)
1264
1445
def supports_executable():