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

Commit d5e73cb

Browse files
authored
Define StateMap as immutable and add a MutableStateMap type. (#8183)
1 parent 2c2e649 commit d5e73cb

File tree

8 files changed

+52
-32
lines changed

8 files changed

+52
-32
lines changed

changelog.d/8183.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add type hints to `synapse.state`.

synapse/handlers/federation.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,13 @@
7272
from synapse.replication.http.membership import ReplicationUserJoinedLeftRoomRestServlet
7373
from synapse.state import StateResolutionStore, resolve_events_with_store
7474
from synapse.storage.databases.main.events_worker import EventRedactBehaviour
75-
from synapse.types import JsonDict, StateMap, UserID, get_domain_from_id
75+
from synapse.types import (
76+
JsonDict,
77+
MutableStateMap,
78+
StateMap,
79+
UserID,
80+
get_domain_from_id,
81+
)
7682
from synapse.util.async_helpers import Linearizer, concurrently_execute
7783
from synapse.util.distributor import user_joined_room
7884
from synapse.util.retryutils import NotRetryingDestination
@@ -96,7 +102,7 @@ class _NewEventInfo:
96102

97103
event = attr.ib(type=EventBase)
98104
state = attr.ib(type=Optional[Sequence[EventBase]], default=None)
99-
auth_events = attr.ib(type=Optional[StateMap[EventBase]], default=None)
105+
auth_events = attr.ib(type=Optional[MutableStateMap[EventBase]], default=None)
100106

101107

102108
class FederationHandler(BaseHandler):
@@ -2053,7 +2059,7 @@ async def _prep_event(
20532059
origin: str,
20542060
event: EventBase,
20552061
state: Optional[Iterable[EventBase]],
2056-
auth_events: Optional[StateMap[EventBase]],
2062+
auth_events: Optional[MutableStateMap[EventBase]],
20572063
backfilled: bool,
20582064
) -> EventContext:
20592065
context = await self.state_handler.compute_event_context(event, old_state=state)
@@ -2137,7 +2143,9 @@ async def _check_for_soft_fail(
21372143
current_states = await self.state_handler.resolve_events(
21382144
room_version, state_sets, event
21392145
)
2140-
current_state_ids = {k: e.event_id for k, e in current_states.items()}
2146+
current_state_ids = {
2147+
k: e.event_id for k, e in current_states.items()
2148+
} # type: StateMap[str]
21412149
else:
21422150
current_state_ids = await self.state_handler.get_current_state_ids(
21432151
event.room_id, latest_event_ids=extrem_ids
@@ -2223,7 +2231,7 @@ async def do_auth(
22232231
origin: str,
22242232
event: EventBase,
22252233
context: EventContext,
2226-
auth_events: StateMap[EventBase],
2234+
auth_events: MutableStateMap[EventBase],
22272235
) -> EventContext:
22282236
"""
22292237
@@ -2274,7 +2282,7 @@ async def _update_auth_events_and_context_for_auth(
22742282
origin: str,
22752283
event: EventBase,
22762284
context: EventContext,
2277-
auth_events: StateMap[EventBase],
2285+
auth_events: MutableStateMap[EventBase],
22782286
) -> EventContext:
22792287
"""Helper for do_auth. See there for docs.
22802288

synapse/handlers/room.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from synapse.storage.state import StateFilter
4242
from synapse.types import (
4343
JsonDict,
44+
MutableStateMap,
4445
Requester,
4546
RoomAlias,
4647
RoomID,
@@ -814,7 +815,7 @@ async def _send_events_for_new_room(
814815
room_id: str,
815816
preset_config: str,
816817
invite_list: List[str],
817-
initial_state: StateMap,
818+
initial_state: MutableStateMap,
818819
creation_content: JsonDict,
819820
room_alias: Optional[RoomAlias] = None,
820821
power_level_content_override: Optional[JsonDict] = None,

synapse/handlers/sync.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from synapse.types import (
3232
Collection,
3333
JsonDict,
34+
MutableStateMap,
3435
RoomStreamToken,
3536
StateMap,
3637
StreamToken,
@@ -588,7 +589,7 @@ async def compute_summary(
588589
room_id: str,
589590
sync_config: SyncConfig,
590591
batch: TimelineBatch,
591-
state: StateMap[EventBase],
592+
state: MutableStateMap[EventBase],
592593
now_token: StreamToken,
593594
) -> Optional[JsonDict]:
594595
""" Works out a room summary block for this room, summarising the number
@@ -736,7 +737,7 @@ async def compute_state_delta(
736737
since_token: Optional[StreamToken],
737738
now_token: StreamToken,
738739
full_state: bool,
739-
) -> StateMap[EventBase]:
740+
) -> MutableStateMap[EventBase]:
740741
""" Works out the difference in state between the start of the timeline
741742
and the previous sync.
742743

synapse/state/__init__.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
Sequence,
2626
Set,
2727
Union,
28+
cast,
2829
overload,
2930
)
3031

@@ -41,7 +42,7 @@
4142
from synapse.state import v1, v2
4243
from synapse.storage.databases.main.events_worker import EventRedactBehaviour
4344
from synapse.storage.roommember import ProfileInfo
44-
from synapse.types import Collection, StateMap
45+
from synapse.types import Collection, MutableStateMap, StateMap
4546
from synapse.util import Clock
4647
from synapse.util.async_helpers import Linearizer
4748
from synapse.util.caches.expiringcache import ExpiringCache
@@ -205,7 +206,7 @@ async def get_current_state_ids(
205206

206207
logger.debug("calling resolve_state_groups from get_current_state_ids")
207208
ret = await self.resolve_state_groups_for_events(room_id, latest_event_ids)
208-
return dict(ret.state)
209+
return ret.state
209210

210211
async def get_current_users_in_room(
211212
self, room_id: str, latest_event_ids: Optional[List[str]] = None
@@ -302,7 +303,7 @@ async def compute_event_context(
302303
# if we're given the state before the event, then we use that
303304
state_ids_before_event = {
304305
(s.type, s.state_key): s.event_id for s in old_state
305-
}
306+
} # type: StateMap[str]
306307
state_group_before_event = None
307308
state_group_before_event_prev_group = None
308309
deltas_to_state_group_before_event = None
@@ -315,7 +316,7 @@ async def compute_event_context(
315316
event.room_id, event.prev_event_ids()
316317
)
317318

318-
state_ids_before_event = dict(entry.state)
319+
state_ids_before_event = entry.state
319320
state_group_before_event = entry.state_group
320321
state_group_before_event_prev_group = entry.prev_group
321322
deltas_to_state_group_before_event = entry.delta_ids
@@ -540,7 +541,7 @@ async def resolve_state_groups(
540541
#
541542
# XXX: is this actually worthwhile, or should we just let
542543
# resolve_events_with_store do it?
543-
new_state = {}
544+
new_state = {} # type: MutableStateMap[str]
544545
conflicted_state = False
545546
for st in state_groups_ids.values():
546547
for key, e_id in st.items():
@@ -554,13 +555,20 @@ async def resolve_state_groups(
554555
if conflicted_state:
555556
logger.info("Resolving conflicted state for %r", room_id)
556557
with Measure(self.clock, "state._resolve_events"):
557-
new_state = await resolve_events_with_store(
558-
self.clock,
559-
room_id,
560-
room_version,
561-
list(state_groups_ids.values()),
562-
event_map=event_map,
563-
state_res_store=state_res_store,
558+
# resolve_events_with_store returns a StateMap, but we can
559+
# treat it as a MutableStateMap as it is above. It isn't
560+
# actually mutated anymore (and is frozen in
561+
# _make_state_cache_entry below).
562+
new_state = cast(
563+
MutableStateMap,
564+
await resolve_events_with_store(
565+
self.clock,
566+
room_id,
567+
room_version,
568+
list(state_groups_ids.values()),
569+
event_map=event_map,
570+
state_res_store=state_res_store,
571+
),
564572
)
565573

566574
# if the new state matches any of the input state groups, we can

synapse/state/v1.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
from synapse.api.errors import AuthError
3333
from synapse.api.room_versions import RoomVersions
3434
from synapse.events import EventBase
35-
from synapse.types import StateMap
35+
from synapse.types import MutableStateMap, StateMap
3636

3737
logger = logging.getLogger(__name__)
3838

@@ -131,7 +131,7 @@ async def resolve_events_with_store(
131131

132132
def _seperate(
133133
state_sets: Iterable[StateMap[str]],
134-
) -> Tuple[StateMap[str], StateMap[Set[str]]]:
134+
) -> Tuple[MutableStateMap[str], MutableStateMap[Set[str]]]:
135135
"""Takes the state_sets and figures out which keys are conflicted and
136136
which aren't. i.e., which have multiple different event_ids associated
137137
with them in different state sets.
@@ -152,7 +152,7 @@ def _seperate(
152152
"""
153153
state_set_iterator = iter(state_sets)
154154
unconflicted_state = dict(next(state_set_iterator))
155-
conflicted_state = {} # type: StateMap[Set[str]]
155+
conflicted_state = {} # type: MutableStateMap[Set[str]]
156156

157157
for state_set in state_set_iterator:
158158
for key, value in state_set.items():
@@ -208,7 +208,7 @@ def _create_auth_events_from_maps(
208208

209209

210210
def _resolve_with_state(
211-
unconflicted_state_ids: StateMap[str],
211+
unconflicted_state_ids: MutableStateMap[str],
212212
conflicted_state_ids: StateMap[Set[str]],
213213
auth_event_ids: StateMap[str],
214214
state_map: Dict[str, EventBase],
@@ -241,7 +241,7 @@ def _resolve_with_state(
241241

242242

243243
def _resolve_state_events(
244-
conflicted_state: StateMap[List[EventBase]], auth_events: StateMap[EventBase]
244+
conflicted_state: StateMap[List[EventBase]], auth_events: MutableStateMap[EventBase]
245245
) -> StateMap[EventBase]:
246246
""" This is where we actually decide which of the conflicted state to
247247
use.

synapse/state/v2.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
from synapse.api.errors import AuthError
3939
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
4040
from synapse.events import EventBase
41-
from synapse.types import StateMap
41+
from synapse.types import MutableStateMap, StateMap
4242
from synapse.util import Clock
4343

4444
logger = logging.getLogger(__name__)
@@ -414,7 +414,7 @@ async def _iterative_auth_checks(
414414
base_state: StateMap[str],
415415
event_map: Dict[str, EventBase],
416416
state_res_store: "synapse.state.StateResolutionStore",
417-
) -> StateMap[str]:
417+
) -> MutableStateMap[str]:
418418
"""Sequentially apply auth checks to each event in given list, updating the
419419
state as it goes along.
420420
@@ -430,7 +430,7 @@ async def _iterative_auth_checks(
430430
Returns:
431431
Returns the final updated state
432432
"""
433-
resolved_state = base_state.copy()
433+
resolved_state = dict(base_state)
434434
room_version_obj = KNOWN_ROOM_VERSIONS[room_version]
435435

436436
for idx, event_id in enumerate(event_ids, start=1):

synapse/types.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import string
1919
import sys
2020
from collections import namedtuple
21-
from typing import Any, Dict, Tuple, Type, TypeVar
21+
from typing import Any, Dict, Mapping, MutableMapping, Tuple, Type, TypeVar
2222

2323
import attr
2424
from signedjson.key import decode_verify_key_bytes
@@ -41,8 +41,9 @@ class Collection(Iterable[T_co], Container[T_co], Sized): # type: ignore
4141
# Define a state map type from type/state_key to T (usually an event ID or
4242
# event)
4343
T = TypeVar("T")
44-
StateMap = Dict[Tuple[str, str], T]
45-
44+
StateKey = Tuple[str, str]
45+
StateMap = Mapping[StateKey, T]
46+
MutableStateMap = MutableMapping[StateKey, T]
4647

4748
# the type of a JSON-serialisable dict. This could be made stronger, but it will
4849
# do for now.

0 commit comments

Comments
 (0)