[mypy]
disallow_untyped_defs = True
ignore_missing_imports = True
+no_implicit_optional = True
show_error_codes = True
+[mypy-starlette.testclient]
+no_implicit_optional = False
+
[mypy-tests.*]
disallow_untyped_defs = False
check_untyped_defs = True
def __init__(
self,
debug: bool = False,
- routes: typing.Sequence[BaseRoute] = None,
- middleware: typing.Sequence[Middleware] = None,
- exception_handlers: typing.Mapping[
- typing.Any,
- typing.Callable[
- [Request, Exception], typing.Union[Response, typing.Awaitable[Response]]
- ],
+ routes: typing.Optional[typing.Sequence[BaseRoute]] = None,
+ middleware: typing.Optional[typing.Sequence[Middleware]] = None,
+ exception_handlers: typing.Optional[
+ typing.Mapping[
+ typing.Any,
+ typing.Callable[
+ [Request, Exception],
+ typing.Union[Response, typing.Awaitable[Response]],
+ ],
+ ]
+ ] = None,
+ on_startup: typing.Optional[typing.Sequence[typing.Callable]] = None,
+ on_shutdown: typing.Optional[typing.Sequence[typing.Callable]] = None,
+ lifespan: typing.Optional[
+ typing.Callable[["Starlette"], typing.AsyncContextManager]
] = None,
- on_startup: typing.Sequence[typing.Callable] = None,
- on_shutdown: typing.Sequence[typing.Callable] = None,
- lifespan: typing.Callable[["Starlette"], typing.AsyncContextManager] = None,
) -> None:
# The lifespan context function is a newer style that replaces
# on_startup / on_shutdown handlers. Use one or the other, not both.
return self.router.on_event(event_type)
def mount(
- self, path: str, app: ASGIApp, name: str = None
+ self, path: str, app: ASGIApp, name: typing.Optional[str] = None
) -> None: # pragma: nocover
"""
We no longer document this API, and its usage is discouraged.
self.router.mount(path, app=app, name=name)
def host(
- self, host: str, app: ASGIApp, name: str = None
+ self, host: str, app: ASGIApp, name: typing.Optional[str] = None
) -> None: # pragma: no cover
"""
We no longer document this API, and its usage is discouraged.
self,
path: str,
route: typing.Callable,
- methods: typing.List[str] = None,
- name: str = None,
+ methods: typing.Optional[typing.List[str]] = None,
+ name: typing.Optional[str] = None,
include_in_schema: bool = True,
) -> None: # pragma: no cover
self.router.add_route(
)
def add_websocket_route(
- self, path: str, route: typing.Callable, name: str = None
+ self, path: str, route: typing.Callable, name: typing.Optional[str] = None
) -> None: # pragma: no cover
self.router.add_websocket_route(path, route, name=name)
def route(
self,
path: str,
- methods: typing.List[str] = None,
- name: str = None,
+ methods: typing.Optional[typing.List[str]] = None,
+ name: typing.Optional[str] = None,
include_in_schema: bool = True,
) -> typing.Callable: # pragma: nocover
"""
return decorator
def websocket_route(
- self, path: str, name: str = None
+ self, path: str, name: typing.Optional[str] = None
) -> typing.Callable: # pragma: nocover
"""
We no longer document this decorator style API, and its usage is discouraged.
def requires(
scopes: typing.Union[str, typing.Sequence[str]],
status_code: int = 403,
- redirect: str = None,
+ redirect: typing.Optional[str] = None,
) -> typing.Callable:
scopes_list = [scopes] if isinstance(scopes, str) else list(scopes)
class AuthCredentials:
- def __init__(self, scopes: typing.Sequence[str] = None):
+ def __init__(self, scopes: typing.Optional[typing.Sequence[str]] = None):
self.scopes = [] if scopes is None else list(scopes)
class BackgroundTasks(BackgroundTask):
- def __init__(self, tasks: typing.Sequence[BackgroundTask] = None):
+ def __init__(self, tasks: typing.Optional[typing.Sequence[BackgroundTask]] = None):
self.tasks = list(tasks) if tasks else []
def add_task(
class Config:
def __init__(
self,
- env_file: typing.Union[str, Path] = None,
+ env_file: typing.Optional[typing.Union[str, Path]] = None,
environ: typing.Mapping[str, str] = environ,
) -> None:
self.environ = environ
...
def __call__(
- self, key: str, cast: typing.Callable = None, default: typing.Any = undefined
+ self,
+ key: str,
+ cast: typing.Optional[typing.Callable] = None,
+ default: typing.Any = undefined,
) -> typing.Any:
return self.get(key, cast, default)
def get(
- self, key: str, cast: typing.Callable = None, default: typing.Any = undefined
+ self,
+ key: str,
+ cast: typing.Optional[typing.Callable] = None,
+ default: typing.Any = undefined,
) -> typing.Any:
if key in self.environ:
value = self.environ[key]
return file_values
def _perform_cast(
- self, key: str, value: typing.Any, cast: typing.Callable = None
+ self, key: str, value: typing.Any, cast: typing.Optional[typing.Callable] = None
) -> typing.Any:
if cast is None or value is None:
return value
class HTTPException(Exception):
def __init__(
- self, status_code: int, detail: str = None, headers: dict = None
+ self,
+ status_code: int,
+ detail: typing.Optional[str] = None,
+ headers: typing.Optional[dict] = None,
) -> None:
if detail is None:
detail = http.HTTPStatus(status_code).phrase
def __init__(
self,
app: ASGIApp,
- handlers: typing.Mapping[
- typing.Any, typing.Callable[[Request, Exception], Response]
+ handlers: typing.Optional[
+ typing.Mapping[typing.Any, typing.Callable[[Request, Exception], Response]]
] = None,
debug: bool = False,
) -> None:
self,
app: ASGIApp,
backend: AuthenticationBackend,
- on_error: typing.Callable[
- [HTTPConnection, AuthenticationError], Response
+ on_error: typing.Optional[
+ typing.Callable[[HTTPConnection, AuthenticationError], Response]
] = None,
) -> None:
self.app = app
class BaseHTTPMiddleware:
- def __init__(self, app: ASGIApp, dispatch: DispatchFunction = None) -> None:
+ def __init__(
+ self, app: ASGIApp, dispatch: typing.Optional[DispatchFunction] = None
+ ) -> None:
self.app = app
self.dispatch_func = self.dispatch if dispatch is None else dispatch
allow_methods: typing.Sequence[str] = ("GET",),
allow_headers: typing.Sequence[str] = (),
allow_credentials: bool = False,
- allow_origin_regex: str = None,
+ allow_origin_regex: typing.Optional[str] = None,
expose_headers: typing.Sequence[str] = (),
max_age: int = 600,
) -> None:
"""
def __init__(
- self, app: ASGIApp, handler: typing.Callable = None, debug: bool = False
+ self,
+ app: ASGIApp,
+ handler: typing.Optional[typing.Callable] = None,
+ debug: bool = False,
) -> None:
self.app = app
self.handler = handler
def __init__(
self,
app: ASGIApp,
- allowed_hosts: typing.Sequence[str] = None,
+ allowed_hosts: typing.Optional[typing.Sequence[str]] = None,
www_redirect: bool = True,
) -> None:
if allowed_hosts is None:
any functionality that is common to both `Request` and `WebSocket`.
"""
- def __init__(self, scope: Scope, receive: Receive = None) -> None:
+ def __init__(self, scope: Scope, receive: typing.Optional[Receive] = None) -> None:
assert scope["type"] in ("http", "websocket")
self.scope = scope
self,
content: typing.Any = None,
status_code: int = 200,
- headers: typing.Mapping[str, str] = None,
- media_type: str = None,
- background: BackgroundTask = None,
+ headers: typing.Optional[typing.Mapping[str, str]] = None,
+ media_type: typing.Optional[str] = None,
+ background: typing.Optional[BackgroundTask] = None,
) -> None:
self.status_code = status_code
if media_type is not None:
return content
return content.encode(self.charset)
- def init_headers(self, headers: typing.Mapping[str, str] = None) -> None:
+ def init_headers(
+ self, headers: typing.Optional[typing.Mapping[str, str]] = None
+ ) -> None:
if headers is None:
raw_headers: typing.List[typing.Tuple[bytes, bytes]] = []
populate_content_length = True
self,
key: str,
value: str = "",
- max_age: int = None,
- expires: int = None,
+ max_age: typing.Optional[int] = None,
+ expires: typing.Optional[int] = None,
path: str = "/",
- domain: str = None,
+ domain: typing.Optional[str] = None,
secure: bool = False,
httponly: bool = False,
samesite: str = "lax",
self,
key: str,
path: str = "/",
- domain: str = None,
+ domain: typing.Optional[str] = None,
secure: bool = False,
httponly: bool = False,
samesite: str = "lax",
self,
content: typing.Any,
status_code: int = 200,
- headers: dict = None,
- media_type: str = None,
- background: BackgroundTask = None,
+ headers: typing.Optional[dict] = None,
+ media_type: typing.Optional[str] = None,
+ background: typing.Optional[BackgroundTask] = None,
) -> None:
super().__init__(content, status_code, headers, media_type, background)
self,
url: typing.Union[str, URL],
status_code: int = 307,
- headers: typing.Mapping[str, str] = None,
- background: BackgroundTask = None,
+ headers: typing.Optional[typing.Mapping[str, str]] = None,
+ background: typing.Optional[BackgroundTask] = None,
) -> None:
super().__init__(
content=b"", status_code=status_code, headers=headers, background=background
self,
content: typing.Any,
status_code: int = 200,
- headers: typing.Mapping[str, str] = None,
- media_type: str = None,
- background: BackgroundTask = None,
+ headers: typing.Optional[typing.Mapping[str, str]] = None,
+ media_type: typing.Optional[str] = None,
+ background: typing.Optional[BackgroundTask] = None,
) -> None:
if isinstance(content, typing.AsyncIterable):
self.body_iterator = content
self,
path: typing.Union[str, "os.PathLike[str]"],
status_code: int = 200,
- headers: typing.Mapping[str, str] = None,
- media_type: str = None,
- background: BackgroundTask = None,
- filename: str = None,
- stat_result: os.stat_result = None,
- method: str = None,
+ headers: typing.Optional[typing.Mapping[str, str]] = None,
+ media_type: typing.Optional[str] = None,
+ background: typing.Optional[BackgroundTask] = None,
+ filename: typing.Optional[str] = None,
+ stat_result: typing.Optional[os.stat_result] = None,
+ method: typing.Optional[str] = None,
content_disposition_type: str = "attachment",
) -> None:
self.path = path
path: str,
endpoint: typing.Callable,
*,
- methods: typing.List[str] = None,
- name: str = None,
+ methods: typing.Optional[typing.List[str]] = None,
+ name: typing.Optional[str] = None,
include_in_schema: bool = True,
) -> None:
assert path.startswith("/"), "Routed paths must start with '/'"
class WebSocketRoute(BaseRoute):
def __init__(
- self, path: str, endpoint: typing.Callable, *, name: str = None
+ self, path: str, endpoint: typing.Callable, *, name: typing.Optional[str] = None
) -> None:
assert path.startswith("/"), "Routed paths must start with '/'"
self.path = path
def __init__(
self,
path: str,
- app: ASGIApp = None,
- routes: typing.Sequence[BaseRoute] = None,
- name: str = None,
+ app: typing.Optional[ASGIApp] = None,
+ routes: typing.Optional[typing.Sequence[BaseRoute]] = None,
+ name: typing.Optional[str] = None,
) -> None:
assert path == "" or path.startswith("/"), "Routed paths must start with '/'"
assert (
class Host(BaseRoute):
- def __init__(self, host: str, app: ASGIApp, name: str = None) -> None:
+ def __init__(
+ self, host: str, app: ASGIApp, name: typing.Optional[str] = None
+ ) -> None:
self.host = host
self.app = app
self.name = name
class Router:
def __init__(
self,
- routes: typing.Sequence[BaseRoute] = None,
+ routes: typing.Optional[typing.Sequence[BaseRoute]] = None,
redirect_slashes: bool = True,
- default: ASGIApp = None,
- on_startup: typing.Sequence[typing.Callable] = None,
- on_shutdown: typing.Sequence[typing.Callable] = None,
- lifespan: typing.Callable[[typing.Any], typing.AsyncContextManager] = None,
+ default: typing.Optional[ASGIApp] = None,
+ on_startup: typing.Optional[typing.Sequence[typing.Callable]] = None,
+ on_shutdown: typing.Optional[typing.Sequence[typing.Callable]] = None,
+ lifespan: typing.Optional[
+ typing.Callable[[typing.Any], typing.AsyncContextManager]
+ ] = None,
) -> None:
self.routes = [] if routes is None else list(routes)
self.redirect_slashes = redirect_slashes
# The following usages are now discouraged in favour of configuration
# during Router.__init__(...)
def mount(
- self, path: str, app: ASGIApp, name: str = None
+ self, path: str, app: ASGIApp, name: typing.Optional[str] = None
) -> None: # pragma: nocover
"""
We no longer document this API, and its usage is discouraged.
self.routes.append(route)
def host(
- self, host: str, app: ASGIApp, name: str = None
+ self, host: str, app: ASGIApp, name: typing.Optional[str] = None
) -> None: # pragma: no cover
"""
We no longer document this API, and its usage is discouraged.
self,
path: str,
endpoint: typing.Callable,
- methods: typing.List[str] = None,
- name: str = None,
+ methods: typing.Optional[typing.List[str]] = None,
+ name: typing.Optional[str] = None,
include_in_schema: bool = True,
) -> None: # pragma: nocover
route = Route(
self.routes.append(route)
def add_websocket_route(
- self, path: str, endpoint: typing.Callable, name: str = None
+ self, path: str, endpoint: typing.Callable, name: typing.Optional[str] = None
) -> None: # pragma: no cover
route = WebSocketRoute(path, endpoint=endpoint, name=name)
self.routes.append(route)
def route(
self,
path: str,
- methods: typing.List[str] = None,
- name: str = None,
+ methods: typing.Optional[typing.List[str]] = None,
+ name: typing.Optional[str] = None,
include_in_schema: bool = True,
) -> typing.Callable: # pragma: nocover
"""
return decorator
def websocket_route(
- self, path: str, name: str = None
+ self, path: str, name: typing.Optional[str] = None
) -> typing.Callable: # pragma: nocover
"""
We no longer document this decorator style API, and its usage is discouraged.
def __init__(
self,
*,
- directory: PathLike = None,
- packages: typing.List[typing.Union[str, typing.Tuple[str, str]]] = None,
+ directory: typing.Optional[PathLike] = None,
+ packages: typing.Optional[
+ typing.List[typing.Union[str, typing.Tuple[str, str]]]
+ ] = None,
html: bool = False,
check_dir: bool = True,
) -> None:
def get_directories(
self,
- directory: PathLike = None,
- packages: typing.List[typing.Union[str, typing.Tuple[str, str]]] = None,
+ directory: typing.Optional[PathLike] = None,
+ packages: typing.Optional[
+ typing.List[typing.Union[str, typing.Tuple[str, str]]]
+ ] = None,
) -> typing.List[PathLike]:
"""
Given `directory` and `packages` arguments, return a list of all the
template: typing.Any,
context: dict,
status_code: int = 200,
- headers: typing.Mapping[str, str] = None,
- media_type: str = None,
- background: BackgroundTask = None,
+ headers: typing.Optional[typing.Mapping[str, str]] = None,
+ media_type: typing.Optional[str] = None,
+ background: typing.Optional[BackgroundTask] = None,
):
self.template = template
self.context = context
name: str,
context: dict,
status_code: int = 200,
- headers: typing.Mapping[str, str] = None,
- media_type: str = None,
- background: BackgroundTask = None,
+ headers: typing.Optional[typing.Mapping[str, str]] = None,
+ media_type: typing.Optional[str] = None,
+ background: typing.Optional[BackgroundTask] = None,
) -> _TemplateResponse:
if "request" not in context:
raise ValueError('context must include a "request" key')
class WebSocketDisconnect(Exception):
- def __init__(self, code: int = 1000, reason: str = None) -> None:
+ def __init__(self, code: int = 1000, reason: typing.Optional[str] = None) -> None:
self.code = code
self.reason = reason or ""
async def accept(
self,
- subprotocol: str = None,
- headers: typing.Iterable[typing.Tuple[bytes, bytes]] = None,
+ subprotocol: typing.Optional[str] = None,
+ headers: typing.Optional[typing.Iterable[typing.Tuple[bytes, bytes]]] = None,
) -> None:
headers = headers or []
else:
await self.send({"type": "websocket.send", "bytes": text.encode("utf-8")})
- async def close(self, code: int = 1000, reason: str = None) -> None:
+ async def close(
+ self, code: int = 1000, reason: typing.Optional[str] = None
+ ) -> None:
await self.send(
{"type": "websocket.close", "code": code, "reason": reason or ""}
)
class WebSocketClose:
- def __init__(self, code: int = 1000, reason: str = None) -> None:
+ def __init__(self, code: int = 1000, reason: typing.Optional[str] = None) -> None:
self.code = code
self.reason = reason or ""