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,