diff --git a/synapse/events/__init__.py b/synapse/events/__init__.py
index 88ed6d764f..f813fa2fe7 100644
--- a/synapse/events/__init__.py
+++ b/synapse/events/__init__.py
@@ -23,6 +23,7 @@ from unpaddedbase64 import encode_base64
from synapse.api.errors import UnsupportedRoomVersionError
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, EventFormatVersions
+from synapse.types import JsonDict
from synapse.util.caches import intern_dict
from synapse.util.frozenutils import freeze
@@ -116,16 +117,32 @@ class _EventInternalMetadata(object):
return getattr(self, "redacted", False)
-def _event_dict_property(key):
+_SENTINEL = object()
+
+
+def _event_dict_property(key, default=_SENTINEL):
+ """Creates a new property for the given key that delegates access to
+ `self._event_dict`.
+
+ The default is used if the key is missing from the `_event_dict`, if given,
+ otherwise an AttributeError will be raised.
+
+ Note: If a default is given then `hasattr` will always return true.
+ """
+
# We want to be able to use hasattr with the event dict properties.
# However, (on python3) hasattr expects AttributeError to be raised. Hence,
# we need to transform the KeyError into an AttributeError
- def getter(self):
+
+ def getter_raises(self):
try:
return self._event_dict[key]
except KeyError:
raise AttributeError(key)
+ def getter_default(self):
+ return self._event_dict.get(key, default)
+
def setter(self, v):
try:
self._event_dict[key] = v
@@ -138,7 +155,11 @@ def _event_dict_property(key):
except KeyError:
raise AttributeError(key)
- return property(getter, setter, delete)
+ if default is _SENTINEL:
+ # No default given, so use the getter that raises
+ return property(getter_raises, setter, delete)
+ else:
+ return property(getter_default, setter, delete)
class EventBase(object):
@@ -165,7 +186,7 @@ class EventBase(object):
origin = _event_dict_property("origin")
origin_server_ts = _event_dict_property("origin_server_ts")
prev_events = _event_dict_property("prev_events")
- redacts = _event_dict_property("redacts")
+ redacts = _event_dict_property("redacts", None)
room_id = _event_dict_property("room_id")
sender = _event_dict_property("sender")
user_id = _event_dict_property("sender")
@@ -177,7 +198,7 @@ class EventBase(object):
def is_state(self):
return hasattr(self, "state_key") and self.state_key is not None
- def get_dict(self):
+ def get_dict(self) -> JsonDict:
d = dict(self._event_dict)
d.update({"signatures": self.signatures, "unsigned": dict(self.unsigned)})
@@ -189,7 +210,7 @@ class EventBase(object):
def get_internal_metadata_dict(self):
return self.internal_metadata.get_dict()
- def get_pdu_json(self, time_now=None):
+ def get_pdu_json(self, time_now=None) -> JsonDict:
pdu_json = self.get_dict()
if time_now is not None and "age_ts" in pdu_json["unsigned"]:
|