From a2877c7be2f8ee0f0f73071a81864062cbb1a73a Mon Sep 17 00:00:00 2001 From: Min RK Date: Tue, 3 Dec 2024 09:13:31 +0100 Subject: [PATCH] satisfy updated ruff rules mostly f-strings, manual fixes --- examples/service-whoami-flask/whoami-flask.py | 1 - jupyterhub/apihandlers/users.py | 2 +- jupyterhub/app.py | 2 +- jupyterhub/auth.py | 2 +- jupyterhub/handlers/base.py | 10 ++++++---- jupyterhub/orm.py | 2 +- jupyterhub/tests/conftest.py | 7 ++++--- jupyterhub/tests/mocking.py | 2 +- jupyterhub/tests/test_crypto.py | 4 ++-- jupyterhub/tests/test_orm.py | 12 ++++++------ jupyterhub/tests/test_pages.py | 2 +- jupyterhub/tests/test_proxy.py | 6 +++--- jupyterhub/tests/test_services.py | 2 +- jupyterhub/tests/test_spawner.py | 2 +- jupyterhub/user.py | 19 ++++++++----------- jupyterhub/utils.py | 14 +++++++------- 16 files changed, 44 insertions(+), 45 deletions(-) diff --git a/examples/service-whoami-flask/whoami-flask.py b/examples/service-whoami-flask/whoami-flask.py index 2831d8c1..c960938c 100644 --- a/examples/service-whoami-flask/whoami-flask.py +++ b/examples/service-whoami-flask/whoami-flask.py @@ -9,7 +9,6 @@ import secrets from functools import wraps from flask import Flask, Response, make_response, redirect, request, session - from jupyterhub.services.auth import HubOAuth prefix = os.environ.get('JUPYTERHUB_SERVICE_PREFIX', '/') diff --git a/jupyterhub/apihandlers/users.py b/jupyterhub/apihandlers/users.py index 2dc4b43e..9511fdc7 100644 --- a/jupyterhub/apihandlers/users.py +++ b/jupyterhub/apihandlers/users.py @@ -260,7 +260,7 @@ class UserListAPIHandler(APIHandler): raise web.HTTPError(400, msg) if not to_create: - raise web.HTTPError(409, "All %i users already exist" % len(usernames)) + raise web.HTTPError(409, f"All {len(usernames)} users already exist") created = [] for name in to_create: diff --git a/jupyterhub/app.py b/jupyterhub/app.py index 38b5eb06..f867a19c 100644 --- a/jupyterhub/app.py +++ b/jupyterhub/app.py @@ -3320,7 +3320,7 @@ class JupyterHub(Application): if self.pid_file: self.log.debug("Writing PID %i to %s", pid, self.pid_file) with open(self.pid_file, 'w') as f: - f.write('%i' % pid) + f.write(str(pid)) @catch_config_error async def initialize(self, *args, **kwargs): diff --git a/jupyterhub/auth.py b/jupyterhub/auth.py index e622f403..d5ba38dc 100644 --- a/jupyterhub/auth.py +++ b/jupyterhub/auth.py @@ -1225,7 +1225,7 @@ class LocalAuthenticator(Authenticator): cmd = [arg.replace('USERNAME', name) for arg in self.add_user_cmd] try: uid = self.uids[name] - cmd += ['--uid', '%d' % uid] + cmd += ['--uid', str(uid)] except KeyError: self.log.debug(f"No UID for user {name}") cmd += [name] diff --git a/jupyterhub/handlers/base.py b/jupyterhub/handlers/base.py index 58732620..458a364b 100644 --- a/jupyterhub/handlers/base.py +++ b/jupyterhub/handlers/base.py @@ -1061,10 +1061,12 @@ class BaseHandler(RequestHandler): # round suggestion to nicer human value (nearest 10 seconds or minute) if retry_time <= 90: # round human seconds up to nearest 10 - human_retry_time = "%i0 seconds" % math.ceil(retry_time / 10.0) + delay = math.ceil(retry_time / 10.0) + human_retry_time = f"{delay}0 seconds" else: # round number of minutes - human_retry_time = "%i minutes" % round(retry_time / 60.0) + delay = round(retry_time / 60.0) + human_retry_time = f"{delay} minutes" self.log.warning( '%s pending spawns, throttling. Suggested retry in %s seconds.', @@ -1099,12 +1101,12 @@ class BaseHandler(RequestHandler): self.log.debug( "%i%s concurrent spawns", spawn_pending_count, - '/%i' % concurrent_spawn_limit if concurrent_spawn_limit else '', + f'/{concurrent_spawn_limit}' if concurrent_spawn_limit else '', ) self.log.debug( "%i%s active servers", active_count, - '/%i' % active_server_limit if active_server_limit else '', + f'/{active_server_limit}' if active_server_limit else '', ) spawner = user.spawners[server_name] diff --git a/jupyterhub/orm.py b/jupyterhub/orm.py index 1998c5f6..a08b6967 100644 --- a/jupyterhub/orm.py +++ b/jupyterhub/orm.py @@ -1050,7 +1050,7 @@ class APIToken(Hashed, Base): @property def api_id(self): - return 'a%i' % self.id + return f"a{self.id}" @property def owner(self): diff --git a/jupyterhub/tests/conftest.py b/jupyterhub/tests/conftest.py index f5e42891..6d994d55 100644 --- a/jupyterhub/tests/conftest.py +++ b/jupyterhub/tests/conftest.py @@ -358,14 +358,15 @@ async def _mockservice(request, app, name, external=False, url=False): (as opposed to headless, API-only). """ spec = {'name': name, 'command': mockservice_cmd, 'admin': True} + port = random_port() if url: if app.internal_ssl: - spec['url'] = 'https://127.0.0.1:%i' % random_port() + spec['url'] = f'https://127.0.0.1:{port}' else: - spec['url'] = 'http://127.0.0.1:%i' % random_port() + spec['url'] = f'http://127.0.0.1:{port}' if external: - spec['oauth_redirect_uri'] = 'http://127.0.0.1:%i' % random_port() + spec['oauth_redirect_uri'] = f'http://127.0.0.1:{port}' event_loop = asyncio.get_running_loop() diff --git a/jupyterhub/tests/mocking.py b/jupyterhub/tests/mocking.py index f441cd67..29ffae2c 100644 --- a/jupyterhub/tests/mocking.py +++ b/jupyterhub/tests/mocking.py @@ -256,7 +256,7 @@ class MockHub(JupyterHub): port = urlparse(self.subdomain_host).port else: port = random_port() - return 'http://127.0.0.1:%i/@/space%%20word/' % (port,) + return f'http://127.0.0.1:{port}/@/space%20word/' @default('ip') def _ip_default(self): diff --git a/jupyterhub/tests/test_crypto.py b/jupyterhub/tests/test_crypto.py index 20d5f62b..9320cb4f 100644 --- a/jupyterhub/tests/test_crypto.py +++ b/jupyterhub/tests/test_crypto.py @@ -7,7 +7,7 @@ import pytest from .. import crypto from ..crypto import decrypt, encrypt -keys = [('%i' % i).encode('ascii') * 32 for i in range(3)] +keys = [str(i).encode('ascii') * 32 for i in range(3)] hex_keys = [b2a_hex(key).decode('ascii') for key in keys] b64_keys = [b2a_base64(key).decode('ascii').strip() for key in keys] @@ -36,7 +36,7 @@ def test_env_constructor(key_env, keys): "key", [ 'a' * 44, # base64, not 32 bytes - ('%44s' % 'notbase64'), # not base64 + f"{'notbase64':44}", # not base64 b'x' * 64, # not hex b'short', # not 32 bytes ], diff --git a/jupyterhub/tests/test_orm.py b/jupyterhub/tests/test_orm.py index 09dac989..5f2d7dc1 100644 --- a/jupyterhub/tests/test_orm.py +++ b/jupyterhub/tests/test_orm.py @@ -33,19 +33,19 @@ def test_server(db): # test wrapper server = objects.Server(orm_server=server) - assert server.host == 'http://%s:%i' % (socket.gethostname(), server.port) + assert server.host == f'http://{socket.gethostname()}:{server.port}' assert server.url == server.host + '/' - assert server.bind_url == 'http://*:%i/' % server.port + assert server.bind_url == f'http://*:{server.port}/' server.ip = '127.0.0.1' - assert server.host == 'http://127.0.0.1:%i' % server.port + assert server.host == f'http://127.0.0.1:{server.port}' assert server.url == server.host + '/' server.connect_ip = 'hub' - assert server.host == 'http://hub:%i' % server.port + assert server.host == f'http://hub:{server.port}' assert server.url == server.host + '/' - server.connect_url = 'http://hub-url:%i/connect' % server.port - assert server.host == 'http://hub-url:%i' % server.port + server.connect_url = f'http://hub-url:{server.port}/connect' + assert server.host == f'http://hub-url:{server.port}' server.bind_url = 'http://127.0.0.1/' assert server.port == 80 diff --git a/jupyterhub/tests/test_pages.py b/jupyterhub/tests/test_pages.py index fb6de52c..bc76bead 100644 --- a/jupyterhub/tests/test_pages.py +++ b/jupyterhub/tests/test_pages.py @@ -1060,7 +1060,7 @@ async def test_oauth_token_page(app): @pytest.mark.parametrize("error_status", [503, 404]) async def test_proxy_error(app, error_status): - r = await get_page('/error/%i' % error_status, app) + r = await get_page(f'/error/{error_status}', app) assert r.status_code == 200 diff --git a/jupyterhub/tests/test_proxy.py b/jupyterhub/tests/test_proxy.py index 3f821c13..688892aa 100644 --- a/jupyterhub/tests/test_proxy.py +++ b/jupyterhub/tests/test_proxy.py @@ -35,7 +35,7 @@ async def test_external_proxy(request): proxy_port = random_port() cfg = Config() cfg.ConfigurableHTTPProxy.auth_token = auth_token - cfg.ConfigurableHTTPProxy.api_url = 'http://%s:%i' % (proxy_ip, proxy_port) + cfg.ConfigurableHTTPProxy.api_url = f'http://{proxy_ip}:{proxy_port}' cfg.ConfigurableHTTPProxy.should_start = False app = MockHub.instance(config=cfg) @@ -76,7 +76,7 @@ async def test_external_proxy(request): request.addfinalizer(_cleanup_proxy) def wait_for_proxy(): - return wait_for_http_server('http://%s:%i' % (proxy_ip, proxy_port)) + return wait_for_http_server(f'http://{proxy_ip}:{proxy_port}') await wait_for_proxy() @@ -141,7 +141,7 @@ async def test_external_proxy(request): '--api-port', str(proxy_port), '--default-target', - 'http://%s:%i' % (app.hub_ip, app.hub_port), + f'http://{app.hub_ip}:{app.hub_port}', ] if app.subdomain_host: cmd.append('--host-routing') diff --git a/jupyterhub/tests/test_services.py b/jupyterhub/tests/test_services.py index 9c41c422..9350e3d4 100644 --- a/jupyterhub/tests/test_services.py +++ b/jupyterhub/tests/test_services.py @@ -27,7 +27,7 @@ async def external_service(app, name='mockservice'): 'JUPYTERHUB_API_TOKEN': hexlify(os.urandom(5)), 'JUPYTERHUB_SERVICE_NAME': name, 'JUPYTERHUB_API_URL': url_path_join(app.hub.url, 'api/'), - 'JUPYTERHUB_SERVICE_URL': 'http://127.0.0.1:%i' % random_port(), + 'JUPYTERHUB_SERVICE_URL': f'http://127.0.0.1:{random_port()}', } proc = Popen(mockservice_cmd, env=env) try: diff --git a/jupyterhub/tests/test_spawner.py b/jupyterhub/tests/test_spawner.py index 7f141e30..e4c4b1d5 100644 --- a/jupyterhub/tests/test_spawner.py +++ b/jupyterhub/tests/test_spawner.py @@ -260,7 +260,7 @@ async def test_shell_cmd(db, tmpdir, request): s.server.port = port db.commit() await wait_for_spawner(s) - r = await async_requests.get('http://%s:%i/env' % (ip, port)) + r = await async_requests.get(f'http://{ip}:{port}/env') r.raise_for_status() env = r.json() assert env['TESTVAR'] == 'foo' diff --git a/jupyterhub/user.py b/jupyterhub/user.py index e6287fc1..aba33720 100644 --- a/jupyterhub/user.py +++ b/jupyterhub/user.py @@ -920,19 +920,16 @@ class User: await asyncio.wait_for(f, timeout=spawner.start_timeout) url = f.result() if url: - # get ip, port info from return value of start() - if isinstance(url, str): - # >= 0.9 can return a full URL string - pass - else: - # >= 0.7 returns (ip, port) + # get url from return value of start() + if not isinstance(url, str): + # older Spawners return (ip, port) proto = 'https' if self.settings['internal_ssl'] else 'http' - + ip, port = url # check if spawner returned an IPv6 address - if ':' in url[0]: - url = '%s://[%s]:%i' % ((proto,) + url) - else: - url = '%s://%s:%i' % ((proto,) + url) + if ':' in ip: + # ipv6 needs [::] in url + ip = f'[{ip}]' + url = f'{proto}://{ip}:{int(port)}' urlinfo = urlparse(url) server.proto = urlinfo.scheme server.ip = urlinfo.hostname diff --git a/jupyterhub/utils.py b/jupyterhub/utils.py index 3035e487..6ee7de66 100644 --- a/jupyterhub/utils.py +++ b/jupyterhub/utils.py @@ -502,20 +502,20 @@ def print_ps_info(file=sys.stderr): # format CPU percentage cpu = p.cpu_percent(0.1) if cpu >= 10: - cpu_s = "%i" % cpu + cpu_s = str(int(cpu)) else: cpu_s = f"{cpu:.1f}" # format memory (only resident set) rss = p.memory_info().rss if rss >= 1e9: - mem_s = '%.1fG' % (rss / 1e9) + mem_s = f'{rss / 1e9:.1f}G' elif rss >= 1e7: - mem_s = '%.0fM' % (rss / 1e6) + mem_s = f'{rss / 1e6:.0f}M' elif rss >= 1e6: - mem_s = '%.1fM' % (rss / 1e6) + mem_s = f'{rss / 1e6:.1f}M' else: - mem_s = '%.0fk' % (rss / 1e3) + mem_s = f'{rss / 1e3:.0f}k' # left-justify and shrink-to-fit columns cpulen = max(len(cpu_s), 4) @@ -560,7 +560,7 @@ def print_stacks(file=sys.stderr): from .log import coroutine_frames - print("Active threads: %i" % threading.active_count(), file=file) + print(f"Active threads: {threading.active_count()}", file=file) for thread in threading.enumerate(): print(f"Thread {thread.name}:", end='', file=file) frame = sys._current_frames()[thread.ident] @@ -592,7 +592,7 @@ def print_stacks(file=sys.stderr): # coroutines to native `async def` tasks = asyncio_all_tasks() if tasks: - print("AsyncIO tasks: %i" % len(tasks)) + print(f"AsyncIO tasks: {len(tasks)}") for task in tasks: task.print_stack(file=file)