Rev 4882: Fix minor issues and make test passing on windows for terminal_width() in http://bazaar.launchpad.net/~vila/bzr/integration
Vincent Ladeuil
v.ladeuil+lp at free.fr
Wed Dec 9 17:22:10 GMT 2009
At http://bazaar.launchpad.net/~vila/bzr/integration
------------------------------------------------------------
revno: 4882 [merge]
revision-id: v.ladeuil+lp at free.fr-20091209172154-cefhveeazvlbpy4r
parent: pqm at pqm.ubuntu.com-20091209083802-i7thqoq5irt2r4ya
parent: v.ladeuil+lp at free.fr-20091209150900-pbytmi9fh4fa3vbf
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: integration
timestamp: Wed 2009-12-09 18:21:54 +0100
message:
Fix minor issues and make test passing on windows for terminal_width()
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2009-12-09 05:47:32 +0000
+++ b/NEWS 2009-12-09 17:21:54 +0000
@@ -64,11 +64,13 @@
* Lots of bugfixes for the test suite on Windows. We should once again
have a test suite with no failures on Windows. (John Arbash Meinel)
-* ``osutils.terminal_width()`` obeys the BZR_COLUMNS envrionment
+* ``osutils.terminal_width()`` obeys the BZR_COLUMNS environment
variable but returns None if the terminal is not a tty (when output is
redirected for example). Also fixes its usage under OSes that doesn't
- provide termios.TIOCGWINSZ.
+ provide termios.TIOCGWINSZ. Make sure the corresponding tests runs on
+ windows too.
(Joke de Buhr, Vincent Ladeuil, #353370, #62539)
+ (John Arbash Meinel, Vincent Ladeuil, #492561)
* Terminate ssh subprocesses when no references to them remain, fixing
subprocess and file descriptor leaks. (Andrew Bennetts, #426662)
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py 2009-12-04 10:09:11 +0000
+++ b/bzrlib/osutils.py 2009-12-09 14:18:48 +0000
@@ -1342,6 +1342,23 @@
"""Return terminal width.
None is returned if the width can't established precisely.
+
+ The rules are:
+ - if BZR_COLUMNS is set, returns its value
+ - if there is no controlling terminal, returns None
+ - if COLUMNS is set, returns its value,
+
+ From there, we need to query the OS to get the size of the controlling
+ terminal.
+
+ Unices:
+ - get termios.TIOCGWINSZ
+ - if an error occurs or a negative value is obtained, returns None
+
+ Windows:
+
+ - win32utils.get_console_size() decides,
+ - returns None on error (provided default value)
"""
# If BZR_COLUMNS is set, take it, user is always right
@@ -1355,26 +1372,50 @@
# Don't guess, setting BZR_COLUMNS is the recommended way to override.
return None
- if sys.platform == 'win32':
- return win32utils.get_console_size(defaultx=None)[0]
-
+ # If COLUMNS is set, take it, the terminal knows better (even inside a
+ # given terminal, the application can decide to set COLUMNS to a lower
+ # value (splitted screen) or a bigger value (scroll bars))
+ try:
+ return int(os.environ['COLUMNS'])
+ except (KeyError, ValueError):
+ pass
+
+ width, height = _terminal_size(None, None)
+ if width <= 0:
+ # Consider invalid values as meaning no width
+ return None
+
+ return width
+
+
+def _win32_terminal_size(width, height):
+ width, height = win32utils.get_console_size(defaultx=width, defaulty=height)
+ return width, height
+
+
+def _ioctl_terminal_size(width, height):
try:
import struct, fcntl, termios
s = struct.pack('HHHH', 0, 0, 0, 0)
x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
- width = struct.unpack('HHHH', x)[1]
+ height, width = struct.unpack('HHHH', x)[0:2]
except (IOError, AttributeError):
- # If COLUMNS is set, take it
- try:
- return int(os.environ['COLUMNS'])
- except (KeyError, ValueError):
- return None
-
- if width <= 0:
- # Consider invalid values as meaning no width
- return None
-
- return width
+ pass
+ return width, height
+
+_terminal_size = None
+"""Returns the terminal size as (width, height).
+
+:param width: Default value for width.
+:param height: Default value for height.
+
+This is defined specifically for each OS and query the size of the controlling
+terminal. If any error occurs, the provided default values should be returned.
+"""
+if sys.platform == 'win32':
+ _terminal_size = _win32_terminal_size
+else:
+ _terminal_size = _ioctl_terminal_size
def supports_executable():
=== modified file 'bzrlib/tests/test_osutils.py'
--- a/bzrlib/tests/test_osutils.py 2009-12-08 21:46:07 +0000
+++ b/bzrlib/tests/test_osutils.py 2009-12-09 15:09:00 +0000
@@ -1928,39 +1928,63 @@
class TestTerminalWidth(tests.TestCase):
+ def replace_stdout(self, new):
+ orig_stdout = sys.stdout
+ def restore():
+ sys.stdout = orig_stdout
+ self.addCleanup(restore)
+ sys.stdout = new
+
+ def replace__terminal_size(self, new):
+ orig__terminal_size = osutils._terminal_size
+ def restore():
+ osutils._terminal_size = orig__terminal_size
+ self.addCleanup(restore)
+ osutils._terminal_size = new
+
+ def set_fake_tty(self):
+
+ class I_am_a_tty(object):
+ def isatty(self):
+ return True
+
+ self.replace_stdout(I_am_a_tty())
+
def test_default_values(self):
- self.assertEquals(80, osutils.default_terminal_width)
+ self.assertEqual(80, osutils.default_terminal_width)
def test_defaults_to_BZR_COLUMNS(self):
# BZR_COLUMNS is set by the test framework
- self.assertEquals('80', os.environ['BZR_COLUMNS'])
+ self.assertNotEqual('12', os.environ['BZR_COLUMNS'])
os.environ['BZR_COLUMNS'] = '12'
- self.assertEquals(12, osutils.terminal_width())
+ self.assertEqual(12, osutils.terminal_width())
+
+ def test_falls_back_to_COLUMNS(self):
+ del os.environ['BZR_COLUMNS']
+ self.assertNotEqual('42', os.environ['COLUMNS'])
+ self.set_fake_tty()
+ os.environ['COLUMNS'] = '42'
+ self.assertEqual(42, osutils.terminal_width())
def test_tty_default_without_columns(self):
del os.environ['BZR_COLUMNS']
del os.environ['COLUMNS']
- orig_stdout = sys.stdout
- def restore():
- sys.stdout = orig_stdout
- self.addCleanup(restore)
-
- class I_am_a_tty(object):
- def isatty(self):
- return True
-
- sys.stdout = I_am_a_tty()
- self.assertEquals(None, osutils.terminal_width())
+
+ def terminal_size(w, h):
+ return 42, 42
+
+ self.set_fake_tty()
+ # We need to override the osutils definition as it depends on the
+ # running environment that we can't control (PQM running without a
+ # controlling terminal is one example).
+ self.replace__terminal_size(terminal_size)
+ self.assertEqual(42, osutils.terminal_width())
def test_non_tty_default_without_columns(self):
del os.environ['BZR_COLUMNS']
del os.environ['COLUMNS']
- orig_stdout = sys.stdout
- def restore():
- sys.stdout = orig_stdout
- self.addCleanup(restore)
- sys.stdout = None
- self.assertEquals(None, osutils.terminal_width())
+ self.replace_stdout(None)
+ self.assertEqual(None, osutils.terminal_width())
def test_no_TIOCGWINSZ(self):
self.requireFeature(TermIOSFeature)
@@ -1978,4 +2002,5 @@
del termios.TIOCGWINSZ
del os.environ['BZR_COLUMNS']
del os.environ['COLUMNS']
- self.assertIs(None, osutils.terminal_width())
+ # Whatever the result is, if we don't raise an exception, it's ok.
+ osutils.terminal_width()
More information about the bazaar-commits
mailing list