mirror of https://github.com/encode/starlette.git
parent
8545b022f9
commit
0c3a1e4a60
|
@ -28,7 +28,7 @@ def requires(
|
|||
if parameter.name == "request":
|
||||
break
|
||||
else:
|
||||
raise Exception('No "request" argument on function "%s"' % func)
|
||||
raise Exception(f'No "request" argument on function "{func}"')
|
||||
|
||||
if asyncio.iscoroutinefunction(func):
|
||||
|
||||
|
|
|
@ -23,16 +23,14 @@ class Environ(MutableMapping):
|
|||
def __setitem__(self, key: typing.Any, value: typing.Any) -> None:
|
||||
if key in self._has_been_read:
|
||||
raise EnvironError(
|
||||
"Attempting to set environ['%s'], but the value has already be read."
|
||||
% key
|
||||
f"Attempting to set environ['{key}'], but the value has already be read."
|
||||
)
|
||||
self._environ.__setitem__(key, value)
|
||||
|
||||
def __delitem__(self, key: typing.Any) -> None:
|
||||
if key in self._has_been_read:
|
||||
raise EnvironError(
|
||||
"Attempting to delete environ['%s'], but the value has already be read."
|
||||
% key
|
||||
f"Attempting to delete environ['{key}'], but the value has already be read."
|
||||
)
|
||||
self._environ.__delitem__(key)
|
||||
|
||||
|
@ -71,7 +69,7 @@ class Config:
|
|||
return self._perform_cast(key, value, cast)
|
||||
if default is not undefined:
|
||||
return self._perform_cast(key, default, cast)
|
||||
raise KeyError("Config '%s' is missing, and has no default." % key)
|
||||
raise KeyError(f"Config '{key}' is missing, and has no default.")
|
||||
|
||||
def _read_file(self, file_name: str) -> typing.Dict[str, str]:
|
||||
file_values = {} # type: typing.Dict[str, str]
|
||||
|
@ -95,13 +93,12 @@ class Config:
|
|||
value = value.lower()
|
||||
if value not in mapping:
|
||||
raise ValueError(
|
||||
"Config '%s' has value '%s'. Not a valid bool." % (key, value)
|
||||
f"Config '{key}' has value '{value}'. Not a valid bool."
|
||||
)
|
||||
return mapping[value]
|
||||
try:
|
||||
return cast(value)
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError(
|
||||
"Config '%s' has value '%s'. Not a valid %s."
|
||||
% (key, value, cast.__name__)
|
||||
f"Config '{key}' has value '{value}'. Not a valid {cast.__name__}."
|
||||
)
|
||||
|
|
|
@ -28,16 +28,16 @@ class URL:
|
|||
break
|
||||
|
||||
if host_header is not None:
|
||||
url = "%s://%s%s" % (scheme, host_header, path)
|
||||
url = f"{scheme}://{host_header}{path}"
|
||||
elif server is None:
|
||||
url = path
|
||||
else:
|
||||
host, port = server
|
||||
default_port = {"http": 80, "https": 443, "ws": 80, "wss": 443}[scheme]
|
||||
if port == default_port:
|
||||
url = "%s://%s%s" % (scheme, host, path)
|
||||
url = f"{scheme}://{host}{path}"
|
||||
else:
|
||||
url = "%s://%s:%s%s" % (scheme, host, port, path)
|
||||
url = f"{scheme}://{host}:{port}{path}"
|
||||
|
||||
if query_string:
|
||||
url += "?" + query_string.decode()
|
||||
|
@ -111,12 +111,12 @@ class URL:
|
|||
|
||||
netloc = hostname
|
||||
if port is not None:
|
||||
netloc += ":%d" % port
|
||||
netloc += f":{port}"
|
||||
if username is not None:
|
||||
userpass = username
|
||||
if password is not None:
|
||||
userpass += ":%s" % password
|
||||
netloc = "%s@%s" % (userpass, netloc)
|
||||
userpass += f":{password}"
|
||||
netloc = f"{userpass}@{netloc}"
|
||||
|
||||
kwargs["netloc"] = netloc
|
||||
|
||||
|
@ -133,7 +133,7 @@ class URL:
|
|||
url = str(self)
|
||||
if self.password:
|
||||
url = str(self.replace(password="********"))
|
||||
return "%s(%s)" % (self.__class__.__name__, repr(url))
|
||||
return f"{self.__class__.__name__}({repr(url)})"
|
||||
|
||||
|
||||
class DatabaseURL(URL):
|
||||
|
@ -191,7 +191,7 @@ class Secret:
|
|||
self._value = value
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "%s('**********')" % self.__class__.__name__
|
||||
return f"{self.__class__.__name__}('**********')"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self._value
|
||||
|
@ -218,7 +218,7 @@ class CommaSeparatedStrings(Sequence):
|
|||
|
||||
def __repr__(self) -> str:
|
||||
list_repr = repr([item for item in self])
|
||||
return "%s(%s)" % (self.__class__.__name__, list_repr)
|
||||
return f"{self.__class__.__name__}({list_repr})"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return ", ".join([repr(item) for item in self])
|
||||
|
@ -294,7 +294,7 @@ class QueryParams(typing.Mapping[str, str]):
|
|||
return urlencode(self._list)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "%s(query_string=%s)" % (self.__class__.__name__, repr(str(self)))
|
||||
return f"{self.__class__.__name__}(query_string={repr(str(self))})"
|
||||
|
||||
|
||||
class Headers(typing.Mapping[str, str]):
|
||||
|
@ -383,8 +383,8 @@ class Headers(typing.Mapping[str, str]):
|
|||
def __repr__(self) -> str:
|
||||
as_dict = dict(self.items())
|
||||
if len(as_dict) == len(self):
|
||||
return "%s(%s)" % (self.__class__.__name__, repr(as_dict))
|
||||
return "%s(raw=%s)" % (self.__class__.__name__, repr(self.raw))
|
||||
return f"{self.__class__.__name__}({repr(as_dict)})"
|
||||
return f"{self.__class__.__name__}(raw={repr(self.raw)})"
|
||||
|
||||
|
||||
class MutableHeaders(Headers):
|
||||
|
|
|
@ -16,7 +16,7 @@ def build_environ(scope: Scope, body: bytes) -> dict:
|
|||
"SCRIPT_NAME": "",
|
||||
"PATH_INFO": scope["path"],
|
||||
"QUERY_STRING": scope["query_string"].decode("ascii"),
|
||||
"SERVER_PROTOCOL": "HTTP/%s" % scope["http_version"],
|
||||
"SERVER_PROTOCOL": f"HTTP/{scope['http_version']}",
|
||||
"wsgi.version": (1, 0),
|
||||
"wsgi.url_scheme": scope.get("scheme", "http"),
|
||||
"wsgi.input": io.BytesIO(body),
|
||||
|
@ -43,7 +43,7 @@ def build_environ(scope: Scope, body: bytes) -> dict:
|
|||
elif name == "content-type":
|
||||
corrected_name = "CONTENT_TYPE"
|
||||
else:
|
||||
corrected_name = "HTTP_%s" % name.upper().replace("-", "_")
|
||||
corrected_name = f"HTTP_{name}".upper().replace("-", "_")
|
||||
# HTTPbis say only ASCII chars are allowed in headers, but we latin1 just in case
|
||||
value = value.decode("latin1")
|
||||
if corrected_name in environ:
|
||||
|
|
|
@ -103,13 +103,13 @@ def compile_path(
|
|||
for match in PARAM_REGEX.finditer(path):
|
||||
param_name, convertor_type = match.groups("str")
|
||||
convertor_type = convertor_type.lstrip(":")
|
||||
assert convertor_type in CONVERTOR_TYPES, (
|
||||
"Unknown path convertor '%s'" % convertor_type
|
||||
)
|
||||
assert (
|
||||
convertor_type in CONVERTOR_TYPES
|
||||
), f"Unknown path convertor '{convertor_type}'"
|
||||
convertor = CONVERTOR_TYPES[convertor_type]
|
||||
|
||||
path_regex += path[idx : match.start()]
|
||||
path_regex += "(?P<%s>%s)" % (param_name, convertor.regex)
|
||||
path_regex += f"(?P<{param_name}>{convertor.regex})"
|
||||
|
||||
path_format += path[idx : match.start()]
|
||||
path_format += "{%s}" % param_name
|
||||
|
@ -146,7 +146,7 @@ class Route(BaseRoute):
|
|||
*,
|
||||
methods: typing.List[str] = None,
|
||||
name: str = None,
|
||||
include_in_schema: bool = True
|
||||
include_in_schema: bool = True,
|
||||
) -> None:
|
||||
assert path.startswith("/"), "Routed paths must start with '/'"
|
||||
self.path = path
|
||||
|
|
|
@ -22,7 +22,7 @@ NOT_MODIFIED_HEADERS = (
|
|||
class StaticFiles:
|
||||
def __init__(self, *, directory: str, check_dir: bool = True) -> None:
|
||||
if check_dir and not os.path.isdir(directory):
|
||||
raise RuntimeError("Directory '%s' does not exist" % directory)
|
||||
raise RuntimeError(f"Directory '{directory}' does not exist")
|
||||
self.directory = directory
|
||||
self.config_checked = False
|
||||
|
||||
|
@ -58,9 +58,9 @@ class _StaticFilesResponder:
|
|||
try:
|
||||
stat_result = await aio_stat(directory)
|
||||
except FileNotFoundError:
|
||||
raise RuntimeError("StaticFiles directory '%s' does not exist." % directory)
|
||||
raise RuntimeError(f"StaticFiles directory '{directory}' does not exist.")
|
||||
if not (stat.S_ISDIR(stat_result.st_mode) or stat.S_ISLNK(stat_result.st_mode)):
|
||||
raise RuntimeError("StaticFiles path '%s' is not a directory." % directory)
|
||||
raise RuntimeError(f"StaticFiles path '{directory}' is not a directory.")
|
||||
|
||||
def is_not_modified(self, stat_headers: typing.Dict[str, str]) -> bool:
|
||||
etag = stat_headers["etag"]
|
||||
|
|
|
@ -86,7 +86,7 @@ class _ASGIAdapter(requests.adapters.HTTPAdapter):
|
|||
elif port == default_port:
|
||||
headers = [(b"host", host.encode())]
|
||||
else:
|
||||
headers = [(b"host", ("%s:%d" % (host, port)).encode())]
|
||||
headers = [(b"host", (f"{host}:{port}").encode())]
|
||||
|
||||
# Include other request headers.
|
||||
headers += [
|
||||
|
|
|
@ -70,7 +70,7 @@ def all_users_page(request):
|
|||
@users.route("/{username}")
|
||||
def user_page(request):
|
||||
username = request.path_params["username"]
|
||||
return PlainTextResponse("Hello, %s!" % username)
|
||||
return PlainTextResponse(f"Hello, {username}!")
|
||||
|
||||
|
||||
app.mount("/users", users)
|
||||
|
|
|
@ -255,7 +255,7 @@ def test_template_response():
|
|||
self.name = name
|
||||
|
||||
def render(self, context):
|
||||
return "username: %s" % context["username"]
|
||||
return f"username: {context['username']}"
|
||||
|
||||
async def asgi(receive, send):
|
||||
template = Template("index.html")
|
||||
|
|
|
@ -90,7 +90,7 @@ async def websocket_endpoint(session):
|
|||
@app.websocket_route("/ws/{room}")
|
||||
async def websocket_params(session):
|
||||
await session.accept()
|
||||
await session.send_text("Hello, %s!" % session.path_params["room"])
|
||||
await session.send_text(f"Hello, {session.path_params['room']}!")
|
||||
await session.close()
|
||||
|
||||
|
||||
|
@ -208,7 +208,7 @@ def test_router_add_websocket_route():
|
|||
|
||||
def http_endpoint(request):
|
||||
url = request.url_for("http_endpoint")
|
||||
return Response("URL: %s" % url, media_type="text/plain")
|
||||
return Response(f"URL: {url}", media_type="text/plain")
|
||||
|
||||
|
||||
class WebsocketEndpoint:
|
||||
|
|
Loading…
Reference in New Issue