summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-04-24 06:58:43 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-04-24 06:58:43 (GMT)
commitd30829def2be7edc649f06d73fdc5a4813e29d1f (patch)
tree50ee974b26294a8159185b50fd9239f22418e88b
parente37fc18b3c0d5fe13d75f37d9ae9c4387a46ee3d (diff)
downloadcpython-d30829def2be7edc649f06d73fdc5a4813e29d1f.zip
cpython-d30829def2be7edc649f06d73fdc5a4813e29d1f.tar.gz
cpython-d30829def2be7edc649f06d73fdc5a4813e29d1f.tar.bz2
Issue #26801: shutil.get_terminal_size() now handles the case of stdout is
reopened on Windows. Added tests for fallbacks.
-rw-r--r--Lib/shutil.py4
-rw-r--r--Lib/test/test_shutil.py29
2 files changed, 32 insertions, 1 deletions
diff --git a/Lib/shutil.py b/Lib/shutil.py
index 7f8edf5..37124a0 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -1069,7 +1069,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
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index 7e41891..13b30b9 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -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."""