diff --git a/bower-lite b/bower-lite
index 5276b6c8..f6b176bd 100755
--- a/bower-lite
+++ b/bower-lite
@@ -29,5 +29,5 @@ dependencies = package_json['dependencies']
for dep in dependencies:
src = join(node_modules, dep)
dest = join(components, dep)
- print("%s -> %s" % (src, dest))
+ print(f"{src} -> {dest}")
shutil.copytree(src, dest)
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 20ab77a4..50267e6a 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
import os
import sys
@@ -29,9 +28,9 @@ myst_enable_extensions = [
master_doc = 'index'
# General information about the project.
-project = u'JupyterHub'
-copyright = u'2016, Project Jupyter team'
-author = u'Project Jupyter team'
+project = 'JupyterHub'
+copyright = '2016, Project Jupyter team'
+author = 'Project Jupyter team'
# Autopopulate version
from os.path import dirname
@@ -146,8 +145,8 @@ latex_documents = [
(
master_doc,
'JupyterHub.tex',
- u'JupyterHub Documentation',
- u'Project Jupyter team',
+ 'JupyterHub Documentation',
+ 'Project Jupyter team',
'manual',
)
]
@@ -164,7 +163,7 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
-man_pages = [(master_doc, 'jupyterhub', u'JupyterHub Documentation', [author], 1)]
+man_pages = [(master_doc, 'jupyterhub', 'JupyterHub Documentation', [author], 1)]
# man_show_urls = False
@@ -178,7 +177,7 @@ texinfo_documents = [
(
master_doc,
'JupyterHub',
- u'JupyterHub Documentation',
+ 'JupyterHub Documentation',
author,
'JupyterHub',
'One line description of project.',
diff --git a/examples/service-notebook/external/jupyterhub_config.py b/examples/service-notebook/external/jupyterhub_config.py
index 21911fc8..e6371389 100644
--- a/examples/service-notebook/external/jupyterhub_config.py
+++ b/examples/service-notebook/external/jupyterhub_config.py
@@ -13,7 +13,7 @@ c.JupyterHub.load_groups = {group_name: ['ellisonbg', 'willingc']}
c.JupyterHub.services = [
{
'name': service_name,
- 'url': 'http://127.0.0.1:{}'.format(service_port),
+ 'url': f'http://127.0.0.1:{service_port}',
'api_token': 'c3a29e5d386fd7c9aa1e8fe9d41c282ec8b',
}
]
diff --git a/examples/service-notebook/managed/jupyterhub_config.py b/examples/service-notebook/managed/jupyterhub_config.py
index 10b95ef0..1102dda9 100644
--- a/examples/service-notebook/managed/jupyterhub_config.py
+++ b/examples/service-notebook/managed/jupyterhub_config.py
@@ -13,7 +13,7 @@ c.JupyterHub.load_groups = {group_name: ['ellisonbg', 'willingc']}
c.JupyterHub.services = [
{
'name': service_name,
- 'url': 'http://127.0.0.1:{}'.format(service_port),
+ 'url': f'http://127.0.0.1:{service_port}',
'command': ['jupyterhub-singleuser', '--debug'],
}
]
diff --git a/jupyterhub/_version.py b/jupyterhub/_version.py
index dec40e86..8ba9425d 100644
--- a/jupyterhub/_version.py
+++ b/jupyterhub/_version.py
@@ -60,7 +60,7 @@ def _check_version(hub_version, singleuser_version, log):
log_method = log.debug
else:
# log warning-level for more significant mismatch, such as 0.8 vs 0.9, etc.
- key = '%s-%s' % (hub_version, singleuser_version)
+ key = f'{hub_version}-{singleuser_version}'
global _version_mismatch_warning_logged
if _version_mismatch_warning_logged.get(key):
do_log = False # We already logged this warning so don't log it again.
diff --git a/jupyterhub/apihandlers/auth.py b/jupyterhub/apihandlers/auth.py
index ee0a5343..7a787928 100644
--- a/jupyterhub/apihandlers/auth.py
+++ b/jupyterhub/apihandlers/auth.py
@@ -190,9 +190,9 @@ class OAuthAuthorizeHandler(OAuthHandler, BaseHandler):
.. versionadded: 1.1
"""
# get the oauth client ids for the user's own server(s)
- own_oauth_client_ids = set(
+ own_oauth_client_ids = {
spawner.oauth_client_id for spawner in user.spawners.values()
- )
+ }
if (
# it's the user's own server
oauth_client.identifier in own_oauth_client_ids
diff --git a/jupyterhub/apihandlers/hub.py b/jupyterhub/apihandlers/hub.py
index 3a4787f5..129fd921 100644
--- a/jupyterhub/apihandlers/hub.py
+++ b/jupyterhub/apihandlers/hub.py
@@ -74,9 +74,7 @@ class InfoAPIHandler(APIHandler):
def _class_info(typ):
"""info about a class (Spawner or Authenticator)"""
- info = {
- 'class': '{mod}.{name}'.format(mod=typ.__module__, name=typ.__name__)
- }
+ info = {'class': f'{typ.__module__}.{typ.__name__}'}
pkg = typ.__module__.split('.')[0]
try:
version = sys.modules[pkg].__version__
diff --git a/jupyterhub/apihandlers/users.py b/jupyterhub/apihandlers/users.py
index 124049f9..bc12db6c 100644
--- a/jupyterhub/apihandlers/users.py
+++ b/jupyterhub/apihandlers/users.py
@@ -210,9 +210,7 @@ class UserListAPIHandler(APIHandler):
except Exception as e:
self.log.error("Failed to create user: %s" % name, exc_info=True)
self.users.delete(user)
- raise web.HTTPError(
- 400, "Failed to create user %s: %s" % (name, str(e))
- )
+ raise web.HTTPError(400, f"Failed to create user {name}: {str(e)}")
else:
created.append(user)
@@ -394,7 +392,7 @@ class UserTokenListAPIHandler(APIHandler):
if not note:
note = "Requested via api"
if requester is not user:
- note += " by %s %s" % (kind, requester.name)
+ note += f" by {kind} {requester.name}"
token_roles = body.get('roles')
try:
@@ -434,7 +432,7 @@ class UserTokenAPIHandler(APIHandler):
Raises 404 if not found for any reason
(e.g. wrong owner, invalid key format, etc.)
"""
- not_found = "No such token %s for user %s" % (token_id, user.name)
+ not_found = f"No such token {token_id} for user {user.name}"
prefix, id_ = token_id[:1], token_id[1:]
if prefix != 'a':
raise web.HTTPError(404, not_found)
@@ -508,7 +506,7 @@ class UserServerAPIHandler(APIHandler):
self.set_status(202)
return
elif pending:
- raise web.HTTPError(400, "%s is pending %s" % (spawner._log_name, pending))
+ raise web.HTTPError(400, f"{spawner._log_name} is pending {pending}")
if spawner.ready:
# include notify, so that a server that died is noticed immediately
@@ -554,7 +552,7 @@ class UserServerAPIHandler(APIHandler):
raise web.HTTPError(400, "Named servers are not enabled.")
if server_name not in user.orm_spawners:
raise web.HTTPError(
- 404, "%s has no server named '%s'" % (user_name, server_name)
+ 404, f"{user_name} has no server named '{server_name}'"
)
elif remove:
raise web.HTTPError(400, "Cannot delete the default server")
@@ -572,7 +570,7 @@ class UserServerAPIHandler(APIHandler):
if spawner.pending:
raise web.HTTPError(
400,
- "%s is pending %s, please wait" % (spawner._log_name, spawner.pending),
+ f"{spawner._log_name} is pending {spawner.pending}, please wait",
)
stop_future = None
@@ -627,7 +625,7 @@ class SpawnProgressAPIHandler(APIHandler):
async def send_event(self, event):
try:
- self.write('data: {}\n\n'.format(json.dumps(event)))
+ self.write(f'data: {json.dumps(event)}\n\n')
await self.flush()
except StreamClosedError:
self.log.warning("Stream closed while handling %s", self.request.uri)
@@ -681,7 +679,7 @@ class SpawnProgressAPIHandler(APIHandler):
ready_event = {
'progress': 100,
'ready': True,
- 'message': "Server ready at {}".format(url),
+ 'message': f"Server ready at {url}",
'html_message': 'Server ready at {0}'.format(url),
'url': url,
}
@@ -784,7 +782,7 @@ class ActivityAPIHandler(APIHandler):
if server_name not in spawners:
raise web.HTTPError(
400,
- "No such server '{}' for user {}".format(server_name, user.name),
+ f"No such server '{server_name}' for user {user.name}",
)
# check that each per-server field is a dict
if not isinstance(server_info, dict):
diff --git a/jupyterhub/app.py b/jupyterhub/app.py
index deb6cf4b..801c3785 100644
--- a/jupyterhub/app.py
+++ b/jupyterhub/app.py
@@ -2208,7 +2208,7 @@ class JupyterHub(Application):
"""
# this should be all the subclasses of Expiring
for cls in (orm.APIToken, orm.OAuthCode):
- self.log.debug("Purging expired {name}s".format(name=cls.__name__))
+ self.log.debug(f"Purging expired {cls.__name__}s")
cls.purge_expired(self.db)
async def init_api_tokens(self):
@@ -2232,7 +2232,7 @@ class JupyterHub(Application):
if self.domain:
domain = 'services.' + self.domain
parsed = urlparse(self.subdomain_host)
- host = '%s://services.%s' % (parsed.scheme, parsed.netloc)
+ host = f'{parsed.scheme}://services.{parsed.netloc}'
else:
domain = host = ''
@@ -2359,14 +2359,12 @@ class JupyterHub(Application):
def _user_summary(user):
"""user is an orm.User, not a full user"""
- parts = ['{0: >8}'.format(user.name)]
+ parts = [f'{user.name: >8}']
if user.admin:
parts.append('admin')
for name, spawner in sorted(user.orm_spawners.items(), key=itemgetter(0)):
if spawner.server:
- parts.append(
- '%s:%s running at %s' % (user.name, name, spawner.server)
- )
+ parts.append(f'{user.name}:{name} running at {spawner.server}')
return ' '.join(parts)
async def user_stopped(user, server_name):
@@ -2703,7 +2701,7 @@ class JupyterHub(Application):
self.log.warning(
"Use JupyterHub in config, not JupyterHubApp. Outdated config:\n%s",
'\n'.join(
- 'JupyterHubApp.{key} = {value!r}'.format(key=key, value=value)
+ f'JupyterHubApp.{key} = {value!r}'
for key, value in self.config.JupyterHubApp.items()
),
)
@@ -2725,7 +2723,7 @@ class JupyterHub(Application):
mod = sys.modules.get(cls.__module__.split('.')[0])
version = getattr(mod, '__version__', '')
if version:
- version = '-{}'.format(version)
+ version = f'-{version}'
else:
version = ''
self.log.info(
@@ -3025,11 +3023,7 @@ class JupyterHub(Application):
# start the service(s)
for service_name, service in self._service_map.items():
- msg = (
- '%s at %s' % (service_name, service.url)
- if service.url
- else service_name
- )
+ msg = f'{service_name} at {service.url}' if service.url else service_name
if service.managed:
self.log.info("Starting managed service %s", msg)
try:
diff --git a/jupyterhub/auth.py b/jupyterhub/auth.py
index d977b824..5ac706c4 100644
--- a/jupyterhub/auth.py
+++ b/jupyterhub/auth.py
@@ -926,7 +926,7 @@ class LocalAuthenticator(Authenticator):
p.wait()
if p.returncode:
err = p.stdout.read().decode('utf8', 'replace')
- raise RuntimeError("Failed to create system user %s: %s" % (name, err))
+ raise RuntimeError(f"Failed to create system user {name}: {err}")
class PAMAuthenticator(LocalAuthenticator):
diff --git a/jupyterhub/dbutil.py b/jupyterhub/dbutil.py
index fd67e941..6466bdad 100644
--- a/jupyterhub/dbutil.py
+++ b/jupyterhub/dbutil.py
@@ -91,7 +91,7 @@ def backup_db_file(db_file, log=None):
for i in range(1, 10):
if not os.path.exists(backup_db_file):
break
- backup_db_file = '{}.{}.{}'.format(db_file, timestamp, i)
+ backup_db_file = f'{db_file}.{timestamp}.{i}'
#
if os.path.exists(backup_db_file):
raise OSError("backup db file already exists: %s" % backup_db_file)
diff --git a/jupyterhub/handlers/base.py b/jupyterhub/handlers/base.py
index 72e0096e..822440fa 100644
--- a/jupyterhub/handlers/base.py
+++ b/jupyterhub/handlers/base.py
@@ -622,7 +622,7 @@ class BaseHandler(RequestHandler):
next_url = next_url.replace('\\', '%5C')
if (next_url + '/').startswith(
(
- '%s://%s/' % (self.request.protocol, self.request.host),
+ f'{self.request.protocol}://{self.request.host}/',
'//%s/' % self.request.host,
)
) or (
@@ -748,7 +748,7 @@ class BaseHandler(RequestHandler):
refreshing = user is not None
if user and username != user.name:
- raise ValueError("Username doesn't match! %s != %s" % (username, user.name))
+ raise ValueError(f"Username doesn't match! {username} != {user.name}")
if user is None:
user = self.find_user(username)
@@ -830,14 +830,14 @@ class BaseHandler(RequestHandler):
user_server_name = user.name
if server_name:
- user_server_name = '%s:%s' % (user.name, server_name)
+ user_server_name = f'{user.name}:{server_name}'
if server_name in user.spawners and user.spawners[server_name].pending:
pending = user.spawners[server_name].pending
SERVER_SPAWN_DURATION_SECONDS.labels(
status=ServerSpawnStatus.already_pending
).observe(time.perf_counter() - spawn_start_time)
- raise RuntimeError("%s pending %s" % (user_server_name, pending))
+ raise RuntimeError(f"{user_server_name} pending {pending}")
# count active servers and pending spawns
# we could do careful bookkeeping to avoid
@@ -1114,7 +1114,7 @@ class BaseHandler(RequestHandler):
raise KeyError("User %s has no such spawner %r", user.name, server_name)
spawner = user.spawners[server_name]
if spawner.pending:
- raise RuntimeError("%s pending %s" % (spawner._log_name, spawner.pending))
+ raise RuntimeError(f"{spawner._log_name} pending {spawner.pending}")
# set user._stop_pending before doing anything async
# to avoid races
spawner._stop_pending = True
diff --git a/jupyterhub/handlers/pages.py b/jupyterhub/handlers/pages.py
index fa654a6b..3d96014a 100644
--- a/jupyterhub/handlers/pages.py
+++ b/jupyterhub/handlers/pages.py
@@ -239,7 +239,7 @@ class SpawnHandler(BaseHandler):
raise web.HTTPError(400, "%s is already running" % (spawner._log_name))
elif spawner.pending:
raise web.HTTPError(
- 400, "%s is pending %s" % (spawner._log_name, spawner.pending)
+ 400, f"{spawner._log_name} is pending {spawner.pending}"
)
form_options = {}
@@ -348,9 +348,7 @@ class SpawnPendingHandler(BaseHandler):
raise web.HTTPError(404, "No such user: %s" % for_user)
if server_name and server_name not in user.spawners:
- raise web.HTTPError(
- 404, "%s has no such server %s" % (user.name, server_name)
- )
+ raise web.HTTPError(404, f"{user.name} has no such server {server_name}")
spawner = user.spawners[server_name]
@@ -466,7 +464,7 @@ class AdminHandler(BaseHandler):
admin_access=self.settings.get('admin_access', False),
allow_named_servers=self.allow_named_servers,
named_server_limit_per_user=self.named_server_limit_per_user,
- server_version='{} {}'.format(__version__, self.version_hash),
+ server_version=f'{__version__} {self.version_hash}',
api_page_limit=self.settings["api_page_default_limit"],
)
self.finish(html)
diff --git a/jupyterhub/log.py b/jupyterhub/log.py
index 43a38d36..47534ab7 100644
--- a/jupyterhub/log.py
+++ b/jupyterhub/log.py
@@ -106,12 +106,12 @@ def _scrub_headers(headers):
else:
# no space, hide the whole thing in case there was a mistake
auth_type = ''
- headers['Authorization'] = '{} [secret]'.format(auth_type)
+ headers['Authorization'] = f'{auth_type} [secret]'
if 'Cookie' in headers:
c = SimpleCookie(headers['Cookie'])
redacted = []
for name in c.keys():
- redacted.append("{}=[secret]".format(name))
+ redacted.append(f"{name}=[secret]")
headers['Cookie'] = '; '.join(redacted)
return headers
@@ -185,6 +185,6 @@ def log_request(handler):
# to get headers from tornado
location = handler._headers.get('Location')
if location:
- ns['location'] = ' -> {}'.format(_scrub_uri(location))
+ ns['location'] = f' -> {_scrub_uri(location)}'
log_method(msg.format(**ns))
prometheus_log_method(handler)
diff --git a/jupyterhub/metrics.py b/jupyterhub/metrics.py
index 2f50dfc2..ff58748f 100644
--- a/jupyterhub/metrics.py
+++ b/jupyterhub/metrics.py
@@ -198,6 +198,6 @@ def prometheus_log_method(handler):
"""
REQUEST_DURATION_SECONDS.labels(
method=handler.request.method,
- handler='{}.{}'.format(handler.__class__.__module__, type(handler).__name__),
+ handler=f'{handler.__class__.__module__}.{type(handler).__name__}',
code=handler.get_status(),
).observe(handler.request.request_time())
diff --git a/jupyterhub/objects.py b/jupyterhub/objects.py
index e5aa9c1c..b6857b0b 100644
--- a/jupyterhub/objects.py
+++ b/jupyterhub/objects.py
@@ -148,7 +148,7 @@ class Server(HasTraits):
def host(self):
if self.connect_url:
parsed = urlparse(self.connect_url)
- return "{proto}://{host}".format(proto=parsed.scheme, host=parsed.netloc)
+ return f"{parsed.scheme}://{parsed.netloc}"
if ':' in self._connect_ip:
fmt = "{proto}://[{ip}]:{port}"
@@ -162,7 +162,7 @@ class Server(HasTraits):
def url(self):
if self.connect_url:
return self.connect_url
- return "{host}{uri}".format(host=self.host, uri=self.base_url)
+ return f"{self.host}{self.base_url}"
def __repr__(self):
return "{name}(url={url}, bind_url={bind})".format(
@@ -218,4 +218,4 @@ class Hub(Server):
return url_path_join(self.url, 'api')
def __repr__(self):
- return "<%s %s:%s>" % (self.__class__.__name__, self.ip, self.port)
+ return f"<{self.__class__.__name__} {self.ip}:{self.port}>"
diff --git a/jupyterhub/orm.py b/jupyterhub/orm.py
index aa24c499..903c544c 100644
--- a/jupyterhub/orm.py
+++ b/jupyterhub/orm.py
@@ -145,7 +145,7 @@ class Server(Base):
cookie_name = Column(Unicode(255), default='cookie')
def __repr__(self):
- return "" % (self.ip, self.port)
+ return f""
# lots of things have roles
@@ -192,7 +192,7 @@ class Role(Base):
groups = relationship('Group', secondary='group_role_map', backref='roles')
def __repr__(self):
- return "<%s %s (%s) - scopes: %s>" % (
+ return "<{} {} ({}) - scopes: {}>".format(
self.__class__.__name__,
self.name,
self.description,
@@ -1039,6 +1039,8 @@ def get_class(resource_name):
}
if resource_name not in class_dict:
raise ValueError(
- "Kind must be one of %s, not %s" % (", ".join(class_dict), resource_name)
+ "Kind must be one of {}, not {}".format(
+ ", ".join(class_dict), resource_name
+ )
)
return class_dict[resource_name]
diff --git a/jupyterhub/pagination.py b/jupyterhub/pagination.py
index e7672caa..517d77fa 100644
--- a/jupyterhub/pagination.py
+++ b/jupyterhub/pagination.py
@@ -170,9 +170,7 @@ class Pagination(Configurable):
if self.page > 1:
prev_page = self.page - 1
- links.append(
- '«'.format(prev_page=prev_page)
- )
+ links.append(f'«')
else:
links.append(
'«'
@@ -198,9 +196,7 @@ class Pagination(Configurable):
if self.page >= 1 and self.page < self.total_pages:
next_page = self.page + 1
- links.append(
- '»'.format(next_page=next_page)
- )
+ links.append(f'»')
else:
links.append(
'»'
diff --git a/jupyterhub/proxy.py b/jupyterhub/proxy.py
index b4d147b7..ed119605 100644
--- a/jupyterhub/proxy.py
+++ b/jupyterhub/proxy.py
@@ -509,7 +509,7 @@ class ConfigurableHTTPProxy(Proxy):
if self.app.internal_ssl:
proto = 'https'
- return "{proto}://{url}".format(proto=proto, url=url)
+ return f"{proto}://{url}"
command = Command(
'configurable-http-proxy',
@@ -565,7 +565,7 @@ class ConfigurableHTTPProxy(Proxy):
pid_file = os.path.abspath(self.pid_file)
self.log.warning("Found proxy pid file: %s", pid_file)
try:
- with open(pid_file, "r") as f:
+ with open(pid_file) as f:
pid = int(f.read().strip())
except ValueError:
self.log.warning("%s did not appear to contain a pid", pid_file)
@@ -823,7 +823,7 @@ class ConfigurableHTTPProxy(Proxy):
req = HTTPRequest(
url,
method=method,
- headers={'Authorization': 'token {}'.format(self.auth_token)},
+ headers={'Authorization': f'token {self.auth_token}'},
body=body,
connect_timeout=3, # default: 20s
request_timeout=10, # default: 20s
@@ -845,13 +845,13 @@ class ConfigurableHTTPProxy(Proxy):
)
return False # a falsy return value make exponential_backoff retry
else:
- self.log.error("api_request to proxy failed: {0}".format(e))
+ self.log.error(f"api_request to proxy failed: {e}")
# An unhandled error here will help the hub invoke cleanup logic
raise
result = await exponential_backoff(
_wait_for_api_request,
- 'Repeated api_request to proxy path "{}" failed.'.format(path),
+ f'Repeated api_request to proxy path "{path}" failed.',
timeout=30,
)
return result
diff --git a/jupyterhub/roles.py b/jupyterhub/roles.py
index d2f1d5d1..9a786409 100644
--- a/jupyterhub/roles.py
+++ b/jupyterhub/roles.py
@@ -94,7 +94,7 @@ def expand_self_scope(name):
'read:tokens',
'access:servers',
]
- return {"{}!user={}".format(scope, name) for scope in scope_list}
+ return {f"{scope}!user={name}" for scope in scope_list}
def horizontal_filter(func):
@@ -331,7 +331,7 @@ def existing_only(func):
role = orm.Role.find(db, rolename)
if entity is None:
raise ValueError(
- "%r of kind %r does not exist" % (entity, type(entity).__name__)
+ f"{entity!r} of kind {type(entity).__name__!r} does not exist"
)
elif role is None:
raise ValueError("Role %r does not exist" % rolename)
diff --git a/jupyterhub/scopes.py b/jupyterhub/scopes.py
index 878d7d1e..6884e1b4 100644
--- a/jupyterhub/scopes.py
+++ b/jupyterhub/scopes.py
@@ -434,7 +434,7 @@ def parse_scopes(scope_list):
if parsed_scopes[base_scope] != Scope.ALL:
key, _, value = filter_.partition('=')
if key not in parsed_scopes[base_scope]:
- parsed_scopes[base_scope][key] = set([value])
+ parsed_scopes[base_scope][key] = {value}
else:
parsed_scopes[base_scope][key].add(value)
return parsed_scopes
diff --git a/jupyterhub/services/auth.py b/jupyterhub/services/auth.py
index a918d080..ac3b09a3 100644
--- a/jupyterhub/services/auth.py
+++ b/jupyterhub/services/auth.py
@@ -739,7 +739,7 @@ class HubOAuth(HubAuth):
cookie_suffix = ''.join(
random.choice(string.ascii_letters) for i in range(8)
)
- cookie_name = '{}-{}'.format(self.state_cookie_name, cookie_suffix)
+ cookie_name = f'{self.state_cookie_name}-{cookie_suffix}'
extra_state['cookie_name'] = cookie_name
else:
cookie_name = self.state_cookie_name
diff --git a/jupyterhub/singleuser/mixins.py b/jupyterhub/singleuser/mixins.py
index 0e8ade0c..8785f135 100755
--- a/jupyterhub/singleuser/mixins.py
+++ b/jupyterhub/singleuser/mixins.py
@@ -560,7 +560,7 @@ class SingleUserNotebookAppMixin(Configurable):
url=self.hub_activity_url,
method='POST',
headers={
- "Authorization": "token {}".format(self.hub_auth.api_token),
+ "Authorization": f"token {self.hub_auth.api_token}",
"Content-Type": "application/json",
},
body=json.dumps(
@@ -811,7 +811,7 @@ def _patch_app_base_handlers(app):
BaseHandler = import_item("notebook.base.handlers.IPythonHandler")
else:
raise ValueError(
- "{}.base_handler_class must be defined".format(app.__class__.__name__)
+ f"{app.__class__.__name__}.base_handler_class must be defined"
)
base_handlers.append(BaseHandler)
diff --git a/jupyterhub/spawner.py b/jupyterhub/spawner.py
index a5f415f4..916d24ce 100644
--- a/jupyterhub/spawner.py
+++ b/jupyterhub/spawner.py
@@ -97,7 +97,7 @@ class Spawner(LoggingConfigurable):
Used in logging for consistency with named servers.
"""
if self.name:
- return '%s:%s' % (self.user.name, self.name)
+ return f'{self.user.name}:{self.name}'
else:
return self.user.name
@@ -1258,7 +1258,7 @@ class Spawner(LoggingConfigurable):
try:
r = await exponential_backoff(
_wait_for_death,
- 'Process did not die in {timeout} seconds'.format(timeout=timeout),
+ f'Process did not die in {timeout} seconds',
start_wait=self.death_interval,
timeout=timeout,
)
@@ -1277,7 +1277,7 @@ def _try_setcwd(path):
os.chdir(path)
except OSError as e:
exc = e # break exception instance out of except scope
- print("Couldn't set CWD to %s (%s)" % (path, e), file=sys.stderr)
+ print(f"Couldn't set CWD to {path} ({e})", file=sys.stderr)
path, _ = os.path.split(path)
else:
return
@@ -1423,7 +1423,7 @@ class LocalProcessSpawner(Spawner):
Local processes only need the process id.
"""
- super(LocalProcessSpawner, self).load_state(state)
+ super().load_state(state)
if 'pid' in state:
self.pid = state['pid']
@@ -1432,14 +1432,14 @@ class LocalProcessSpawner(Spawner):
Local processes only need the process id.
"""
- state = super(LocalProcessSpawner, self).get_state()
+ state = super().get_state()
if self.pid:
state['pid'] = self.pid
return state
def clear_state(self):
"""Clear stored state about this spawner (pid)"""
- super(LocalProcessSpawner, self).clear_state()
+ super().clear_state()
self.pid = 0
def user_env(self, env):
@@ -1488,8 +1488,8 @@ class LocalProcessSpawner(Spawner):
home = user.pw_dir
# Create dir for user's certs wherever we're starting
- hub_dir = "{home}/.jupyterhub".format(home=home)
- out_dir = "{hub_dir}/jupyterhub-certs".format(hub_dir=hub_dir)
+ hub_dir = f"{home}/.jupyterhub"
+ out_dir = f"{hub_dir}/jupyterhub-certs"
shutil.rmtree(out_dir, ignore_errors=True)
os.makedirs(out_dir, 0o700, exist_ok=True)
diff --git a/jupyterhub/user.py b/jupyterhub/user.py
index 5f10f54e..80734cf0 100644
--- a/jupyterhub/user.py
+++ b/jupyterhub/user.py
@@ -328,7 +328,7 @@ class User:
# self.escaped_name may contain @ which is legal in URLs but not cookie keys
client_id = 'jupyterhub-user-%s' % quote(self.name)
if server_name:
- client_id = '%s-%s' % (client_id, quote(server_name))
+ client_id = f'{client_id}-{quote(server_name)}'
trusted_alt_names = []
trusted_alt_names.extend(self.settings.get('trusted_alt_names', []))
@@ -452,7 +452,7 @@ class User:
"""Get the *host* for my server (proto://domain[:port])"""
# FIXME: escaped_name probably isn't escaped enough in general for a domain fragment
parsed = urlparse(self.settings['subdomain_host'])
- h = '%s://%s' % (parsed.scheme, self.domain)
+ h = f'{parsed.scheme}://{self.domain}'
if parsed.port:
h += ':%i' % parsed.port
return h
@@ -464,7 +464,7 @@ class User:
Full name.domain/path if using subdomains, otherwise just my /base/url
"""
if self.settings.get('subdomain_host'):
- return '{host}{path}'.format(host=self.host, path=self.base_url)
+ return f'{self.host}{self.base_url}'
else:
return self.base_url
@@ -533,9 +533,7 @@ class User:
else:
# spawn via POST or on behalf of another user.
# nothing we can do here but fail
- raise web.HTTPError(
- 400, "{}'s authentication has expired".format(self.name)
- )
+ raise web.HTTPError(400, f"{self.name}'s authentication has expired")
async def spawn(self, server_name='', options=None, handler=None):
"""Start the user's spawner
diff --git a/jupyterhub/utils.py b/jupyterhub/utils.py
index f78bfdb6..9e2a2e08 100644
--- a/jupyterhub/utils.py
+++ b/jupyterhub/utils.py
@@ -77,7 +77,7 @@ def can_connect(ip, port):
ip = '127.0.0.1'
try:
socket.create_connection((ip, port)).close()
- except socket.error as e:
+ except OSError as e:
if e.errno not in {errno.ECONNREFUSED, errno.ETIMEDOUT}:
app_log.error("Unexpected error connecting to %s:%i %s", ip, port, e)
return False
@@ -225,7 +225,7 @@ async def wait_for_http_server(url, timeout=10, ssl_context=None):
else:
app_log.debug("Server at %s responded with %s", url, e.code)
return e.response
- except (OSError, socket.error) as e:
+ except OSError as e:
if e.errno not in {
errno.ECONNABORTED,
errno.ECONNREFUSED,
@@ -602,7 +602,7 @@ def _parse_accept_header(accept):
media_params.append(('vendor', vnd))
# and re-write media_type to something like application/json so
# it can be used usefully when looking up emitters
- media_type = '{}/{}'.format(typ, extra)
+ media_type = f'{typ}/{extra}'
q = 1.0
for part in parts:
diff --git a/setup.py b/setup.py
index fc169388..2c189fa6 100755
--- a/setup.py
+++ b/setup.py
@@ -1,12 +1,9 @@
#!/usr/bin/env python3
-# coding: utf-8
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
# -----------------------------------------------------------------------------
# Minimal Python version sanity check (from IPython)
# -----------------------------------------------------------------------------
-from __future__ import print_function
-
import os
import shutil
import sys
@@ -239,8 +236,8 @@ class CSS(BaseCommand):
'lessc',
'--',
'--clean-css',
- '--source-map-basepath={}'.format(static),
- '--source-map={}'.format(sourcemap),
+ f'--source-map-basepath={static}',
+ f'--source-map={sourcemap}',
'--source-map-rootpath=../',
style_less,
style_css,