Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Fix typing for notifier #8064

Merged
merged 4 commits into from
Aug 12, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/8064.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add type hints to `Notifier`.
7 changes: 5 additions & 2 deletions synapse/federation/sender/transaction_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
from typing import TYPE_CHECKING, List
from typing import TYPE_CHECKING, List, Tuple

from canonicaljson import json

Expand Down Expand Up @@ -54,7 +54,10 @@ def __init__(self, hs: "synapse.server.HomeServer"):

@measure_func("_send_new_transaction")
async def send_new_transaction(
self, destination: str, pending_pdus: List[EventBase], pending_edus: List[Edu]
self,
destination: str,
pending_pdus: List[Tuple[EventBase, int]],
clokep marked this conversation as resolved.
Show resolved Hide resolved
pending_edus: List[Edu],
):

# Make a transaction-sending opentracing span. This span follows on from
Expand Down
12 changes: 8 additions & 4 deletions synapse/notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
Set,
Tuple,
TypeVar,
Union,
)

from prometheus_client import Counter
Expand Down Expand Up @@ -186,7 +187,7 @@ def __init__(self, hs: "synapse.server.HomeServer"):
self.store = hs.get_datastore()
self.pending_new_room_events = (
[]
) # type: List[Tuple[int, EventBase, Collection[str]]]
) # type: List[Tuple[int, EventBase, Collection[Union[str, UserID]]]]

# Called when there are new things to stream over replication
self.replication_callbacks = [] # type: List[Callable[[], None]]
Expand Down Expand Up @@ -246,7 +247,7 @@ def on_new_room_event(
event: EventBase,
room_stream_id: int,
max_room_stream_id: int,
extra_users: Collection[str] = [],
extra_users: Collection[Union[str, UserID]] = [],
):
""" Used by handlers to inform the notifier something has happened
in the room, room event wise.
Expand Down Expand Up @@ -282,7 +283,10 @@ def _notify_pending_new_room_events(self, max_room_stream_id: int):
self._on_new_room_event(event, room_stream_id, extra_users)

def _on_new_room_event(
self, event: EventBase, room_stream_id: int, extra_users: Collection[str] = []
self,
event: EventBase,
room_stream_id: int,
extra_users: Collection[Union[str, UserID]] = [],
):
"""Notify any user streams that are interested in this room event"""
# poke any interested application service.
Expand Down Expand Up @@ -310,7 +314,7 @@ def on_new_event(
self,
stream_key: str,
new_token: int,
users: Collection[str] = [],
users: Collection[Union[str, UserID]] = [],
rooms: Collection[str] = [],
):
""" Used to inform listeners that something has happened event wise.
Expand Down
23 changes: 16 additions & 7 deletions synapse/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import abc
import re
import string
import sys
from collections import namedtuple
from typing import Any, Dict, Tuple, TypeVar
from typing import Any, Dict, Tuple, Type, TypeVar

import attr
from signedjson.key import decode_verify_key_bytes
Expand All @@ -33,7 +34,7 @@

T_co = TypeVar("T_co", covariant=True)

class Collection(Iterable[T_co], Container[T_co], Sized):
class Collection(Iterable[T_co], Container[T_co], Sized): # type: ignore
__slots__ = ()


Expand Down Expand Up @@ -141,6 +142,9 @@ def get_localpart_from_id(string):
return string[1:idx]


DS = TypeVar("DS", bound="DomainSpecificString")


class DomainSpecificString(namedtuple("DomainSpecificString", ("localpart", "domain"))):
"""Common base class among ID/name strings that have a local part and a
domain name, prefixed with a sigil.
Expand All @@ -151,6 +155,10 @@ class DomainSpecificString(namedtuple("DomainSpecificString", ("localpart", "dom
'domain' : The domain part of the name
"""

__metaclass__ = abc.ABCMeta
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the Python 2 way of declaring metaclasses?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what we do elsewhere. I'm not sure if its "better" to move it up?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong opinion. 👍


SIGIL = abc.abstractproperty() # type: str # type: ignore

# Deny iteration because it will bite you if you try to create a singleton
# set by:
# users = set(user)
Expand All @@ -166,7 +174,7 @@ def __deepcopy__(self, memo):
return self

@classmethod
def from_string(cls, s: str):
def from_string(cls: Type[DS], s: str) -> DS:
"""Parse the string given by 's' into a structure object."""
if len(s) < 1 or s[0:1] != cls.SIGIL:
raise SynapseError(
Expand All @@ -190,12 +198,12 @@ def from_string(cls, s: str):
# names on one HS
return cls(localpart=parts[0], domain=domain)

def to_string(self):
def to_string(self) -> str:
"""Return a string encoding the fields of the structure object."""
return "%s%s:%s" % (self.SIGIL, self.localpart, self.domain)

@classmethod
def is_valid(cls, s):
def is_valid(cls: Type[DS], s: str) -> bool:
try:
cls.from_string(s)
return True
Expand Down Expand Up @@ -235,8 +243,9 @@ class GroupID(DomainSpecificString):
SIGIL = "+"

@classmethod
def from_string(cls, s):
group_id = super(GroupID, cls).from_string(s)
def from_string(cls: Type[DS], s: str) -> DS:
group_id = super().from_string(s) # type: DS # type: ignore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we setting the type or ignoring it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha, this means "I promise mypy the result of this type is str now shut up about this line". mypy doesn't seem to like using super with a Type[DS], which is why we have to ignore the line and manually type it.


if not group_id.localpart:
raise SynapseError(400, "Group ID cannot be empty", Codes.INVALID_PARAM)

Expand Down
9 changes: 6 additions & 3 deletions synapse/util/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import logging
from functools import wraps
from typing import Any, Callable, TypeVar, cast

from prometheus_client import Counter

Expand Down Expand Up @@ -57,8 +58,10 @@
sub_metrics=["real_time_max", "real_time_sum"],
)

T = TypeVar("T", bound=Callable[..., Any])

def measure_func(name=None):

def measure_func(name: Optional[str] = None) -> Callable[[T], T]:
"""
Used to decorate an async function with a `Measure` context manager.

Expand All @@ -76,7 +79,7 @@ async def foo(...):

"""

def wrapper(func):
def wrapper(func: T) -> T:
block_name = func.__name__ if name is None else name

@wraps(func)
Expand All @@ -85,7 +88,7 @@ async def measured_func(self, *args, **kwargs):
r = await func(self, *args, **kwargs)
return r

return measured_func
return cast(T, measured_func)

return wrapper

Expand Down
2 changes: 2 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ commands = mypy \
synapse/storage/state.py \
synapse/storage/util \
synapse/streams \
synapse/types.py \
synapse/util/caches/stream_change_cache.py \
synapse/util/metrics.py \
tests/replication \
tests/test_utils \
tests/rest/client/v2_alpha/test_auth.py \
Expand Down