diff --git a/sanic/__main__.py b/sanic/__main__.py index 11320305..92e7a28c 100644 --- a/sanic/__main__.py +++ b/sanic/__main__.py @@ -28,12 +28,12 @@ if __name__ == "__main__": module = import_module(module_name) app = getattr(module, app_name, None) + app_name = type(app).__name__ + if not isinstance(app, Sanic): raise ValueError( - "Module is not a Sanic app, it is a {}. " - "Perhaps you meant {}.app?".format( - type(app).__name__, args.module - ) + f"Module is not a Sanic app, it is a {app_name}. " + f"Perhaps you meant {args.module}.app?" ) if args.cert is not None or args.key is not None: ssl = { @@ -52,9 +52,9 @@ if __name__ == "__main__": ) except ImportError as e: logger.error( - "No module named {} found.\n" - " Example File: project/sanic_server.py -> app\n" - " Example Module: project.sanic_server.app".format(e.name) + f"No module named {e.name} found.\n" + f" Example File: project/sanic_server.py -> app\n" + f" Example Module: project.sanic_server.app" ) except ValueError: logger.exception("Failed to run app") diff --git a/sanic/app.py b/sanic/app.py index c38f4f7c..d17328b6 100644 --- a/sanic/app.py +++ b/sanic/app.py @@ -204,9 +204,11 @@ class Sanic: args = list(signature(handler).parameters.keys()) if not args: + handler_name = handler.__name__ + raise ValueError( - "Required parameter `request` missing " - "in the {0}() route?".format(handler.__name__) + f"Required parameter `request` missing " + f"in the {handler_name}() route?" ) if stream: @@ -800,7 +802,7 @@ class Sanic: uri, route = self.router.find_route_by_view_name(view_name, **kw) if not (uri and route): raise URLBuildError( - "Endpoint with name `{}` was not found".format(view_name) + f"Endpoint with name `{view_name}` was not found" ) # If the route has host defined, split that off @@ -822,7 +824,7 @@ class Sanic: if filename.startswith("/"): filename = filename[1:] - uri = "{}/{}".format(folder_, filename) + uri = f"{folder_}/{filename}" if uri != "/" and uri.endswith("/"): uri = uri[:-1] @@ -858,7 +860,7 @@ class Sanic: for match in matched_params: name, _type, pattern = self.router.parse_parameter_string(match) # we only want to match against each individual parameter - specific_pattern = "^{}$".format(pattern) + specific_pattern = f"^{pattern}$" supplied_param = None if name in kwargs: @@ -866,9 +868,7 @@ class Sanic: del kwargs[name] else: raise URLBuildError( - "Required parameter `{}` was not passed to url_for".format( - name - ) + f"Required parameter `{name}` was not passed to url_for" ) supplied_param = str(supplied_param) @@ -878,23 +878,22 @@ class Sanic: if not passes_pattern: if _type != str: + type_name = _type.__name__ + msg = ( - 'Value "{}" for parameter `{}` does not ' - "match pattern for type `{}`: {}".format( - supplied_param, name, _type.__name__, pattern - ) + f'Value "{supplied_param}" ' + f"for parameter `{name}` does not " + f"match pattern for type `{type_name}`: {pattern}" ) else: msg = ( - 'Value "{}" for parameter `{}` ' - "does not satisfy pattern {}".format( - supplied_param, name, pattern - ) + f'Value "{supplied_param}" for parameter `{name}` ' + f"does not satisfy pattern {pattern}" ) raise URLBuildError(msg) # replace the parameter in the URL with the supplied value - replacement_regex = "(<{}.*?>)".format(name) + replacement_regex = f"(<{name}.*?>)" out = re.sub(replacement_regex, supplied_param, out) @@ -995,9 +994,8 @@ class Sanic: ) elif self.debug: response = HTTPResponse( - "Error while handling error: {}\nStack: {}".format( - e, format_exc() - ), + f"Error while " + f"handling error: {e}\nStack: {format_exc()}", status=500, ) else: @@ -1437,7 +1435,7 @@ class Sanic: proto = "http" if ssl is not None: proto = "https" - logger.info("Goin' Fast @ {}://{}:{}".format(proto, host, port)) + logger.info(f"Goin' Fast @ {proto}://{host}:{port}") return server_settings diff --git a/sanic/blueprints.py b/sanic/blueprints.py index 511e5162..45073078 100644 --- a/sanic/blueprints.py +++ b/sanic/blueprints.py @@ -151,7 +151,7 @@ class Blueprint: future.middleware, route_names, *future.args, - **future.kwargs + **future.kwargs, ) else: app.register_named_middleware(future.middleware, route_names) @@ -376,7 +376,7 @@ class Blueprint: """ name = kwargs.pop("name", "static") if not name.startswith(self.name + "."): - name = "{}.{}".format(self.name, name) + name = f"{self.name}.{name}" kwargs.update(name=name) strict_slashes = kwargs.get("strict_slashes") diff --git a/sanic/config.py b/sanic/config.py index 58de2110..307c7b5f 100644 --- a/sanic/config.py +++ b/sanic/config.py @@ -51,7 +51,7 @@ class Config(dict): try: return self[attr] except KeyError as ke: - raise AttributeError("Config has no '{}'".format(ke.args[0])) + raise AttributeError(f"Config has no '{ke.args[0]}'") def __setattr__(self, attr, value): self[attr] = value diff --git a/sanic/exceptions.py b/sanic/exceptions.py index 6d78c183..6ce93698 100644 --- a/sanic/exceptions.py +++ b/sanic/exceptions.py @@ -171,7 +171,7 @@ class Unauthorized(SanicException): challenge = ", ".join(values) self.headers = { - "WWW-Authenticate": "{} {}".format(scheme, challenge).rstrip() + "WWW-Authenticate": f"{scheme} {challenge}".rstrip() } diff --git a/sanic/reloader_helpers.py b/sanic/reloader_helpers.py index b58391f6..1fefc6f4 100644 --- a/sanic/reloader_helpers.py +++ b/sanic/reloader_helpers.py @@ -72,7 +72,7 @@ def kill_process_children_unix(pid): :param pid: PID of parent process (process ID) :return: Nothing """ - root_process_path = "/proc/{pid}/task/{pid}/children".format(pid=pid) + root_process_path = f"/proc/{pid}/task/{pid}/children" if not os.path.isfile(root_process_path): return with open(root_process_path) as children_list_file: diff --git a/sanic/request.py b/sanic/request.py index 53706eab..6e1a3061 100644 --- a/sanic/request.py +++ b/sanic/request.py @@ -130,9 +130,8 @@ class Request: self.endpoint = None def __repr__(self): - return "<{0}: {1} {2}>".format( - self.__class__.__name__, self.method, self.path - ) + class_name = self.__class__.__name__ + return f"<{class_name}: {self.method} {self.path}>" def body_init(self): """.. deprecated:: 20.3""" @@ -527,7 +526,7 @@ class Request: ): netloc = host else: - netloc = "{}:{}".format(host, port) + netloc = f"{host}:{port}" return self.app.url_for( view_name, _external=True, _scheme=scheme, _server=netloc, **kwargs diff --git a/sanic/response.py b/sanic/response.py index 2d268464..37d58304 100644 --- a/sanic/response.py +++ b/sanic/response.py @@ -299,7 +299,7 @@ async def file( out_stream = await f.read(_range.size) headers[ "Content-Range" - ] = "bytes {0.start}-{0.end}/{0.total}".format(_range) + ] = f"bytes {_range.start}-{_range.end}/{_range.total}" status = 206 else: out_stream = await f.read() @@ -341,9 +341,11 @@ async def file_stream( filename = filename or path.split(location)[-1] mime_type = mime_type or guess_type(filename)[0] or "text/plain" if _range: - headers["Content-Range"] = "bytes {0.start}-{0.end}/{0.total}".format( - _range - ) + start = _range.start + end = _range.end + total = _range.total + + headers["Content-Range"] = f"bytes {start}-{end}/{total}" status = 206 async def _streaming_fn(response): diff --git a/sanic/router.py b/sanic/router.py index 013f88d7..ab6e3cef 100644 --- a/sanic/router.py +++ b/sanic/router.py @@ -109,7 +109,7 @@ class Router: name, pattern = parameter_string.split(":", 1) if not name: raise ValueError( - "Invalid parameter syntax: {}".format(parameter_string) + f"Invalid parameter syntax: {parameter_string}" ) default = (str, pattern) @@ -143,7 +143,7 @@ class Router: routes = [] if version is not None: version = re.escape(str(version).strip("/").lstrip("v")) - uri = "/".join(["/v{}".format(version), uri.lstrip("/")]) + uri = "/".join([f"/v{version}", uri.lstrip("/")]) # add regular version routes.append(self._add(uri, methods, handler, host, name)) @@ -203,8 +203,8 @@ class Router: else: if not isinstance(host, Iterable): raise ValueError( - "Expected either string or Iterable of " - "host strings, not {!r}".format(host) + f"Expected either string or Iterable of " + f"host strings, not {host!r}" ) for host_ in host: @@ -225,8 +225,7 @@ class Router: if name in parameter_names: raise ParameterNameConflicts( - "Multiple parameter named <{name}> " - "in route uri {uri}".format(name=name, uri=uri) + f"Multiple parameter named <{name}> " f"in route uri {uri}" ) parameter_names.add(name) @@ -240,23 +239,23 @@ class Router: elif re.search(r"/", pattern): properties["unhashable"] = True - return "({})".format(pattern) + return f"({pattern})" pattern_string = re.sub(self.parameter_pattern, add_parameter, uri) - pattern = re.compile(r"^{}$".format(pattern_string)) + pattern = re.compile(fr"^{pattern_string}$") def merge_route(route, methods, handler): # merge to the existing route when possible. if not route.methods or not methods: # method-unspecified routes are not mergeable. - raise RouteExists("Route already registered: {}".format(uri)) + raise RouteExists(f"Route already registered: {uri}") elif route.methods.intersection(methods): # already existing method is not overloadable. duplicated = methods.intersection(route.methods) + duplicated_methods = ",".join(list(duplicated)) + raise RouteExists( - "Route already registered: {} [{}]".format( - uri, ",".join(list(duplicated)) - ) + f"Route already registered: {uri} [{duplicated_methods}]" ) if isinstance(route.handler, CompositionView): view = route.handler @@ -296,9 +295,9 @@ class Router: name = name.split("_static_", 1)[-1] if hasattr(handler, "__blueprintname__"): - handler_name = "{}.{}".format( - handler.__blueprintname__, name or handler.__name__ - ) + bp_name = handler.__blueprintname__ + + handler_name = f"{bp_name}.{name or handler.__name__}" else: handler_name = name or getattr(handler, "__name__", None) @@ -411,7 +410,7 @@ class Router: # Check against known static routes route = self.routes_static.get(url) method_not_supported = MethodNotSupported( - "Method {} not allowed for URL {}".format(method, url), + f"Method {method} not allowed for URL {url}", method=method, allowed_methods=self.get_supported_methods(url), ) @@ -441,7 +440,7 @@ class Router: # Route was found but the methods didn't match if route_found: raise method_not_supported - raise NotFound("Requested URL {} not found".format(url)) + raise NotFound(f"Requested URL {url} not found") kwargs = { p.name: p.cast(value) diff --git a/sanic/server.py b/sanic/server.py index 003ddc4d..5128b30a 100644 --- a/sanic/server.py +++ b/sanic/server.py @@ -114,7 +114,7 @@ class HttpProtocol(asyncio.Protocol): router=None, state=None, debug=False, - **kwargs + **kwargs, ): self.loop = loop self.app = app @@ -349,9 +349,7 @@ class HttpProtocol(asyncio.Protocol): self.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n") else: self.write_error( - HeaderExpectationFailed( - "Unknown Expect: {expect}".format(expect=expect) - ) + HeaderExpectationFailed(f"Unknown Expect: {expect}") ) def on_body(self, body): @@ -458,13 +456,9 @@ class HttpProtocol(asyncio.Protocol): extra["host"] = "UNKNOWN" if self.request is not None: if self.request.ip: - extra["host"] = "{0}:{1}".format( - self.request.ip, self.request.port - ) + extra["host"] = f"{self.request.ip}:{self.request.port}" - extra["request"] = "{0} {1}".format( - self.request.method, self.request.url - ) + extra["request"] = f"{self.request.method} {self.request.url}" else: extra["request"] = "nil" @@ -501,9 +495,7 @@ class HttpProtocol(asyncio.Protocol): ) keep_alive = False except Exception as e: - self.bail_out( - "Writing response failed, connection closed {}".format(repr(e)) - ) + self.bail_out(f"Writing response failed, connection closed {e!r}") finally: if not keep_alive: self.transport.close() @@ -554,9 +546,7 @@ class HttpProtocol(asyncio.Protocol): ) keep_alive = False except Exception as e: - self.bail_out( - "Writing response failed, connection closed {}".format(repr(e)) - ) + self.bail_out(f"Writing response failed, connection closed {e!r}") finally: if not keep_alive: self.transport.close() @@ -587,7 +577,7 @@ class HttpProtocol(asyncio.Protocol): ) except Exception as e: self.bail_out( - "Writing error failed, connection closed {}".format(repr(e)), + f"Writing error failed, connection closed {e!r}", from_error=True, ) finally: @@ -902,7 +892,7 @@ def serve( reuse_port=reuse_port, sock=sock, backlog=backlog, - **asyncio_server_kwargs + **asyncio_server_kwargs, ) if run_async: diff --git a/sanic/static.py b/sanic/static.py index fc50c76b..bb37e561 100644 --- a/sanic/static.py +++ b/sanic/static.py @@ -134,7 +134,7 @@ def register( # special prefix for static files if not name.startswith("_static_"): - name = "_static_{}".format(name) + name = f"_static_{name}" app.route( uri, diff --git a/sanic/testing.py b/sanic/testing.py index 41985041..7fe08905 100644 --- a/sanic/testing.py +++ b/sanic/testing.py @@ -110,11 +110,9 @@ class SanicTestClient: ): url = uri else: - uri = uri if uri.startswith("/") else "/{uri}".format(uri=uri) + uri = uri if uri.startswith("/") else f"/{uri}" scheme = "ws" if method == "websocket" else "http" - url = "{scheme}://{host}:{port}{uri}".format( - scheme=scheme, host=host, port=port, uri=uri - ) + url = f"{scheme}://{host}:{port}{uri}" # Tests construct URLs using PORT = None, which means random port not # known until this function is called, so fix that here url = url.replace(":None/", f":{port}/") @@ -135,7 +133,7 @@ class SanicTestClient: self.app.listeners["after_server_start"].pop() if exceptions: - raise ValueError("Exception during request: {}".format(exceptions)) + raise ValueError(f"Exception during request: {exceptions}") if gather_request: try: @@ -143,17 +141,13 @@ class SanicTestClient: return request, response except BaseException: # noqa raise ValueError( - "Request and response object expected, got ({})".format( - results - ) + f"Request and response object expected, got ({results})" ) else: try: return results[-1] except BaseException: # noqa - raise ValueError( - "Request object expected, got ({})".format(results) - ) + raise ValueError(f"Request object expected, got ({results})") def get(self, *args, **kwargs): return self._sanic_endpoint_test("get", *args, **kwargs) @@ -199,7 +193,7 @@ class SanicASGITestClient(httpx.AsyncClient): def __init__( self, app, - base_url: str = "http://{}".format(ASGI_HOST), + base_url: str = f"http://{ASGI_HOST}", suppress_exceptions: bool = False, ) -> None: app.__class__.__call__ = app_call_with_return @@ -230,7 +224,7 @@ class SanicASGITestClient(httpx.AsyncClient): async def websocket(self, uri, subprotocols=None, *args, **kwargs): scheme = "ws" path = uri - root_path = "{}://{}".format(scheme, ASGI_HOST) + root_path = f"{scheme}://{ASGI_HOST}" headers = kwargs.get("headers", {}) headers.setdefault("connection", "upgrade") diff --git a/sanic/views.py b/sanic/views.py index c4574b8d..30d0abcb 100644 --- a/sanic/views.py +++ b/sanic/views.py @@ -96,14 +96,10 @@ class CompositionView: handler.is_stream = stream for method in methods: if method not in HTTP_METHODS: - raise InvalidUsage( - "{} is not a valid HTTP method.".format(method) - ) + raise InvalidUsage(f"{method} is not a valid HTTP method.") if method in self.handlers: - raise InvalidUsage( - "Method {} is already registered.".format(method) - ) + raise InvalidUsage(f"Method {method} is already registered.") self.handlers[method] = handler def __call__(self, request, *args, **kwargs):