From b4c3d449be3f0b36d48b27e3fd71bfa02809112c Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Mon, 14 Mar 2022 21:56:53 +0300 Subject: [PATCH 01/14] Convert TestSendfile to IsolatedAsyncioTestCase --- Lib/test/test_os.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index ae8d930a95253a..9042956b56cb4b 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3308,7 +3308,7 @@ def handle_error(self): @unittest.skipUnless(hasattr(os, 'sendfile'), "test needs os.sendfile()") -class TestSendfile(unittest.TestCase): +class TestSendfile(unittest.IsolatedAsyncioTestCase): DATA = b"12345abcde" * 16 * 1024 # 160 KiB SUPPORT_HEADERS_TRAILERS = not sys.platform.startswith("linux") and \ @@ -3329,7 +3329,7 @@ def tearDownClass(cls): threading_helper.threading_cleanup(*cls.key) os_helper.unlink(os_helper.TESTFN) - def setUp(self): + async def asyncSetUp(self): self.server = SendfileTestServer((socket_helper.HOST, 0)) self.server.start() self.client = socket.socket() @@ -3341,7 +3341,7 @@ def setUp(self): self.file = open(os_helper.TESTFN, 'rb') self.fileno = self.file.fileno() - def tearDown(self): + async def asyncTearDown(self): self.file.close() self.client.close() if self.server.running: @@ -3365,7 +3365,7 @@ def sendfile_wrapper(self, *args, **kwargs): else: raise - def test_send_whole_file(self): + async def test_send_whole_file(self): # normal send total_sent = 0 offset = 0 @@ -3387,7 +3387,7 @@ def test_send_whole_file(self): self.assertEqual(len(data), len(self.DATA)) self.assertEqual(data, self.DATA) - def test_send_at_certain_offset(self): + async def test_send_at_certain_offset(self): # start sending a file at a certain offset total_sent = 0 offset = len(self.DATA) // 2 @@ -3410,7 +3410,7 @@ def test_send_at_certain_offset(self): self.assertEqual(len(data), len(expected)) self.assertEqual(data, expected) - def test_offset_overflow(self): + async def test_offset_overflow(self): # specify an offset > file size offset = len(self.DATA) + 4096 try: @@ -3427,12 +3427,12 @@ def test_offset_overflow(self): data = self.server.handler_instance.get_data() self.assertEqual(data, b'') - def test_invalid_offset(self): + async def test_invalid_offset(self): with self.assertRaises(OSError) as cm: os.sendfile(self.sockno, self.fileno, -1, 4096) self.assertEqual(cm.exception.errno, errno.EINVAL) - def test_keywords(self): + async def test_keywords(self): # Keyword arguments should be supported os.sendfile(out_fd=self.sockno, in_fd=self.fileno, offset=0, count=4096) @@ -3444,7 +3444,7 @@ def test_keywords(self): # --- headers / trailers tests @requires_headers_trailers - def test_headers(self): + async def test_headers(self): total_sent = 0 expected_data = b"x" * 512 + b"y" * 256 + self.DATA[:-1] sent = os.sendfile(self.sockno, self.fileno, 0, 4096, @@ -3469,7 +3469,7 @@ def test_headers(self): self.assertEqual(hash(data), hash(expected_data)) @requires_headers_trailers - def test_trailers(self): + async def test_trailers(self): TESTFN2 = os_helper.TESTFN + "2" file_data = b"abcdef" @@ -3486,7 +3486,7 @@ def test_trailers(self): @requires_headers_trailers @requires_32b - def test_headers_overflow_32bits(self): + async def test_headers_overflow_32bits(self): self.server.handler_instance.accumulate = False with self.assertRaises(OSError) as cm: os.sendfile(self.sockno, self.fileno, 0, 0, @@ -3495,7 +3495,7 @@ def test_headers_overflow_32bits(self): @requires_headers_trailers @requires_32b - def test_trailers_overflow_32bits(self): + async def test_trailers_overflow_32bits(self): self.server.handler_instance.accumulate = False with self.assertRaises(OSError) as cm: os.sendfile(self.sockno, self.fileno, 0, 0, @@ -3505,7 +3505,7 @@ def test_trailers_overflow_32bits(self): @requires_headers_trailers @unittest.skipUnless(hasattr(os, 'SF_NODISKIO'), 'test needs os.SF_NODISKIO') - def test_flags(self): + async def test_flags(self): try: os.sendfile(self.sockno, self.fileno, 0, 4096, flags=os.SF_NODISKIO) From 51c5422c332c1353fefab08f55a3ca3d20917dbf Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Fri, 18 Mar 2022 18:04:31 +0300 Subject: [PATCH 02/14] Make os.sendfile asynchronous --- Lib/test/test_os.py | 56 ++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 9042956b56cb4b..405dcf2e4f9836 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -2,6 +2,7 @@ # does add tests for a few functions which have been determined to be more # portable than they had been thought to be. +import asyncio import codecs import contextlib import decimal @@ -3348,13 +3349,19 @@ async def asyncTearDown(self): self.server.stop() self.server = None - def sendfile_wrapper(self, *args, **kwargs): + # Use the test subject instead of asyncio.loop.sendfile + @staticmethod + async def async_sendfile(*args, **kwargs): + return await asyncio.to_thread(os.sendfile, *args, **kwargs) + + @staticmethod + async def sendfile_wrapper(*args, **kwargs): """A higher level wrapper representing how an application is supposed to use sendfile(). """ while True: try: - return os.sendfile(*args, **kwargs) + return await TestSendfile.async_sendfile(*args, **kwargs) except OSError as err: if err.errno == errno.ECONNRESET: # disconnected @@ -3371,7 +3378,8 @@ async def test_send_whole_file(self): offset = 0 nbytes = 4096 while total_sent < len(self.DATA): - sent = self.sendfile_wrapper(self.sockno, self.fileno, offset, nbytes) + sent = await self.sendfile_wrapper(self.sockno, self.fileno, + offset, nbytes) if sent == 0: break offset += sent @@ -3394,7 +3402,8 @@ async def test_send_at_certain_offset(self): must_send = len(self.DATA) - offset nbytes = 4096 while total_sent < must_send: - sent = self.sendfile_wrapper(self.sockno, self.fileno, offset, nbytes) + sent = await self.sendfile_wrapper(self.sockno, self.fileno, + offset, nbytes) if sent == 0: break offset += sent @@ -3414,7 +3423,8 @@ async def test_offset_overflow(self): # specify an offset > file size offset = len(self.DATA) + 4096 try: - sent = os.sendfile(self.sockno, self.fileno, offset, 4096) + sent = await self.async_sendfile(self.sockno, self.fileno, + offset, 4096) except OSError as e: # Solaris can raise EINVAL if offset >= file length, ignore. if e.errno != errno.EINVAL: @@ -3429,17 +3439,17 @@ async def test_offset_overflow(self): async def test_invalid_offset(self): with self.assertRaises(OSError) as cm: - os.sendfile(self.sockno, self.fileno, -1, 4096) + await self.async_sendfile(self.sockno, self.fileno, -1, 4096) self.assertEqual(cm.exception.errno, errno.EINVAL) async def test_keywords(self): # Keyword arguments should be supported - os.sendfile(out_fd=self.sockno, in_fd=self.fileno, - offset=0, count=4096) + await self.async_sendfile(out_fd=self.sockno, in_fd=self.fileno, + offset=0, count=4096) if self.SUPPORT_HEADERS_TRAILERS: - os.sendfile(out_fd=self.sockno, in_fd=self.fileno, - offset=0, count=4096, - headers=(), trailers=(), flags=0) + await self.async_sendfile(out_fd=self.sockno, in_fd=self.fileno, + offset=0, count=4096, + headers=(), trailers=(), flags=0) # --- headers / trailers tests @@ -3447,15 +3457,15 @@ async def test_keywords(self): async def test_headers(self): total_sent = 0 expected_data = b"x" * 512 + b"y" * 256 + self.DATA[:-1] - sent = os.sendfile(self.sockno, self.fileno, 0, 4096, - headers=[b"x" * 512, b"y" * 256]) + sent = await self.async_sendfile(self.sockno, self.fileno, 0, 4096, + headers=[b"x" * 512, b"y" * 256]) self.assertLessEqual(sent, 512 + 256 + 4096) total_sent += sent offset = 4096 while total_sent < len(expected_data): nbytes = min(len(expected_data) - total_sent, 4096) - sent = self.sendfile_wrapper(self.sockno, self.fileno, - offset, nbytes) + sent = await self.sendfile_wrapper(self.sockno, self.fileno, + offset, nbytes) if sent == 0: break self.assertLessEqual(sent, nbytes) @@ -3477,8 +3487,8 @@ async def test_trailers(self): create_file(TESTFN2, file_data) with open(TESTFN2, 'rb') as f: - os.sendfile(self.sockno, f.fileno(), 0, 5, - trailers=[b"123456", b"789"]) + await self.async_sendfile(self.sockno, f.fileno(), 0, 5, + trailers=[b"123456", b"789"]) self.client.close() self.server.wait() data = self.server.handler_instance.get_data() @@ -3489,8 +3499,8 @@ async def test_trailers(self): async def test_headers_overflow_32bits(self): self.server.handler_instance.accumulate = False with self.assertRaises(OSError) as cm: - os.sendfile(self.sockno, self.fileno, 0, 0, - headers=[b"x" * 2**16] * 2**15) + await self.async_sendfile(self.sockno, self.fileno, 0, 0, + headers=[b"x" * 2**16] * 2**15) self.assertEqual(cm.exception.errno, errno.EINVAL) @requires_headers_trailers @@ -3498,8 +3508,8 @@ async def test_headers_overflow_32bits(self): async def test_trailers_overflow_32bits(self): self.server.handler_instance.accumulate = False with self.assertRaises(OSError) as cm: - os.sendfile(self.sockno, self.fileno, 0, 0, - trailers=[b"x" * 2**16] * 2**15) + await self.async_sendfile(self.sockno, self.fileno, 0, 0, + trailers=[b"x" * 2**16] * 2**15) self.assertEqual(cm.exception.errno, errno.EINVAL) @requires_headers_trailers @@ -3507,8 +3517,8 @@ async def test_trailers_overflow_32bits(self): 'test needs os.SF_NODISKIO') async def test_flags(self): try: - os.sendfile(self.sockno, self.fileno, 0, 4096, - flags=os.SF_NODISKIO) + await async_sendfile(self.sockno, self.fileno, 0, 4096, + flags=os.SF_NODISKIO) except OSError as err: if err.errno not in (errno.EBUSY, errno.EAGAIN): raise From ee9dbe4e1b027c81f377303c5c624a485dc47b8f Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Fri, 18 Mar 2022 17:57:32 +0300 Subject: [PATCH 03/14] Use an asyncio-connected client --- Lib/test/test_os.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 405dcf2e4f9836..7d8349253c88a6 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3334,7 +3334,9 @@ async def asyncSetUp(self): self.server = SendfileTestServer((socket_helper.HOST, 0)) self.server.start() self.client = socket.socket() - self.client.connect((self.server.host, self.server.port)) + self.client.setblocking(False) + l = asyncio.get_running_loop() + await l.sock_connect(self.client, (self.server.host, self.server.port)) self.client.settimeout(1) # synchronize by waiting for "220 ready" response self.client.recv(1024) From a3b9debc33e5b6c2efa399cc15bde7f1d4b06609 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Fri, 18 Mar 2022 19:16:30 +0300 Subject: [PATCH 04/14] Add and use an asyncio server --- Lib/test/test_os.py | 49 ++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 7d8349253c88a6..2aaea61aaa0dd7 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3330,13 +3330,23 @@ def tearDownClass(cls): threading_helper.threading_cleanup(*cls.key) os_helper.unlink(os_helper.TESTFN) + async def handle_new_client(self, reader, writer): + writer.write(b"220 ready\r\n") + buffer = [] + while not reader.at_eof(): + buffer.append(await reader.read()) + self.server_buffer = b''.join(buffer) + writer.close() + self.server.close() # The test server processes a single client only + async def asyncSetUp(self): - self.server = SendfileTestServer((socket_helper.HOST, 0)) - self.server.start() + self.server_buffer = b'' + cb = lambda reader, writer: self.handle_new_client(reader, writer) + self.server = await asyncio.start_server(cb, socket_helper.HOSTv4) self.client = socket.socket() self.client.setblocking(False) l = asyncio.get_running_loop() - await l.sock_connect(self.client, (self.server.host, self.server.port)) + await l.sock_connect(self.client, self.server.sockets[0].getsockname()) self.client.settimeout(1) # synchronize by waiting for "220 ready" response self.client.recv(1024) @@ -3347,9 +3357,7 @@ async def asyncSetUp(self): async def asyncTearDown(self): self.file.close() self.client.close() - if self.server.running: - self.server.stop() - self.server = None + await self.server.wait_closed() # Use the test subject instead of asyncio.loop.sendfile @staticmethod @@ -3392,10 +3400,9 @@ async def test_send_whole_file(self): self.assertEqual(total_sent, len(self.DATA)) self.client.shutdown(socket.SHUT_RDWR) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() - self.assertEqual(len(data), len(self.DATA)) - self.assertEqual(data, self.DATA) + await self.server.wait_closed() + self.assertEqual(len(self.server_buffer), len(self.DATA)) + self.assertEqual(self.server_buffer, self.DATA) async def test_send_at_certain_offset(self): # start sending a file at a certain offset @@ -3414,12 +3421,11 @@ async def test_send_at_certain_offset(self): self.client.shutdown(socket.SHUT_RDWR) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() + await self.server.wait_closed() expected = self.DATA[len(self.DATA) // 2:] self.assertEqual(total_sent, len(expected)) - self.assertEqual(len(data), len(expected)) - self.assertEqual(data, expected) + self.assertEqual(len(self.server_buffer), len(expected)) + self.assertEqual(self.server_buffer, expected) async def test_offset_overflow(self): # specify an offset > file size @@ -3435,9 +3441,8 @@ async def test_offset_overflow(self): self.assertEqual(sent, 0) self.client.shutdown(socket.SHUT_RDWR) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() - self.assertEqual(data, b'') + await self.server.wait_closed() + self.assertEqual(self.server_buffer, b'') async def test_invalid_offset(self): with self.assertRaises(OSError) as cm: @@ -3476,9 +3481,8 @@ async def test_headers(self): self.assertEqual(total_sent, len(expected_data)) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() - self.assertEqual(hash(data), hash(expected_data)) + await self.server.wait_closed() + self.assertEqual(hash(self.server_buffer), hash(expected_data)) @requires_headers_trailers async def test_trailers(self): @@ -3492,9 +3496,8 @@ async def test_trailers(self): await self.async_sendfile(self.sockno, f.fileno(), 0, 5, trailers=[b"123456", b"789"]) self.client.close() - self.server.wait() - data = self.server.handler_instance.get_data() - self.assertEqual(data, b"abcde123456789") + await self.server.wait_closed() + self.assertEqual(self.server_buffer, b"abcde123456789") @requires_headers_trailers @requires_32b From dcb42518fdef4bda9a357e416691b6663c46d728 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Fri, 18 Mar 2022 19:27:52 +0300 Subject: [PATCH 05/14] Turn client data reading loop into a comprehension --- Lib/test/test_os.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 2aaea61aaa0dd7..ebaac9c9a7128f 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3330,12 +3330,14 @@ def tearDownClass(cls): threading_helper.threading_cleanup(*cls.key) os_helper.unlink(os_helper.TESTFN) + @staticmethod + async def chunks(reader): + while not reader.at_eof(): + yield await reader.read() + async def handle_new_client(self, reader, writer): writer.write(b"220 ready\r\n") - buffer = [] - while not reader.at_eof(): - buffer.append(await reader.read()) - self.server_buffer = b''.join(buffer) + self.server_buffer = b''.join([x async for x in self.chunks(reader)]) writer.close() self.server.close() # The test server processes a single client only From 4cc77666ea83726ff39041e30a370fc59e86be09 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Wed, 16 Mar 2022 10:15:29 +0300 Subject: [PATCH 06/14] Remove redundant synchronization --- Lib/test/test_os.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index ebaac9c9a7128f..6dfa3c8231e35f 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3336,7 +3336,6 @@ async def chunks(reader): yield await reader.read() async def handle_new_client(self, reader, writer): - writer.write(b"220 ready\r\n") self.server_buffer = b''.join([x async for x in self.chunks(reader)]) writer.close() self.server.close() # The test server processes a single client only @@ -3349,9 +3348,6 @@ async def asyncSetUp(self): self.client.setblocking(False) l = asyncio.get_running_loop() await l.sock_connect(self.client, self.server.sockets[0].getsockname()) - self.client.settimeout(1) - # synchronize by waiting for "220 ready" response - self.client.recv(1024) self.sockno = self.client.fileno() self.file = open(os_helper.TESTFN, 'rb') self.fileno = self.file.fileno() From 8c904794ad4e0d781f32ec192b3b832e27da4750 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Sun, 13 Mar 2022 23:18:02 +0300 Subject: [PATCH 07/14] Remove an old, asyncore server --- Lib/test/test_os.py | 91 --------------------------------------------- 1 file changed, 91 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 6dfa3c8231e35f..df7f1285135ac0 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -38,11 +38,6 @@ from test.support import warnings_helper from platform import win32_is_iot -with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - import asynchat - import asyncore - try: import resource except ImportError: @@ -3222,92 +3217,6 @@ def test_set_get_priority(self): raise -class SendfileTestServer(asyncore.dispatcher, threading.Thread): - - class Handler(asynchat.async_chat): - - def __init__(self, conn): - asynchat.async_chat.__init__(self, conn) - self.in_buffer = [] - self.accumulate = True - self.closed = False - self.push(b"220 ready\r\n") - - def handle_read(self): - data = self.recv(4096) - if self.accumulate: - self.in_buffer.append(data) - - def get_data(self): - return b''.join(self.in_buffer) - - def handle_close(self): - self.close() - self.closed = True - - def handle_error(self): - raise - - def __init__(self, address): - threading.Thread.__init__(self) - asyncore.dispatcher.__init__(self) - self.create_socket(socket.AF_INET, socket.SOCK_STREAM) - self.bind(address) - self.listen(5) - self.host, self.port = self.socket.getsockname()[:2] - self.handler_instance = None - self._active = False - self._active_lock = threading.Lock() - - # --- public API - - @property - def running(self): - return self._active - - def start(self): - assert not self.running - self.__flag = threading.Event() - threading.Thread.start(self) - self.__flag.wait() - - def stop(self): - assert self.running - self._active = False - self.join() - - def wait(self): - # wait for handler connection to be closed, then stop the server - while not getattr(self.handler_instance, "closed", False): - time.sleep(0.001) - self.stop() - - # --- internals - - def run(self): - self._active = True - self.__flag.set() - while self._active and asyncore.socket_map: - self._active_lock.acquire() - asyncore.loop(timeout=0.001, count=1) - self._active_lock.release() - asyncore.close_all() - - def handle_accept(self): - conn, addr = self.accept() - self.handler_instance = self.Handler(conn) - - def handle_connect(self): - self.close() - handle_read = handle_connect - - def writable(self): - return 0 - - def handle_error(self): - raise - - @unittest.skipUnless(hasattr(os, 'sendfile'), "test needs os.sendfile()") class TestSendfile(unittest.IsolatedAsyncioTestCase): From 8fc1e785c526e500177726488370eac851bbefc4 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Sun, 13 Mar 2022 23:19:31 +0300 Subject: [PATCH 08/14] Remove threading infrastructure --- Lib/test/test_os.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index df7f1285135ac0..ad15ef94a603c2 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -24,7 +24,6 @@ import sys import sysconfig import tempfile -import threading import time import types import unittest @@ -34,7 +33,6 @@ from test.support import import_helper from test.support import os_helper from test.support import socket_helper -from test.support import threading_helper from test.support import warnings_helper from platform import win32_is_iot @@ -3231,12 +3229,10 @@ class TestSendfile(unittest.IsolatedAsyncioTestCase): @classmethod def setUpClass(cls): - cls.key = threading_helper.threading_setup() create_file(os_helper.TESTFN, cls.DATA) @classmethod def tearDownClass(cls): - threading_helper.threading_cleanup(*cls.key) os_helper.unlink(os_helper.TESTFN) @staticmethod From 9882dafd3e330623b2eb19261b8aff796ba16e41 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Mon, 14 Mar 2022 15:28:38 +0300 Subject: [PATCH 09/14] Add a NEWS entry --- Misc/NEWS.d/next/Tests/2022-03-13-23-43-40.bpo-47015.FjmCsz.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2022-03-13-23-43-40.bpo-47015.FjmCsz.rst diff --git a/Misc/NEWS.d/next/Tests/2022-03-13-23-43-40.bpo-47015.FjmCsz.rst b/Misc/NEWS.d/next/Tests/2022-03-13-23-43-40.bpo-47015.FjmCsz.rst new file mode 100644 index 00000000000000..12c527ad1f23bc --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2022-03-13-23-43-40.bpo-47015.FjmCsz.rst @@ -0,0 +1,2 @@ +A test case for :func:`os.sendfile` is converted from deprecated +:mod:`asyncore` (see :pep:`594`) to :mod:`asyncio`. Patch by Oleg Iarygin. From 475b7e5d117d9d4edaba6736f363f6d974165ebd Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Fri, 18 Mar 2022 21:18:18 +0300 Subject: [PATCH 10/14] Add an explicit asyncio event loop policy --- Lib/test/test_os.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 3e74d3e6a36832..a2bfb5676b2200 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -64,6 +64,8 @@ from test.support.os_helper import FakePath +asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy()) + root_in_posix = False if hasattr(os, 'geteuid'): root_in_posix = (os.geteuid() == 0) From ccb26dd8d59801c054c611c91b2a6c273277fb8a Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Fri, 18 Mar 2022 22:59:49 +0300 Subject: [PATCH 11/14] Address a review of merwok --- Lib/test/test_os.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index a2bfb5676b2200..b38d77476348ca 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3256,8 +3256,8 @@ async def handle_new_client(self, reader, writer): async def asyncSetUp(self): self.server_buffer = b'' - cb = lambda reader, writer: self.handle_new_client(reader, writer) - self.server = await asyncio.start_server(cb, socket_helper.HOSTv4) + self.server = await asyncio.start_server(self.handle_new_client, + socket_helper.HOSTv4) self.client = socket.socket() self.client.setblocking(False) l = asyncio.get_running_loop() From 34f198cb676957982360d168fbfff87168932416 Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Sat, 19 Mar 2022 07:44:57 +0300 Subject: [PATCH 12/14] Address a review of asvetlov --- Lib/test/test_os.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index b38d77476348ca..f05bb5e902021d 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -64,8 +64,6 @@ from test.support.os_helper import FakePath -asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy()) - root_in_posix = False if hasattr(os, 'geteuid'): root_in_posix = (os.geteuid() == 0) @@ -97,6 +95,10 @@ def create_file(filename, content=b'content'): 'on AIX, splice() only accepts sockets') +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + class MiscTests(unittest.TestCase): def test_getcwd(self): cwd = os.getcwd() @@ -3260,8 +3262,8 @@ async def asyncSetUp(self): socket_helper.HOSTv4) self.client = socket.socket() self.client.setblocking(False) - l = asyncio.get_running_loop() - await l.sock_connect(self.client, self.server.sockets[0].getsockname()) + server_name = self.server.sockets[0].getsockname() + await asyncio.get_running_loop().sock_connect(self.client, server_name) self.sockno = self.client.fileno() self.file = open(os_helper.TESTFN, 'rb') self.fileno = self.file.fileno() From 005ad9a898c5ba414f5263a964e6588bcc6f7ccc Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Sat, 19 Mar 2022 08:11:50 +0300 Subject: [PATCH 13/14] Group server stuff together Without the grouping, reading code as a prose becomes harder: > Start the server. For a client, create a socket, set it nonblocking, > get a server name that is a name of its listening port, connect to the > server. instead of: > Start the server, its name is a name of its listening port. For > a client, create a socket, set it nonblocking, connect to the server. --- Lib/test/test_os.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index f05bb5e902021d..34990f95e1124f 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3260,9 +3260,9 @@ async def asyncSetUp(self): self.server_buffer = b'' self.server = await asyncio.start_server(self.handle_new_client, socket_helper.HOSTv4) + server_name = self.server.sockets[0].getsockname() self.client = socket.socket() self.client.setblocking(False) - server_name = self.server.sockets[0].getsockname() await asyncio.get_running_loop().sock_connect(self.client, server_name) self.sockno = self.client.fileno() self.file = open(os_helper.TESTFN, 'rb') From 03cae533ebb02d359092785dc2dd14a38ca937ab Mon Sep 17 00:00:00 2001 From: Oleg Iarygin Date: Sat, 19 Mar 2022 20:00:30 +0300 Subject: [PATCH 14/14] Fix a call of `async_sendfile` in `test_flags` --- Lib/test/test_os.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 34990f95e1124f..9a60bf5f7fdd5c 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3436,8 +3436,8 @@ async def test_trailers_overflow_32bits(self): 'test needs os.SF_NODISKIO') async def test_flags(self): try: - await async_sendfile(self.sockno, self.fileno, 0, 4096, - flags=os.SF_NODISKIO) + await self.async_sendfile(self.sockno, self.fileno, 0, 4096, + flags=os.SF_NODISKIO) except OSError as err: if err.errno not in (errno.EBUSY, errno.EAGAIN): raise