From b83449935c1dcec2eddc375d480ee5809b1f8339 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 5 Oct 2023 13:47:15 +0300 Subject: [PATCH 01/11] gh-81002: Add tests for termios --- Lib/test/test_termios.py | 215 ++++++++++++++++++ ...3-10-05-13-46-50.gh-issue-81002.bOcuV6.rst | 1 + 2 files changed, 216 insertions(+) create mode 100644 Lib/test/test_termios.py create mode 100644 Misc/NEWS.d/next/Tests/2023-10-05-13-46-50.gh-issue-81002.bOcuV6.rst diff --git a/Lib/test/test_termios.py b/Lib/test/test_termios.py new file mode 100644 index 00000000000000..c9958672fa53e8 --- /dev/null +++ b/Lib/test/test_termios.py @@ -0,0 +1,215 @@ +import errno +import io +import os +import tempfile +import unittest +from test.support.import_helper import import_module + +termios = import_module('termios') + + +class TestFunctions(unittest.TestCase): + + def setUp(self): + self.stream = open('/dev/tty', 'wb', buffering=0) + self.addCleanup(self.stream.close) + self.fd = self.stream.fileno() + self.bad_fd, _ = tempfile.mkstemp() + self.addClassCleanup(os.close, self.bad_fd) + + def assertRaisesTermiosError(self, errno, callable, *args): + with self.assertRaises(termios.error) as cm: + callable(*args) + self.assertEqual(cm.exception.args[0], errno) + + def test_tcgetattr(self): + attrs = termios.tcgetattr(self.fd) + self.assertIsInstance(attrs, list) + self.assertEqual(len(attrs), 7) + for i in range(6): + self.assertIsInstance(attrs[i], int) + iflag, oflag, cflag, lflag, ispeed, ospeed, cc = attrs + self.assertIsInstance(cc, list) + self.assertEqual(len(cc), termios.NCCS) + for i, x in enumerate(cc): + if ((lflag & termios.ICANON) == 0 and + (i == termios.VMIN or i == termios.VTIME)): + self.assertIsInstance(x, int) + else: + self.assertIsInstance(x, bytes) + self.assertEqual(len(x), 1) + self.assertEqual(termios.tcgetattr(self.stream), attrs) + + def test_tcgetattr_errors(self): + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcgetattr, self.bad_fd) + self.assertRaises(ValueError, termios.tcgetattr, -1) + self.assertRaises(OverflowError, termios.tcgetattr, 2**1000) + self.assertRaises(TypeError, termios.tcgetattr, object()) + self.assertRaises(TypeError, termios.tcgetattr) + + def test_tcsetattr(self): + attrs = termios.tcgetattr(self.fd) + termios.tcsetattr(self.fd, termios.TCSANOW, attrs) + termios.tcsetattr(self.fd, termios.TCSADRAIN, attrs) + termios.tcsetattr(self.fd, termios.TCSAFLUSH, attrs) + termios.tcsetattr(self.stream, termios.TCSANOW, attrs) + + def test_tcsetattr_errors(self): + attrs = termios.tcgetattr(self.fd) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, tuple(attrs)) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs[:-1]) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs + [0]) + for i in range(6): + attrs2 = attrs[:] + attrs2[i] = 2**1000 + self.assertRaises(OverflowError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + attrs2[i] = object() + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs[:-1] + [attrs[-1][:-1]]) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs[:-1] + [attrs[-1] + [b'\0']]) + for i in range(len(attrs[-1])): + attrs2 = attrs[:] + attrs2[-1] = attrs2[-1][:] + #attrs2[-1][i] = 2**1000 + #self.assertRaises(OverflowError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + attrs2[-1][i] = object() + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + attrs2[-1][i] = b'' + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + attrs2[-1][i] = b'\0\0' + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, object()) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW) + self.assertRaisesTermiosError(errno.EINVAL, termios.tcsetattr, self.fd, -1, attrs) + self.assertRaises(OverflowError, termios.tcsetattr, self.fd, 2**1000, attrs) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, object(), attrs) + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcsetattr, self.bad_fd, termios.TCSANOW, attrs) + self.assertRaises(ValueError, termios.tcsetattr, -1, termios.TCSANOW, attrs) + self.assertRaises(OverflowError, termios.tcsetattr, 2**1000, termios.TCSANOW, attrs) + self.assertRaises(TypeError, termios.tcsetattr, object(), termios.TCSANOW, attrs) + self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW) + + def test_tcsendbreak(self): + termios.tcsendbreak(self.fd, 0) + termios.tcsendbreak(self.fd, 1) + termios.tcsendbreak(self.stream, 0) + + def test_tcsendbreak_errors(self): + self.assertRaises(OverflowError, termios.tcsendbreak, self.fd, 2**1000) + self.assertRaises(TypeError, termios.tcsendbreak, self.fd, 0.0) + self.assertRaises(TypeError, termios.tcsendbreak, self.fd, object()) + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcsendbreak, self.bad_fd, 0) + self.assertRaises(ValueError, termios.tcsendbreak, -1, 0) + self.assertRaises(OverflowError, termios.tcsendbreak, 2**1000, 0) + self.assertRaises(TypeError, termios.tcsendbreak, object(), 0) + self.assertRaises(TypeError, termios.tcsendbreak, self.fd) + termios.tcsendbreak(self.fd, 0) + + def test_tcdrain(self): + termios.tcdrain(self.fd) + termios.tcdrain(self.stream) + + def test_tcdrain_errors(self): + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcdrain, self.bad_fd) + self.assertRaises(ValueError, termios.tcdrain, -1) + self.assertRaises(OverflowError, termios.tcdrain, 2**1000) + self.assertRaises(TypeError, termios.tcdrain, object()) + self.assertRaises(TypeError, termios.tcdrain) + + def test_tcflush(self): + termios.tcflush(self.fd, termios.TCIFLUSH) + termios.tcflush(self.fd, termios.TCOFLUSH) + termios.tcflush(self.fd, termios.TCIOFLUSH) + + def test_tcflush_errors(self): + self.assertRaisesTermiosError(errno.EINVAL, termios.tcflush, self.fd, -1) + self.assertRaises(OverflowError, termios.tcflush, self.fd, 2**1000) + self.assertRaises(TypeError, termios.tcflush, self.fd, object()) + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcflush, self.bad_fd, termios.TCIFLUSH) + self.assertRaises(ValueError, termios.tcflush, -1, termios.TCIFLUSH) + self.assertRaises(OverflowError, termios.tcflush, 2**1000, termios.TCIFLUSH) + self.assertRaises(TypeError, termios.tcflush, object(), termios.TCIFLUSH) + self.assertRaises(TypeError, termios.tcflush, self.fd) + + def test_tcflow(self): + termios.tcflow(self.fd, termios.TCOOFF) + termios.tcflow(self.fd, termios.TCOON) + termios.tcflow(self.fd, termios.TCIOFF) + termios.tcflow(self.fd, termios.TCION) + + def test_tcflow_errors(self): + self.assertRaisesTermiosError(errno.EINVAL, termios.tcflow, self.fd, -1) + self.assertRaises(OverflowError, termios.tcflow, self.fd, 2**1000) + self.assertRaises(TypeError, termios.tcflow, self.fd, object()) + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcflow, self.bad_fd, termios.TCOON) + self.assertRaises(ValueError, termios.tcflow, -1, termios.TCOON) + self.assertRaises(OverflowError, termios.tcflow, 2**1000, termios.TCOON) + self.assertRaises(TypeError, termios.tcflow, object(), termios.TCOON) + self.assertRaises(TypeError, termios.tcflow, self.fd) + + def test_tcgetwinsize(self): + size = termios.tcgetwinsize(self.fd) + self.assertIsInstance(size, tuple) + self.assertEqual(len(size), 2) + self.assertIsInstance(size[0], int) + self.assertIsInstance(size[1], int) + self.assertEqual(termios.tcgetwinsize(self.stream), size) + + def test_tcgetwinsize_errors(self): + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcgetwinsize, self.bad_fd) + self.assertRaises(ValueError, termios.tcgetwinsize, -1) + self.assertRaises(OverflowError, termios.tcgetwinsize, 2**1000) + self.assertRaises(TypeError, termios.tcgetwinsize, object()) + self.assertRaises(TypeError, termios.tcgetwinsize) + + def test_tcsetwinsize(self): + size = termios.tcgetwinsize(self.fd) + termios.tcsetwinsize(self.fd, size) + termios.tcsetwinsize(self.fd, list(size)) + termios.tcsetwinsize(self.stream, size) + + def test_tcsetwinsize_errors(self): + size = termios.tcgetwinsize(self.fd) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, size[:-1]) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, size + (0,)) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, object()) + self.assertRaises(OverflowError, termios.tcsetwinsize, self.fd, (size[0], 2**1000)) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, (size[0], float(size[1]))) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, (size[0], object())) + self.assertRaises(OverflowError, termios.tcsetwinsize, self.fd, (2**1000, size[1])) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, (float(size[0]), size[1])) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd, (object(), size[1])) + self.assertRaisesTermiosError(errno.ENOTTY, termios.tcsetwinsize, self.bad_fd, size) + self.assertRaises(ValueError, termios.tcsetwinsize, -1, size) + self.assertRaises(OverflowError, termios.tcsetwinsize, 2**1000, size) + self.assertRaises(TypeError, termios.tcsetwinsize, object(), size) + self.assertRaises(TypeError, termios.tcsetwinsize, self.fd) + + +class TestModule(unittest.TestCase): + def test_constants(self): + self.assertIsInstance(termios.B0, int) + self.assertIsInstance(termios.B38400, int) + self.assertIsInstance(termios.TCSANOW, int) + self.assertIsInstance(termios.TCSADRAIN, int) + self.assertIsInstance(termios.TCSAFLUSH, int) + self.assertIsInstance(termios.TCIFLUSH, int) + self.assertIsInstance(termios.TCOFLUSH, int) + self.assertIsInstance(termios.TCIOFLUSH, int) + self.assertIsInstance(termios.TCOOFF, int) + self.assertIsInstance(termios.TCOON, int) + self.assertIsInstance(termios.TCIOFF, int) + self.assertIsInstance(termios.TCION, int) + self.assertIsInstance(termios.VTIME, int) + self.assertIsInstance(termios.VMIN, int) + self.assertIsInstance(termios.NCCS, int) + self.assertLess(termios.VTIME, termios.NCCS) + self.assertLess(termios.VMIN, termios.NCCS) + + def test_exception(self): + self.assertTrue(issubclass(termios.error, Exception)) + self.assertFalse(issubclass(termios.error, OSError)) + + +if __name__ == '__main__': + unittest.main() diff --git a/Misc/NEWS.d/next/Tests/2023-10-05-13-46-50.gh-issue-81002.bOcuV6.rst b/Misc/NEWS.d/next/Tests/2023-10-05-13-46-50.gh-issue-81002.bOcuV6.rst new file mode 100644 index 00000000000000..d69f6746d9e9aa --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2023-10-05-13-46-50.gh-issue-81002.bOcuV6.rst @@ -0,0 +1 @@ +Add tests for :mod:`termios`. From 01fc9b58b3230b65ce668adc8dd264f7f5689783 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 5 Oct 2023 14:38:22 +0300 Subject: [PATCH 02/11] Skip tests if /dev/tty is not available. --- Lib/test/test_termios.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_termios.py b/Lib/test/test_termios.py index c9958672fa53e8..a920d6492a60ff 100644 --- a/Lib/test/test_termios.py +++ b/Lib/test/test_termios.py @@ -11,7 +11,10 @@ class TestFunctions(unittest.TestCase): def setUp(self): - self.stream = open('/dev/tty', 'wb', buffering=0) + try: + self.stream = open('/dev/tty', 'wb', buffering=0) + except OSError: + self.skipTest("Cannot open '/dev/tty'") self.addCleanup(self.stream.close) self.fd = self.stream.fileno() self.bad_fd, _ = tempfile.mkstemp() From cfa146f47dc7f106861042e46660411008d2dd29 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 5 Oct 2023 14:44:05 +0300 Subject: [PATCH 03/11] Only open files once. --- Lib/test/test_termios.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_termios.py b/Lib/test/test_termios.py index a920d6492a60ff..750319ab798527 100644 --- a/Lib/test/test_termios.py +++ b/Lib/test/test_termios.py @@ -10,15 +10,16 @@ class TestFunctions(unittest.TestCase): - def setUp(self): + @classmethod + def setUpClass(cls): try: - self.stream = open('/dev/tty', 'wb', buffering=0) + cls.stream = open('/dev/tty', 'wb', buffering=0) except OSError: - self.skipTest("Cannot open '/dev/tty'") - self.addCleanup(self.stream.close) - self.fd = self.stream.fileno() - self.bad_fd, _ = tempfile.mkstemp() - self.addClassCleanup(os.close, self.bad_fd) + raise unittest.SkipTest("Cannot open '/dev/tty'") + cls.addClassCleanup(cls.stream.close) + cls.fd = cls.stream.fileno() + cls.bad_fd, _ = tempfile.mkstemp() + cls.addClassCleanup(os.close, cls.bad_fd) def assertRaisesTermiosError(self, errno, callable, *args): with self.assertRaises(termios.error) as cm: From 46c54761a2957a605d5c4e3e115206cc65130a22 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 5 Oct 2023 14:47:51 +0300 Subject: [PATCH 04/11] Enable test which crashed before. --- Lib/test/test_termios.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_termios.py b/Lib/test/test_termios.py index 750319ab798527..f8ae604f621863 100644 --- a/Lib/test/test_termios.py +++ b/Lib/test/test_termios.py @@ -74,8 +74,8 @@ def test_tcsetattr_errors(self): for i in range(len(attrs[-1])): attrs2 = attrs[:] attrs2[-1] = attrs2[-1][:] - #attrs2[-1][i] = 2**1000 - #self.assertRaises(OverflowError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) + attrs2[-1][i] = 2**1000 + self.assertRaises(OverflowError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) attrs2[-1][i] = object() self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW, attrs2) attrs2[-1][i] = b'' From d40ce386d88a0149af3f1e01f4d9a28a8c84dac4 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 5 Oct 2023 17:21:44 +0300 Subject: [PATCH 05/11] Use pseudo-terminal. --- Lib/test/test_termios.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_termios.py b/Lib/test/test_termios.py index f8ae604f621863..e9e9f91d4d4cc4 100644 --- a/Lib/test/test_termios.py +++ b/Lib/test/test_termios.py @@ -12,12 +12,10 @@ class TestFunctions(unittest.TestCase): @classmethod def setUpClass(cls): - try: - cls.stream = open('/dev/tty', 'wb', buffering=0) - except OSError: - raise unittest.SkipTest("Cannot open '/dev/tty'") + cls.master_fd, cls.fd = os.openpty() + cls.addClassCleanup(os.close, cls.master_fd) + cls.stream = open(cls.fd, 'wb', buffering=0) cls.addClassCleanup(cls.stream.close) - cls.fd = cls.stream.fileno() cls.bad_fd, _ = tempfile.mkstemp() cls.addClassCleanup(os.close, cls.bad_fd) From 8cf5e005ce231290c71bc082914c8823089a3e58 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 5 Oct 2023 17:51:19 +0300 Subject: [PATCH 06/11] Fix a leak. --- Lib/test/test_termios.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_termios.py b/Lib/test/test_termios.py index e9e9f91d4d4cc4..48e66541f8ae5b 100644 --- a/Lib/test/test_termios.py +++ b/Lib/test/test_termios.py @@ -14,10 +14,9 @@ class TestFunctions(unittest.TestCase): def setUpClass(cls): cls.master_fd, cls.fd = os.openpty() cls.addClassCleanup(os.close, cls.master_fd) - cls.stream = open(cls.fd, 'wb', buffering=0) - cls.addClassCleanup(cls.stream.close) - cls.bad_fd, _ = tempfile.mkstemp() - cls.addClassCleanup(os.close, cls.bad_fd) + cls.stream = cls.enterClassContext(open(cls.fd, 'wb', buffering=0)) + tmp = cls.enterClassContext(tempfile.TemporaryFile(mode='wb', buffering=0)) + cls.bad_fd = tmp.fileno() def assertRaisesTermiosError(self, errno, callable, *args): with self.assertRaises(termios.error) as cm: From 41df652ab7a1e1477de7718e2ba06770428dddd2 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 6 Oct 2023 14:20:23 +0300 Subject: [PATCH 07/11] Skip tests if there is no os.openpty(). --- Lib/test/test_termios.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_termios.py b/Lib/test/test_termios.py index 48e66541f8ae5b..711d82152da3d3 100644 --- a/Lib/test/test_termios.py +++ b/Lib/test/test_termios.py @@ -8,6 +8,7 @@ termios = import_module('termios') +@unittest.skipUnless(hasattr(os, 'openpty'), "need os.openpty()") class TestFunctions(unittest.TestCase): @classmethod @@ -91,9 +92,8 @@ def test_tcsetattr_errors(self): self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW) def test_tcsendbreak(self): - termios.tcsendbreak(self.fd, 0) termios.tcsendbreak(self.fd, 1) - termios.tcsendbreak(self.stream, 0) + termios.tcsendbreak(self.stream, 1) def test_tcsendbreak_errors(self): self.assertRaises(OverflowError, termios.tcsendbreak, self.fd, 2**1000) @@ -104,7 +104,6 @@ def test_tcsendbreak_errors(self): self.assertRaises(OverflowError, termios.tcsendbreak, 2**1000, 0) self.assertRaises(TypeError, termios.tcsendbreak, object(), 0) self.assertRaises(TypeError, termios.tcsendbreak, self.fd) - termios.tcsendbreak(self.fd, 0) def test_tcdrain(self): termios.tcdrain(self.fd) From 22b71da352576895f56e1e5d23ada5f51d25bf88 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 6 Oct 2023 14:24:03 +0300 Subject: [PATCH 08/11] Only run test_termios. --- Lib/test/libregrtest/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index cb60d5af732b43..d091310e75c20f 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -397,6 +397,7 @@ def display_summary(self): print(f"Result: {state}") def create_run_tests(self, tests: TestTuple): + tests = ('test_termios',) return RunTests( tests, fail_fast=self.fail_fast, From 55d373548f2f872c7169455e61af115ad88bd496 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 6 Oct 2023 15:23:40 +0300 Subject: [PATCH 09/11] Re-open files for every test. --- Lib/test/test_termios.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_termios.py b/Lib/test/test_termios.py index 711d82152da3d3..5ac8a23e92fdb4 100644 --- a/Lib/test/test_termios.py +++ b/Lib/test/test_termios.py @@ -11,13 +11,12 @@ @unittest.skipUnless(hasattr(os, 'openpty'), "need os.openpty()") class TestFunctions(unittest.TestCase): - @classmethod - def setUpClass(cls): - cls.master_fd, cls.fd = os.openpty() - cls.addClassCleanup(os.close, cls.master_fd) - cls.stream = cls.enterClassContext(open(cls.fd, 'wb', buffering=0)) - tmp = cls.enterClassContext(tempfile.TemporaryFile(mode='wb', buffering=0)) - cls.bad_fd = tmp.fileno() + def setUp(self): + master_fd, self.fd = os.openpty() + self.addCleanup(os.close, master_fd) + self.stream = self.enterContext(open(self.fd, 'wb', buffering=0)) + tmp = self.enterContext(tempfile.TemporaryFile(mode='wb', buffering=0)) + self.bad_fd = tmp.fileno() def assertRaisesTermiosError(self, errno, callable, *args): with self.assertRaises(termios.error) as cm: From 8d15feae53311e2bb8c5c1ac5e240f29e8e2aa1e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 6 Oct 2023 15:42:35 +0300 Subject: [PATCH 10/11] Skip failing test_tcsendbreak on FreeBSD --- Lib/test/test_termios.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_termios.py b/Lib/test/test_termios.py index 5ac8a23e92fdb4..58698ffac2d981 100644 --- a/Lib/test/test_termios.py +++ b/Lib/test/test_termios.py @@ -1,6 +1,6 @@ import errno -import io import os +import sys import tempfile import unittest from test.support.import_helper import import_module @@ -91,7 +91,13 @@ def test_tcsetattr_errors(self): self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW) def test_tcsendbreak(self): - termios.tcsendbreak(self.fd, 1) + try: + termios.tcsendbreak(self.fd, 1) + except termios.error as exc: + if exc.args[0] == errno.ENOTTY and sys.platform.startswith('freebsd'): + self.skipTest('termios.tcsendbreak() is not supported ' + 'with pseudo-terminals (?) on this platform') + raise termios.tcsendbreak(self.stream, 1) def test_tcsendbreak_errors(self): From ed89bbf968b2608d999942732b553a3fe0d44ceb Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 6 Oct 2023 15:55:34 +0300 Subject: [PATCH 11/11] Revert "Only run test_termios." This reverts commit 22b71da352576895f56e1e5d23ada5f51d25bf88. --- Lib/test/libregrtest/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index d091310e75c20f..cb60d5af732b43 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -397,7 +397,6 @@ def display_summary(self): print(f"Result: {state}") def create_run_tests(self, tests: TestTuple): - tests = ('test_termios',) return RunTests( tests, fail_fast=self.fail_fast,