diff --git a/synapse/federation/federation_base.py b/synapse/federation/federation_base.py
index f56344a3b9..4df90e02d7 100644
--- a/synapse/federation/federation_base.py
+++ b/synapse/federation/federation_base.py
@@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
-from collections import namedtuple
from typing import TYPE_CHECKING
from synapse.api.constants import MAX_DEPTH, EventContentFields, EventTypes, Membership
@@ -104,10 +103,6 @@ class FederationBase:
return pdu
-class PduToCheckSig(namedtuple("PduToCheckSig", ["pdu", "sender_domain", "deferreds"])):
- pass
-
-
async def _check_sigs_on_pdu(
keyring: Keyring, room_version: RoomVersion, pdu: EventBase
) -> None:
diff --git a/synapse/federation/send_queue.py b/synapse/federation/send_queue.py
index 63289a5a33..0d7c4f5067 100644
--- a/synapse/federation/send_queue.py
+++ b/synapse/federation/send_queue.py
@@ -30,7 +30,6 @@ Events are replicated via a separate events stream.
"""
import logging
-from collections import namedtuple
from typing import (
TYPE_CHECKING,
Dict,
@@ -43,6 +42,7 @@ from typing import (
Type,
)
+import attr
from sortedcontainers import SortedDict
from synapse.api.presence import UserPresenceState
@@ -382,13 +382,11 @@ class BaseFederationRow:
raise NotImplementedError()
-class PresenceDestinationsRow(
- BaseFederationRow,
- namedtuple(
- "PresenceDestinationsRow",
- ("state", "destinations"), # UserPresenceState # list[str]
- ),
-):
+@attr.s(slots=True, frozen=True, auto_attribs=True)
+class PresenceDestinationsRow(BaseFederationRow):
+ state: UserPresenceState
+ destinations: List[str]
+
TypeId = "pd"
@staticmethod
@@ -404,17 +402,15 @@ class PresenceDestinationsRow(
buff.presence_destinations.append((self.state, self.destinations))
-class KeyedEduRow(
- BaseFederationRow,
- namedtuple(
- "KeyedEduRow",
- ("key", "edu"), # tuple(str) - the edu key passed to send_edu # Edu
- ),
-):
+@attr.s(slots=True, frozen=True, auto_attribs=True)
+class KeyedEduRow(BaseFederationRow):
"""Streams EDUs that have an associated key that is ued to clobber. For example,
typing EDUs clobber based on room_id.
"""
+ key: Tuple[str, ...] # the edu key passed to send_edu
+ edu: Edu
+
TypeId = "k"
@staticmethod
@@ -428,9 +424,12 @@ class KeyedEduRow(
buff.keyed_edus.setdefault(self.edu.destination, {})[self.key] = self.edu
-class EduRow(BaseFederationRow, namedtuple("EduRow", ("edu",))): # Edu
+@attr.s(slots=True, frozen=True, auto_attribs=True)
+class EduRow(BaseFederationRow):
"""Streams EDUs that don't have keys. See KeyedEduRow"""
+ edu: Edu
+
TypeId = "e"
@staticmethod
@@ -453,14 +452,14 @@ _rowtypes: Tuple[Type[BaseFederationRow], ...] = (
TypeToRow = {Row.TypeId: Row for Row in _rowtypes}
-ParsedFederationStreamData = namedtuple(
- "ParsedFederationStreamData",
- (
- "presence_destinations", # list of tuples of UserPresenceState and destinations
- "keyed_edus", # dict of destination -> { key -> Edu }
- "edus", # dict of destination -> [Edu]
- ),
-)
+@attr.s(slots=True, frozen=True, auto_attribs=True)
+class ParsedFederationStreamData:
+ # list of tuples of UserPresenceState and destinations
+ presence_destinations: List[Tuple[UserPresenceState, List[str]]]
+ # dict of destination -> { key -> Edu }
+ keyed_edus: Dict[str, Dict[Tuple[str, ...], Edu]]
+ # dict of destination -> [Edu]
+ edus: Dict[str, List[Edu]]
def process_rows_for_federation(
|