Skip to content

Commit

Permalink
Better typing (#5078)
Browse files Browse the repository at this point in the history
  • Loading branch information
asvetlov authored Oct 18, 2020
1 parent 0ee92db commit 6db8b67
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 32 deletions.
4 changes: 2 additions & 2 deletions aiohttp/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ async def _request(
data: Any=None,
json: Any=None,
cookies: Optional[LooseCookies]=None,
headers: LooseHeaders=None,
headers: Optional[LooseHeaders]=None,
skip_auto_headers: Optional[Iterable[str]]=None,
auth: Optional[BasicAuth]=None,
allow_redirects: bool=True,
Expand Down Expand Up @@ -1089,7 +1089,7 @@ def request(
params: Optional[Mapping[str, str]]=None,
data: Any=None,
json: Any=None,
headers: LooseHeaders=None,
headers: Optional[LooseHeaders]=None,
skip_auto_headers: Optional[Iterable[str]]=None,
auth: Optional[BasicAuth]=None,
allow_redirects: bool=True,
Expand Down
2 changes: 1 addition & 1 deletion aiohttp/client_proto.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def set_parser(self, parser: Any, payload: Any) -> None:
data, self._tail = self._tail, b''
self.data_received(data)

def set_response_params(self, *, timer: BaseTimerContext=None,
def set_response_params(self, *, timer: Optional[BaseTimerContext]=None,
skip_payload: bool=False,
read_until_eof: bool=False,
auto_decompress: bool=True,
Expand Down
2 changes: 1 addition & 1 deletion aiohttp/client_reqrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,7 @@ async def text(self,

return self._body.decode(encoding, errors=errors) # type: ignore

async def json(self, *, encoding: str=None,
async def json(self, *, encoding: Optional[str]=None,
loads: JSONDecoder=DEFAULT_JSON_DECODER,
content_type: Optional[str]='application/json') -> Any:
"""Read and decodes JSON response."""
Expand Down
4 changes: 2 additions & 2 deletions aiohttp/tracing.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from types import SimpleNamespace
from typing import TYPE_CHECKING, Awaitable, Type, TypeVar
from typing import TYPE_CHECKING, Awaitable, Optional, Type, TypeVar

import attr
from multidict import CIMultiDict # noqa
Expand Down Expand Up @@ -92,7 +92,7 @@ def __init__(

def trace_config_ctx(
self,
trace_request_ctx: SimpleNamespace=None
trace_request_ctx: Optional[SimpleNamespace]=None
) -> SimpleNamespace: # noqa
""" Return a new trace_config_ctx instance """
return self._trace_config_ctx_factory(
Expand Down
2 changes: 1 addition & 1 deletion aiohttp/web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class Application(MutableMapping[str, Any]):
def __init__(self, *,
logger: logging.Logger=web_logger,
middlewares: Iterable[_Middleware]=(),
handler_args: Mapping[str, Any]=None,
handler_args: Optional[Mapping[str, Any]]=None,
client_max_size: int=1024**2,
debug: Any=... # mypy doesn't support ellipsis
) -> None:
Expand Down
8 changes: 4 additions & 4 deletions aiohttp/web_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ def __init__(self, *,
content_type: Optional[str]=None,
charset: Optional[str]=None,
zlib_executor_size: Optional[int]=None,
zlib_executor: Executor=None) -> None:
zlib_executor: Optional[Executor]=None) -> None:
if body is not None and text is not None:
raise ValueError("body and text are not allowed together")

Expand Down Expand Up @@ -716,11 +716,11 @@ async def _do_start_compression(self, coding: ContentCoding) -> None:


def json_response(data: Any=sentinel, *,
text: str=None,
body: bytes=None,
text: Optional[str]=None,
body: Optional[bytes]=None,
status: int=200,
reason: Optional[str]=None,
headers: LooseHeaders=None,
headers: Optional[LooseHeaders]=None,
content_type: str='application/json',
dumps: JSONEncoder=json.dumps) -> Response:
if data is not sentinel:
Expand Down
2 changes: 1 addition & 1 deletion aiohttp/web_routedef.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def __repr__(self) -> str:
def register(self, router: UrlDispatcher) -> List[AbstractRoute]:
resource = router.add_static(self.prefix, self.path, **self.kwargs)
routes = resource.get_info().get('routes', {})
return routes.values()
return list(routes.values())


def route(method: str, path: str, handler: _HandlerType,
Expand Down
2 changes: 1 addition & 1 deletion aiohttp/web_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class TCPSite(BaseSite):
__slots__ = ('_host', '_port', '_reuse_address', '_reuse_port')

def __init__(self, runner: 'BaseRunner',
host: str=None, port: int=None, *,
host: Optional[str]=None, port: Optional[int]=None, *,
shutdown_timeout: float=60.0,
ssl_context: Optional[SSLContext]=None,
backlog: int=128, reuse_address: Optional[bool]=None,
Expand Down
59 changes: 42 additions & 17 deletions aiohttp/web_urldispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
List,
Mapping,
Optional,
Pattern,
Set,
Sized,
Tuple,
Expand All @@ -28,6 +29,7 @@
cast,
)

from typing_extensions import TypedDict
from yarl import URL

from . import hdrs
Expand Down Expand Up @@ -69,6 +71,25 @@
_Resolve = Tuple[Optional[AbstractMatchInfo], Set[str]]


class _InfoDict(TypedDict, total=False):
path: str

formatter: str
pattern: Pattern[str]

directory: Path
prefix: str
routes: Mapping[str, 'AbstractRoute']

app: 'Application'

domain: str

rule: 'AbstractRuleMatching'

http_exception: HTTPException


class AbstractResource(Sized, Iterable['AbstractRoute']):

def __init__(self, *, name: Optional[str]=None) -> None:
Expand Down Expand Up @@ -106,7 +127,7 @@ def add_prefix(self, prefix: str) -> None:
"""

@abc.abstractmethod
def get_info(self) -> Dict[str, Any]:
def get_info(self) -> _InfoDict:
"""Return a dict with additional info useful for introspection"""

def freeze(self) -> None:
Expand All @@ -121,8 +142,8 @@ class AbstractRoute(abc.ABC):

def __init__(self, method: str,
handler: Union[_WebHandler, Type[AbstractView]], *,
expect_handler: _ExpectHandler=None,
resource: AbstractResource=None) -> None:
expect_handler: Optional[_ExpectHandler]=None,
resource: Optional[AbstractResource]=None) -> None:

if expect_handler is None:
expect_handler = _default_expect_handler
Expand Down Expand Up @@ -165,7 +186,7 @@ def resource(self) -> Optional[AbstractResource]:
return self._resource

@abc.abstractmethod
def get_info(self) -> Dict[str, Any]:
def get_info(self) -> _InfoDict:
"""Return a dict with additional info useful for introspection"""

@abc.abstractmethod # pragma: no branch
Expand Down Expand Up @@ -201,7 +222,7 @@ def expect_handler(self) -> _ExpectHandler:
def http_exception(self) -> Optional[HTTPException]:
return None

def get_info(self) -> Dict[str, str]:
def get_info(self) -> _InfoDict: # type: ignore
return self._route.get_info()

@property
Expand Down Expand Up @@ -361,7 +382,7 @@ def _match(self, path: str) -> Optional[Dict[str, str]]:
def raw_match(self, path: str) -> bool:
return self._path == path

def get_info(self) -> Dict[str, Any]:
def get_info(self) -> _InfoDict:
return {'path': self._path}

def url_for(self) -> URL: # type: ignore
Expand Down Expand Up @@ -436,7 +457,7 @@ def _match(self, path: str) -> Optional[Dict[str, str]]:
def raw_match(self, path: str) -> bool:
return self._formatter == path

def get_info(self) -> Dict[str, Any]:
def get_info(self) -> _InfoDict:
return {'formatter': self._formatter,
'pattern': self._pattern}

Expand Down Expand Up @@ -549,7 +570,7 @@ def _get_file_hash(byte_array: bytes) -> str:
b64 = base64.urlsafe_b64encode(m.digest())
return b64.decode('ascii')

def get_info(self) -> Dict[str, Any]:
def get_info(self) -> _InfoDict:
return {'directory': self._directory,
'prefix': self._prefix,
'routes': self._routes}
Expand Down Expand Up @@ -677,7 +698,7 @@ def url_for(self, *args: str, **kwargs: str) -> URL:
raise RuntimeError(".url_for() is not supported "
"by sub-application root")

def get_info(self) -> Dict[str, Any]:
def get_info(self) -> _InfoDict:
return {'app': self._app,
'prefix': self._prefix}

Expand Down Expand Up @@ -710,7 +731,7 @@ async def match(self, request: Request) -> bool:
"""Return bool if the request satisfies the criteria"""

@abc.abstractmethod # pragma: no branch
def get_info(self) -> Dict[str, Any]:
def get_info(self) -> _InfoDict:
"""Return a dict with additional info useful for introspection"""

@property
Expand Down Expand Up @@ -756,7 +777,7 @@ async def match(self, request: Request) -> bool:
def match_domain(self, host: str) -> bool:
return host.lower() == self._domain

def get_info(self) -> Dict[str, Any]:
def get_info(self) -> _InfoDict:
return {'domain': self._domain}


Expand Down Expand Up @@ -788,7 +809,7 @@ def __init__(self, rule: AbstractRuleMatching, app: 'Application') -> None:
def canonical(self) -> str:
return self._rule.canonical

def get_info(self) -> Dict[str, Any]:
def get_info(self) -> _InfoDict:
return {'app': self._app,
'rule': self._rule}

Expand Down Expand Up @@ -825,14 +846,18 @@ def __repr__(self) -> str:

@property
def name(self) -> Optional[str]:
return self._resource.name # type: ignore
if self._resource is None:
return None
return self._resource.name

def url_for(self, *args: str, **kwargs: str) -> URL:
"""Construct url for route with additional params."""
return self._resource.url_for(*args, **kwargs) # type: ignore
assert self._resource is not None
return self._resource.url_for(*args, **kwargs)

def get_info(self) -> Dict[str, Any]:
return self._resource.get_info() # type: ignore
def get_info(self) -> _InfoDict:
assert self._resource is not None
return self._resource.get_info()


class SystemRoute(AbstractRoute):
Expand All @@ -848,7 +873,7 @@ def url_for(self, *args: str, **kwargs: str) -> URL:
def name(self) -> Optional[str]:
return None

def get_info(self) -> Dict[str, Any]:
def get_info(self) -> _InfoDict:
return {'http_exception': self._http_exception}

async def _handle(self, request: Request) -> StreamResponse:
Expand Down
5 changes: 4 additions & 1 deletion aiohttp/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ def _wait_next_notify(self) -> 'asyncio.Future[bool]':

return waiter

def _notify_waiter_done(self, waiter: 'asyncio.Future[bool]'=None) -> None:
def _notify_waiter_done(
self,
waiter: Optional['asyncio.Future[bool]']=None
) -> None:
if waiter is None:
waiter = self._notify_waiter
if waiter is not None:
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ xfail_strict = true
follow_imports = silent
strict_optional = True
warn_redundant_casts = True
warn_unused_ignores = True

# uncomment next lines
# to enable strict mypy mode
#
check_untyped_defs = True
disallow_any_generics = True
disallow_untyped_defs = True
warn_unused_ignores = True


[mypy-pytest]
Expand Down

0 comments on commit 6db8b67

Please sign in to comment.