Skip to content

Commit

Permalink
Add typing.Optional on missing annotations (#1549)
Browse files Browse the repository at this point in the history
* Add `typing.Optional` on missing annotations

* Add `no_implicit_optional` on mypy settings
  • Loading branch information
Kludex committed Apr 21, 2022
1 parent d7cbe2a commit 5b56e7d
Show file tree
Hide file tree
Showing 17 changed files with 127 additions and 92 deletions.
4 changes: 4 additions & 0 deletions setup.cfg
Expand Up @@ -5,8 +5,12 @@ max-line-length = 88
[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
Expand Down
41 changes: 23 additions & 18 deletions starlette/applications.py
Expand Up @@ -41,17 +41,22 @@ class Starlette:
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.
Expand Down Expand Up @@ -124,7 +129,7 @@ def on_event(self, event_type: str) -> typing.Callable: # pragma: nocover
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.
Expand All @@ -141,7 +146,7 @@ def mount(
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.
Expand Down Expand Up @@ -180,16 +185,16 @@ def add_route(
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(
path, route, methods=methods, name=name, include_in_schema=include_in_schema
)

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)

Expand All @@ -205,8 +210,8 @@ def decorator(func: typing.Callable) -> typing.Callable:
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
"""
Expand Down Expand Up @@ -234,7 +239,7 @@ def decorator(func: typing.Callable) -> typing.Callable:
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.
Expand Down
4 changes: 2 additions & 2 deletions starlette/authentication.py
Expand Up @@ -20,7 +20,7 @@ def has_required_scope(conn: HTTPConnection, scopes: typing.Sequence[str]) -> bo
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)

Expand Down Expand Up @@ -110,7 +110,7 @@ async def authenticate(


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)


Expand Down
2 changes: 1 addition & 1 deletion starlette/background.py
Expand Up @@ -29,7 +29,7 @@ async def __call__(self) -> None:


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(
Expand Down
14 changes: 10 additions & 4 deletions starlette/config.py
Expand Up @@ -52,7 +52,7 @@ def __len__(self) -> int:
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
Expand Down Expand Up @@ -88,12 +88,18 @@ def __call__(
...

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]
Expand All @@ -118,7 +124,7 @@ def _read_file(self, file_name: typing.Union[str, Path]) -> typing.Dict[str, str
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
Expand Down
9 changes: 6 additions & 3 deletions starlette/exceptions.py
Expand Up @@ -10,7 +10,10 @@

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
Expand All @@ -27,8 +30,8 @@ class ExceptionMiddleware:
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:
Expand Down
4 changes: 2 additions & 2 deletions starlette/middleware/authentication.py
Expand Up @@ -16,8 +16,8 @@ def __init__(
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
Expand Down
4 changes: 3 additions & 1 deletion starlette/middleware/base.py
Expand Up @@ -13,7 +13,9 @@


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

Expand Down
2 changes: 1 addition & 1 deletion starlette/middleware/cors.py
Expand Up @@ -18,7 +18,7 @@ def __init__(
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:
Expand Down
5 changes: 4 additions & 1 deletion starlette/middleware/errors.py
Expand Up @@ -135,7 +135,10 @@ class ServerErrorMiddleware:
"""

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
Expand Down
2 changes: 1 addition & 1 deletion starlette/middleware/trustedhost.py
Expand Up @@ -11,7 +11,7 @@ class TrustedHostMiddleware:
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:
Expand Down
2 changes: 1 addition & 1 deletion starlette/requests.py
Expand Up @@ -65,7 +65,7 @@ class HTTPConnection(Mapping):
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

Expand Down
46 changes: 24 additions & 22 deletions starlette/responses.py
Expand Up @@ -38,9 +38,9 @@ def __init__(
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:
Expand All @@ -56,7 +56,9 @@ def render(self, content: typing.Any) -> bytes:
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
Expand Down Expand Up @@ -97,10 +99,10 @@ def set_cookie(
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",
Expand Down Expand Up @@ -133,7 +135,7 @@ def delete_cookie(
self,
key: str,
path: str = "/",
domain: str = None,
domain: typing.Optional[str] = None,
secure: bool = False,
httponly: bool = False,
samesite: str = "lax",
Expand Down Expand Up @@ -178,9 +180,9 @@ def __init__(
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)

Expand All @@ -199,8 +201,8 @@ def __init__(
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
Expand All @@ -213,9 +215,9 @@ def __init__(
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
Expand Down Expand Up @@ -268,12 +270,12 @@ def __init__(
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
Expand Down

0 comments on commit 5b56e7d

Please sign in to comment.