From 5487aea09f35be017c1ceab886e47a2b058f0d9d Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 6 Mar 2023 09:36:34 -0600 Subject: [PATCH 1/5] fix port selection --- jupyter_server/serverapp.py | 51 ++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/jupyter_server/serverapp.py b/jupyter_server/serverapp.py index e266f118e6..215f479b23 100644 --- a/jupyter_server/serverapp.py +++ b/jupyter_server/serverapp.py @@ -35,6 +35,7 @@ from tornado import httpserver, ioloop, web from tornado.httputil import url_concat from tornado.log import LogFormatter, access_log, app_log, gen_log +from tornado.netutil import bind_sockets if not sys.platform.startswith("win"): from tornado.netutil import bind_unix_socket @@ -2410,17 +2411,10 @@ def _bind_http_server_tcp(self): def _find_http_port(self): """Find an available http port.""" - pat = re.compile("([a-f0-9:]+:+)+[a-f0-9]*") - success = None for port in random_ports(self.port, self.port_retries + 1): - tmp_sock = ( - socket.socket() - if pat.match(self.ip) is None - else socket.socket(family=socket.AF_INET6) - ) try: - tmp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, b"\0" * 8) - tmp_sock.bind((self.ip, port)) + sockets = bind_sockets(port, self.ip) + sockets[0].close() except OSError as e: if e.errno == errno.EADDRINUSE: if self.port_retries: @@ -2440,27 +2434,26 @@ def _find_http_port(self): raise else: self.port = port - success = True break - finally: - tmp_sock.close() - if not success: - if self.port_retries: - self.log.critical( - _i18n( - "ERROR: the Jupyter server could not be started because " - "no available port could be found." - ) - ) - else: - self.log.critical( - _i18n( - "ERROR: the Jupyter server could not be started because " - "port %i is not available." - ) - % port - ) - self.exit(1) + # finally: + # tmp_sock.close() + # if not success: + # if self.port_retries: + # self.log.critical( + # _i18n( + # "ERROR: the Jupyter server could not be started because " + # "no available port could be found." + # ) + # ) + # else: + # self.log.critical( + # _i18n( + # "ERROR: the Jupyter server could not be started because " + # "port %i is not available." + # ) + # % port + # ) + # self.exit(1) @staticmethod def _init_asyncio_patch(): From 2a2048e58068258253ac2f0dcc327f311436c812 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 6 Mar 2023 09:38:12 -0600 Subject: [PATCH 2/5] cleanup --- jupyter_server/serverapp.py | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/jupyter_server/serverapp.py b/jupyter_server/serverapp.py index 215f479b23..ee3caab116 100644 --- a/jupyter_server/serverapp.py +++ b/jupyter_server/serverapp.py @@ -2411,6 +2411,8 @@ def _bind_http_server_tcp(self): def _find_http_port(self): """Find an available http port.""" + success = False + port = self.port for port in random_ports(self.port, self.port_retries + 1): try: sockets = bind_sockets(port, self.ip) @@ -2435,25 +2437,23 @@ def _find_http_port(self): else: self.port = port break - # finally: - # tmp_sock.close() - # if not success: - # if self.port_retries: - # self.log.critical( - # _i18n( - # "ERROR: the Jupyter server could not be started because " - # "no available port could be found." - # ) - # ) - # else: - # self.log.critical( - # _i18n( - # "ERROR: the Jupyter server could not be started because " - # "port %i is not available." - # ) - # % port - # ) - # self.exit(1) + if not success: + if self.port_retries: + self.log.critical( + _i18n( + "ERROR: the Jupyter server could not be started because " + "no available port could be found." + ) + ) + else: + self.log.critical( + _i18n( + "ERROR: the Jupyter server could not be started because " + "port %i is not available." + ) + % port + ) + self.exit(1) @staticmethod def _init_asyncio_patch(): From e63685fdf204b36b8b03afade08404cd5081971b Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 6 Mar 2023 09:43:01 -0600 Subject: [PATCH 3/5] fix logic --- jupyter_server/serverapp.py | 1 + 1 file changed, 1 insertion(+) diff --git a/jupyter_server/serverapp.py b/jupyter_server/serverapp.py index ee3caab116..27dac22316 100644 --- a/jupyter_server/serverapp.py +++ b/jupyter_server/serverapp.py @@ -2435,6 +2435,7 @@ def _find_http_port(self): else: raise else: + success = True self.port = port break if not success: From f8d959737ab7793683be13099afacf72f7f1f23e Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 6 Mar 2023 10:53:38 -0600 Subject: [PATCH 4/5] skip two tests on pypy --- tests/unix_sockets/test_serverapp_integration.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/unix_sockets/test_serverapp_integration.py b/tests/unix_sockets/test_serverapp_integration.py index 47481cba4e..ec9aa99ecb 100644 --- a/tests/unix_sockets/test_serverapp_integration.py +++ b/tests/unix_sockets/test_serverapp_integration.py @@ -1,4 +1,5 @@ import os +import platform import shlex import stat import subprocess @@ -188,6 +189,7 @@ def test_launch_socket_collision(jp_unix_socket_file): @pytest.mark.integration_test +@pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="not supported on pypy") def test_shutdown_server(jp_environ): # Start a server in another process # Stop that server @@ -213,6 +215,7 @@ def test_shutdown_server(jp_environ): @pytest.mark.integration_test +@pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="not supported on pypy") def test_jupyter_server_apps(jp_environ): # Start a server in another process # Stop that server From fa22433024f714ce5cb27028d7e4ca3f0b5b8042 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 6 Mar 2023 11:00:57 -0600 Subject: [PATCH 5/5] another skip --- tests/unix_sockets/test_serverapp_integration.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/unix_sockets/test_serverapp_integration.py b/tests/unix_sockets/test_serverapp_integration.py index ec9aa99ecb..1a2ee7325d 100644 --- a/tests/unix_sockets/test_serverapp_integration.py +++ b/tests/unix_sockets/test_serverapp_integration.py @@ -18,7 +18,8 @@ # Skip this module if on Windows. Unix sockets are not available on Windows. pytestmark = pytest.mark.skipif( - sys.platform.startswith("win"), reason="Unix sockets are not available on Windows." + sys.platform.startswith("win") or platform.python_implementation() == "PyPy", + reason="Unix sockets are not supported.", ) @@ -189,7 +190,6 @@ def test_launch_socket_collision(jp_unix_socket_file): @pytest.mark.integration_test -@pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="not supported on pypy") def test_shutdown_server(jp_environ): # Start a server in another process # Stop that server @@ -215,7 +215,6 @@ def test_shutdown_server(jp_environ): @pytest.mark.integration_test -@pytest.mark.skipif(platform.python_implementation() == "PyPy", reason="not supported on pypy") def test_jupyter_server_apps(jp_environ): # Start a server in another process # Stop that server