From 2ef8113c63c585782e220e13b05554aade7794d1 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Thu, 30 Jan 2025 13:25:36 +0100 Subject: [PATCH 1/7] gh-127146: Update test skips for Emscripten 4.0.2 --- Lib/test/test_genericpath.py | 1 - Lib/test/test_io.py | 17 ++++------------- Lib/test/test_ntpath.py | 1 - Lib/test/test_signal.py | 3 --- Tools/wasm/README.md | 4 ++-- 5 files changed, 6 insertions(+), 20 deletions(-) diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index 391158b855624d..6c3abe602f557c 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -161,7 +161,6 @@ def test_exists(self): self.assertIs(self.pathmodule.lexists(path=filename), True) @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") - @unittest.skipIf(is_emscripten, "Fixed in next Emscripten release after 4.0.1") def test_exists_fd(self): r, w = os.pipe() try: diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index e59d3977df4134..9378ca7db1fa2c 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -445,9 +445,6 @@ def test_invalid_operations(self): self.assertRaises(exc, fp.seek, 1, self.SEEK_CUR) self.assertRaises(exc, fp.seek, -1, self.SEEK_END) - @unittest.skipIf( - support.is_emscripten, "fstat() of a pipe fd is not supported" - ) @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_optional_abilities(self): # Test for OSError when optional APIs are not supported @@ -502,6 +499,8 @@ class UnseekableWriter(self.MockUnseekableIO): (self.BytesIO, "rws"), (self.StringIO, "rws"), ) for [test, abilities] in tests: + if test == pipe_writer and not threading_helper.can_start_thread: + continue with self.subTest(test), test() as obj: readable = "r" in abilities self.assertEqual(obj.readable(), readable) @@ -3928,7 +3927,6 @@ def test_issue35928(self): self.assertEqual(res + f.readline(), 'foo\nbar\n') @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") - @unittest.skipIf(support.is_emscripten, "Fixed in next Emscripten release after 4.0.1") def test_read_non_blocking(self): import os r, w = os.pipe() @@ -4243,9 +4241,6 @@ def test_removed_u_mode(self): self.open(os_helper.TESTFN, mode) self.assertIn('invalid mode', str(cm.exception)) - @unittest.skipIf( - support.is_emscripten, "fstat() of a pipe fd is not supported" - ) @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_open_pipe_with_append(self): # bpo-27805: Ignore ESPIPE from lseek() in open(). @@ -4414,15 +4409,11 @@ def test_pickling(self): with self.assertRaisesRegex(TypeError, msg): pickle.dumps(f, protocol) - @unittest.skipIf( - support.is_emscripten, "fstat() of a pipe fd is not supported" - ) + @unittest.skipIf(support.is_emscripten, "Corrupts memory") def test_nonblock_pipe_write_bigbuf(self): self._test_nonblock_pipe_write(16*1024) - @unittest.skipIf( - support.is_emscripten, "fstat() of a pipe fd is not supported" - ) + @unittest.skipIf(support.is_emscripten, "Corrupts memory") def test_nonblock_pipe_write_smallbuf(self): self._test_nonblock_pipe_write(1024) diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index da01c65a1c2954..c10387b58e3f9c 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -940,7 +940,6 @@ def check_error(paths, expected): self.assertRaises(TypeError, ntpath.commonpath, ['C:\\Foo', b'Foo\\Baz']) self.assertRaises(TypeError, ntpath.commonpath, ['Foo', b'C:\\Foo\\Baz']) - @unittest.skipIf(is_emscripten, "Fixed in next Emscripten release after 4.0.1") def test_sameopenfile(self): with TemporaryFile() as tf1, TemporaryFile() as tf2: # Make sure the same file is really the same diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 96ae79b0eb18b3..df00ab32442f91 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -253,7 +253,6 @@ def test_invalid_socket(self): self.assertRaises((ValueError, OSError), signal.set_wakeup_fd, fd) - @unittest.skipIf(support.is_emscripten, "Fixed in next Emscripten release after 4.0.1") @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_set_wakeup_fd_result(self): r1, w1 = os.pipe() @@ -272,7 +271,6 @@ def test_set_wakeup_fd_result(self): self.assertEqual(signal.set_wakeup_fd(-1), w2) self.assertEqual(signal.set_wakeup_fd(-1), -1) - @unittest.skipIf(support.is_emscripten, "Fixed in next Emscripten release after 4.0.1") @unittest.skipUnless(support.has_socket_support, "needs working sockets.") def test_set_wakeup_fd_socket_result(self): sock1 = socket.socket() @@ -293,7 +291,6 @@ def test_set_wakeup_fd_socket_result(self): # On Windows, files are always blocking and Windows does not provide a # function to test if a socket is in non-blocking mode. @unittest.skipIf(sys.platform == "win32", "tests specific to POSIX") - @unittest.skipIf(support.is_emscripten, "Fixed in next Emscripten release after 4.0.1") @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") def test_set_wakeup_fd_blocking(self): rfd, wfd = os.pipe() diff --git a/Tools/wasm/README.md b/Tools/wasm/README.md index 2e0fa2fb533d67..ee7df46724314d 100644 --- a/Tools/wasm/README.md +++ b/Tools/wasm/README.md @@ -24,7 +24,7 @@ https://github.com/psf/webassembly for more information. To cross compile to the ``wasm32-emscripten`` platform you need [the Emscripten compiler toolchain](https://emscripten.org/), a Python interpreter, and an installation of Node version 18 or newer. -Emscripten version 3.1.73 or newer is recommended. All commands below are +Emscripten version 4.0.2 or newer is recommended. All commands below are relative to a checkout of the Python repository. #### Install [the Emscripten compiler toolchain](https://emscripten.org/docs/getting_started/downloads.html) @@ -266,7 +266,7 @@ if os.name == "posix": posix.uname_result( sysname='Emscripten', nodename='emscripten', - release='3.1.19', + release='4.0.2', version='#1', machine='wasm32' ) From b702cf57a9161fedad25f65723f33fa28d7102fd Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 31 Jan 2025 15:10:05 +0100 Subject: [PATCH 2/7] more specific skip reason --- Lib/test/test_io.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 9378ca7db1fa2c..2337853625482f 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -4409,11 +4409,11 @@ def test_pickling(self): with self.assertRaisesRegex(TypeError, msg): pickle.dumps(f, protocol) - @unittest.skipIf(support.is_emscripten, "Corrupts memory") + @unittest.skipIf(support.is_emscripten, "Emscripten corrupts memory when writing to nonblocking fd") def test_nonblock_pipe_write_bigbuf(self): self._test_nonblock_pipe_write(16*1024) - @unittest.skipIf(support.is_emscripten, "Corrupts memory") + @unittest.skipIf(support.is_emscripten, "Emscripten corrupts memory when writing to nonblocking fd") def test_nonblock_pipe_write_smallbuf(self): self._test_nonblock_pipe_write(1024) From 29b611573fe9c34b9163a96a60599abc47a62079 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 11 Mar 2025 10:18:31 +0100 Subject: [PATCH 3/7] Rearrange test --- Lib/test/test_io.py | 102 +++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 48 deletions(-) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 5e0676ba0ea24c..d123b29fe96618 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -498,59 +498,65 @@ class UnseekableWriter(self.MockUnseekableIO): (text_reader, "r"), (text_writer, "w"), (self.BytesIO, "rws"), (self.StringIO, "rws"), ) - for [test, abilities] in tests: - if test == pipe_writer and not threading_helper.can_start_thread: + + def do_test(obj): + readable = "r" in abilities + self.assertEqual(obj.readable(), readable) + writable = "w" in abilities + self.assertEqual(obj.writable(), writable) + + if isinstance(obj, self.TextIOBase): + data = "3" + elif isinstance(obj, (self.BufferedIOBase, self.RawIOBase)): + data = b"3" + else: + self.fail("Unknown base class") + + if "f" in abilities: + obj.fileno() + else: + self.assertRaises(OSError, obj.fileno) + + if readable: + obj.read(1) + obj.read() + else: + self.assertRaises(OSError, obj.read, 1) + self.assertRaises(OSError, obj.read) + + if writable: + obj.write(data) + else: + self.assertRaises(OSError, obj.write, data) + + if sys.platform.startswith("win") and test in ( + pipe_reader, pipe_writer): + # Pipes seem to appear as seekable on Windows continue - with self.subTest(test), test() as obj: - readable = "r" in abilities - self.assertEqual(obj.readable(), readable) - writable = "w" in abilities - self.assertEqual(obj.writable(), writable) - - if isinstance(obj, self.TextIOBase): - data = "3" - elif isinstance(obj, (self.BufferedIOBase, self.RawIOBase)): - data = b"3" - else: - self.fail("Unknown base class") + seekable = "s" in abilities + self.assertEqual(obj.seekable(), seekable) - if "f" in abilities: - obj.fileno() - else: - self.assertRaises(OSError, obj.fileno) + if seekable: + obj.tell() + obj.seek(0) + else: + self.assertRaises(OSError, obj.tell) + self.assertRaises(OSError, obj.seek, 0) - if readable: - obj.read(1) - obj.read() - else: - self.assertRaises(OSError, obj.read, 1) - self.assertRaises(OSError, obj.read) + if writable and seekable: + obj.truncate() + obj.truncate(0) + else: + self.assertRaises(OSError, obj.truncate) + self.assertRaises(OSError, obj.truncate, 0) - if writable: - obj.write(data) - else: - self.assertRaises(OSError, obj.write, data) - - if sys.platform.startswith("win") and test in ( - pipe_reader, pipe_writer): - # Pipes seem to appear as seekable on Windows - continue - seekable = "s" in abilities - self.assertEqual(obj.seekable(), seekable) - - if seekable: - obj.tell() - obj.seek(0) - else: - self.assertRaises(OSError, obj.tell) - self.assertRaises(OSError, obj.seek, 0) + for [test, abilities] in tests: + with self.subTest(test): + if test == pipe_writer and not threading_helper.can_start_thread: + skipTest() + with test() as obj: + do_test(obj) - if writable and seekable: - obj.truncate() - obj.truncate(0) - else: - self.assertRaises(OSError, obj.truncate) - self.assertRaises(OSError, obj.truncate, 0) def test_open_handles_NUL_chars(self): fn_with_NUL = 'foo\0bar' From 0d187a6b7b13949bc3e5c03d1e7df738c6bdf592 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 11 Mar 2025 10:19:41 +0100 Subject: [PATCH 4/7] Fix --- Lib/test/test_io.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index d123b29fe96618..0d3d45cb602fcd 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -499,7 +499,7 @@ class UnseekableWriter(self.MockUnseekableIO): (self.BytesIO, "rws"), (self.StringIO, "rws"), ) - def do_test(obj): + def do_test(obj, abilities): readable = "r" in abilities self.assertEqual(obj.readable(), readable) writable = "w" in abilities @@ -555,7 +555,7 @@ def do_test(obj): if test == pipe_writer and not threading_helper.can_start_thread: skipTest() with test() as obj: - do_test(obj) + do_test(obj, abilities) def test_open_handles_NUL_chars(self): From 29064d3afd67232f1c0653c01787efa8ca7fc4f1 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Tue, 11 Mar 2025 10:22:17 +0100 Subject: [PATCH 5/7] Fix again --- Lib/test/test_io.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 0d3d45cb602fcd..254e3c580415aa 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -499,7 +499,7 @@ class UnseekableWriter(self.MockUnseekableIO): (self.BytesIO, "rws"), (self.StringIO, "rws"), ) - def do_test(obj, abilities): + def do_test(test, obj, abilities): readable = "r" in abilities self.assertEqual(obj.readable(), readable) writable = "w" in abilities @@ -555,7 +555,7 @@ def do_test(obj, abilities): if test == pipe_writer and not threading_helper.can_start_thread: skipTest() with test() as obj: - do_test(obj, abilities) + do_test(test, obj, abilities) def test_open_handles_NUL_chars(self): From 827f4d94e7d98efc9bffd9e108407f585f55f1a4 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Sat, 15 Mar 2025 14:42:54 +0100 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: Russell Keith-Magee --- Lib/test/test_io.py | 2 +- Tools/wasm/README.md | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 254e3c580415aa..19606112660880 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -553,7 +553,7 @@ def do_test(test, obj, abilities): for [test, abilities] in tests: with self.subTest(test): if test == pipe_writer and not threading_helper.can_start_thread: - skipTest() + skipTest() with test() as obj: do_test(test, obj, abilities) diff --git a/Tools/wasm/README.md b/Tools/wasm/README.md index ee7df46724314d..62aa87aa7b18cd 100644 --- a/Tools/wasm/README.md +++ b/Tools/wasm/README.md @@ -24,8 +24,9 @@ https://github.com/psf/webassembly for more information. To cross compile to the ``wasm32-emscripten`` platform you need [the Emscripten compiler toolchain](https://emscripten.org/), a Python interpreter, and an installation of Node version 18 or newer. -Emscripten version 4.0.2 or newer is recommended. All commands below are -relative to a checkout of the Python repository. +Emscripten version 4.0.2 is recommended; newer versions may also work, but all +official testing is performed with that version. All commands below are relative +to a checkout of the Python repository. #### Install [the Emscripten compiler toolchain](https://emscripten.org/docs/getting_started/downloads.html) From 27efe766da10502607fb6774172d9e0c00f20cde Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Sun, 16 Mar 2025 09:22:47 +0800 Subject: [PATCH 7/7] Replace continue with return in inner test method. --- Lib/test/test_io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 9b2dba08d25d6b..a3fed0f59db0bb 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -532,7 +532,7 @@ def do_test(test, obj, abilities): if sys.platform.startswith("win") and test in ( pipe_reader, pipe_writer): # Pipes seem to appear as seekable on Windows - continue + return seekable = "s" in abilities self.assertEqual(obj.seekable(), seekable) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy