Use `ParamSpec` in type hints for `synapse.logging.context` (#12150)

Signed-off-by: Sean Quah <seanq@element.io>
This commit is contained in:
Sean Quah 2022-03-08 15:58:14 +00:00 committed by GitHub
parent 0dc9c5653c
commit 5627182788
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 25 deletions

1
changelog.d/12150.misc Normal file
View File

@ -0,0 +1 @@
Use `ParamSpec` in type hints for `synapse.logging.context`.

View File

@ -153,8 +153,9 @@ class InitialSyncHandler:
public_room_ids = await self.store.get_public_room_ids() public_room_ids = await self.store.get_public_room_ids()
limit = pagin_config.limit if pagin_config.limit is not None:
if limit is None: limit = pagin_config.limit
else:
limit = 10 limit = 10
serializer_options = SerializeEventConfig(as_client_event=as_client_event) serializer_options = SerializeEventConfig(as_client_event=as_client_event)

View File

@ -29,7 +29,6 @@ import warnings
from types import TracebackType from types import TracebackType
from typing import ( from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Any,
Awaitable, Awaitable,
Callable, Callable,
Optional, Optional,
@ -41,7 +40,7 @@ from typing import (
) )
import attr import attr
from typing_extensions import Literal from typing_extensions import Literal, ParamSpec
from twisted.internet import defer, threads from twisted.internet import defer, threads
from twisted.python.threadpool import ThreadPool from twisted.python.threadpool import ThreadPool
@ -719,32 +718,33 @@ def nested_logging_context(suffix: str) -> LoggingContext:
) )
P = ParamSpec("P")
R = TypeVar("R") R = TypeVar("R")
@overload @overload
def preserve_fn( # type: ignore[misc] def preserve_fn( # type: ignore[misc]
f: Callable[..., Awaitable[R]], f: Callable[P, Awaitable[R]],
) -> Callable[..., "defer.Deferred[R]"]: ) -> Callable[P, "defer.Deferred[R]"]:
# The `type: ignore[misc]` above suppresses # The `type: ignore[misc]` above suppresses
# "Overloaded function signatures 1 and 2 overlap with incompatible return types" # "Overloaded function signatures 1 and 2 overlap with incompatible return types"
... ...
@overload @overload
def preserve_fn(f: Callable[..., R]) -> Callable[..., "defer.Deferred[R]"]: def preserve_fn(f: Callable[P, R]) -> Callable[P, "defer.Deferred[R]"]:
... ...
def preserve_fn( def preserve_fn(
f: Union[ f: Union[
Callable[..., R], Callable[P, R],
Callable[..., Awaitable[R]], Callable[P, Awaitable[R]],
] ]
) -> Callable[..., "defer.Deferred[R]"]: ) -> Callable[P, "defer.Deferred[R]"]:
"""Function decorator which wraps the function with run_in_background""" """Function decorator which wraps the function with run_in_background"""
def g(*args: Any, **kwargs: Any) -> "defer.Deferred[R]": def g(*args: P.args, **kwargs: P.kwargs) -> "defer.Deferred[R]":
return run_in_background(f, *args, **kwargs) return run_in_background(f, *args, **kwargs)
return g return g
@ -752,7 +752,7 @@ def preserve_fn(
@overload @overload
def run_in_background( # type: ignore[misc] def run_in_background( # type: ignore[misc]
f: Callable[..., Awaitable[R]], *args: Any, **kwargs: Any f: Callable[P, Awaitable[R]], *args: P.args, **kwargs: P.kwargs
) -> "defer.Deferred[R]": ) -> "defer.Deferred[R]":
# The `type: ignore[misc]` above suppresses # The `type: ignore[misc]` above suppresses
# "Overloaded function signatures 1 and 2 overlap with incompatible return types" # "Overloaded function signatures 1 and 2 overlap with incompatible return types"
@ -761,18 +761,22 @@ def run_in_background( # type: ignore[misc]
@overload @overload
def run_in_background( def run_in_background(
f: Callable[..., R], *args: Any, **kwargs: Any f: Callable[P, R], *args: P.args, **kwargs: P.kwargs
) -> "defer.Deferred[R]": ) -> "defer.Deferred[R]":
... ...
def run_in_background( def run_in_background( # type: ignore[misc]
# The `type: ignore[misc]` above suppresses
# "Overloaded function implementation does not accept all possible arguments of signature 1"
# "Overloaded function implementation does not accept all possible arguments of signature 2"
# which seems like a bug in mypy.
f: Union[ f: Union[
Callable[..., R], Callable[P, R],
Callable[..., Awaitable[R]], Callable[P, Awaitable[R]],
], ],
*args: Any, *args: P.args,
**kwargs: Any, **kwargs: P.kwargs,
) -> "defer.Deferred[R]": ) -> "defer.Deferred[R]":
"""Calls a function, ensuring that the current context is restored after """Calls a function, ensuring that the current context is restored after
return from the function, and that the sentinel context is set once the return from the function, and that the sentinel context is set once the
@ -872,7 +876,7 @@ def _set_context_cb(result: ResultT, context: LoggingContext) -> ResultT:
def defer_to_thread( def defer_to_thread(
reactor: "ISynapseReactor", f: Callable[..., R], *args: Any, **kwargs: Any reactor: "ISynapseReactor", f: Callable[P, R], *args: P.args, **kwargs: P.kwargs
) -> "defer.Deferred[R]": ) -> "defer.Deferred[R]":
""" """
Calls the function `f` using a thread from the reactor's default threadpool and Calls the function `f` using a thread from the reactor's default threadpool and
@ -908,9 +912,9 @@ def defer_to_thread(
def defer_to_threadpool( def defer_to_threadpool(
reactor: "ISynapseReactor", reactor: "ISynapseReactor",
threadpool: ThreadPool, threadpool: ThreadPool,
f: Callable[..., R], f: Callable[P, R],
*args: Any, *args: P.args,
**kwargs: Any, **kwargs: P.kwargs,
) -> "defer.Deferred[R]": ) -> "defer.Deferred[R]":
""" """
A wrapper for twisted.internet.threads.deferToThreadpool, which handles A wrapper for twisted.internet.threads.deferToThreadpool, which handles

View File

@ -76,7 +76,8 @@ REQUIREMENTS = [
"netaddr>=0.7.18", "netaddr>=0.7.18",
"Jinja2>=2.9", "Jinja2>=2.9",
"bleach>=1.4.3", "bleach>=1.4.3",
"typing-extensions>=3.7.4", # We use `ParamSpec`, which was added in `typing-extensions` 3.10.0.0.
"typing-extensions>=3.10.0",
# We enforce that we have a `cryptography` version that bundles an `openssl` # We enforce that we have a `cryptography` version that bundles an `openssl`
# with the latest security patches. # with the latest security patches.
"cryptography>=3.4.7", "cryptography>=3.4.7",

View File

@ -16,7 +16,7 @@ import abc
import logging import logging
import os import os
import shutil import shutil
from typing import TYPE_CHECKING, Optional from typing import TYPE_CHECKING, Callable, Optional
from synapse.config._base import Config from synapse.config._base import Config
from synapse.logging.context import defer_to_thread, run_in_background from synapse.logging.context import defer_to_thread, run_in_background
@ -150,8 +150,13 @@ class FileStorageProviderBackend(StorageProvider):
dirname = os.path.dirname(backup_fname) dirname = os.path.dirname(backup_fname)
os.makedirs(dirname, exist_ok=True) os.makedirs(dirname, exist_ok=True)
# mypy needs help inferring the type of the second parameter, which is generic
shutil_copyfile: Callable[[str, str], str] = shutil.copyfile
await defer_to_thread( await defer_to_thread(
self.hs.get_reactor(), shutil.copyfile, primary_fname, backup_fname self.hs.get_reactor(),
shutil_copyfile,
primary_fname,
backup_fname,
) )
async def fetch(self, path: str, file_info: FileInfo) -> Optional[Responder]: async def fetch(self, path: str, file_info: FileInfo) -> Optional[Responder]: