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:59:17 +03:00
commit 18a8affc8e
2 changed files with 32 additions and 1 deletions

View File

@ -1072,7 +1072,9 @@ def get_terminal_size(fallback=(80, 24)):
if columns <= 0 or lines <= 0:
try:
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)
if columns <= 0:
columns = size.columns

View File

@ -1828,14 +1828,24 @@ class TermsizeTests(unittest.TestCase):
with support.EnvironmentVarGuard() as env:
env['COLUMNS'] = '777'
del env['LINES']
size = shutil.get_terminal_size()
self.assertEqual(size.columns, 777)
with support.EnvironmentVarGuard() as env:
del env['COLUMNS']
env['LINES'] = '888'
size = shutil.get_terminal_size()
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(hasattr(os, 'get_terminal_size'),
'need os.get_terminal_size()')
@ -1859,6 +1869,25 @@ class TermsizeTests(unittest.TestCase):
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):
"""Ensures that the correct values are exposed in the public API."""