Issue #26801: shutil.get_terminal_size() now handles the case of stdout is

reopened on Windows.  Added tests for fallbacks.
This commit is contained in:
Serhiy Storchaka 2016-04-24 09:58:43 +03:00
parent e37fc18b3c
commit d30829def2
2 changed files with 32 additions and 1 deletions

View File

@ -1069,7 +1069,9 @@ def get_terminal_size(fallback=(80, 24)):
if columns <= 0 or lines <= 0: if columns <= 0 or lines <= 0:
try: try:
size = os.get_terminal_size(sys.__stdout__.fileno()) size = os.get_terminal_size(sys.__stdout__.fileno())
except (AttributeError, OSError): except (AttributeError, ValueError, OSError):
# stdout is None, closed, detached, or not a terminal, or
# os.get_terminal_size() is unsupported
size = os.terminal_size(fallback) size = os.terminal_size(fallback)
if columns <= 0: if columns <= 0:
columns = size.columns columns = size.columns

View File

@ -1828,14 +1828,24 @@ class TermsizeTests(unittest.TestCase):
with support.EnvironmentVarGuard() as env: with support.EnvironmentVarGuard() as env:
env['COLUMNS'] = '777' env['COLUMNS'] = '777'
del env['LINES']
size = shutil.get_terminal_size() size = shutil.get_terminal_size()
self.assertEqual(size.columns, 777) self.assertEqual(size.columns, 777)
with support.EnvironmentVarGuard() as env: with support.EnvironmentVarGuard() as env:
del env['COLUMNS']
env['LINES'] = '888' env['LINES'] = '888'
size = shutil.get_terminal_size() size = shutil.get_terminal_size()
self.assertEqual(size.lines, 888) self.assertEqual(size.lines, 888)
def test_bad_environ(self):
with support.EnvironmentVarGuard() as env:
env['COLUMNS'] = 'xxx'
env['LINES'] = 'yyy'
size = shutil.get_terminal_size()
self.assertGreaterEqual(size.columns, 0)
self.assertGreaterEqual(size.lines, 0)
@unittest.skipUnless(os.isatty(sys.__stdout__.fileno()), "not on tty") @unittest.skipUnless(os.isatty(sys.__stdout__.fileno()), "not on tty")
@unittest.skipUnless(hasattr(os, 'get_terminal_size'), @unittest.skipUnless(hasattr(os, 'get_terminal_size'),
'need os.get_terminal_size()') 'need os.get_terminal_size()')
@ -1859,6 +1869,25 @@ class TermsizeTests(unittest.TestCase):
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
def test_fallback(self):
with support.EnvironmentVarGuard() as env:
del env['LINES']
del env['COLUMNS']
# sys.__stdout__ has no fileno()
with support.swap_attr(sys, '__stdout__', None):
size = shutil.get_terminal_size(fallback=(10, 20))
self.assertEqual(size.columns, 10)
self.assertEqual(size.lines, 20)
# sys.__stdout__ is not a terminal on Unix
# or fileno() not in (0, 1, 2) on Windows
with open(os.devnull, 'w') as f, \
support.swap_attr(sys, '__stdout__', f):
size = shutil.get_terminal_size(fallback=(30, 40))
self.assertEqual(size.columns, 30)
self.assertEqual(size.lines, 40)
class PublicAPITests(unittest.TestCase): class PublicAPITests(unittest.TestCase):
"""Ensures that the correct values are exposed in the public API.""" """Ensures that the correct values are exposed in the public API."""