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

Add Module API for reading and writing global account data. #12391

Merged
merged 12 commits into from
Apr 11, 2022
Prev Previous commit
Next Next commit
Freeze rather than just clone
  • Loading branch information
reivilibre committed Apr 8, 2022
commit a9c4457fb92f5be3b90b53f6f124e5a13871a3cd
8 changes: 4 additions & 4 deletions synapse/module_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
# 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 copy
import email.utils
import logging
from typing import (
Expand Down Expand Up @@ -120,6 +119,7 @@
from synapse.util import Clock
from synapse.util.async_helpers import maybe_awaitable
from synapse.util.caches.descriptors import cached
from synapse.util.frozenutils import freeze

if TYPE_CHECKING:
from synapse.app.generic_worker import GenericWorkerSlavedStore
Expand Down Expand Up @@ -1432,9 +1432,9 @@ async def get_global(self, user_id: str, data_type: str) -> Optional[JsonDict]:
data = await self._store.get_global_account_data_by_type_for_user(
user_id, data_type
)
# We clone to prevent the module accidentally mutating the dict that
# lives in the cache, as that could introduce nasty bugs.
return copy.deepcopy(data)
# We clone and freeze to prevent the module accidentally mutating the
# dict that lives in the cache, as that could introduce nasty bugs.
return freeze(data)

async def put_global(
self, user_id: str, data_type: str, new_data: JsonDict
Expand Down
26 changes: 4 additions & 22 deletions tests/module_api/test_account_data_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,31 +85,13 @@ def test_get_global_no_mutability(self) -> None:
)
)

# Request that account data from the normal store; check it's as we expect.
self.assertEqual(
self.get_success(
self._store.get_global_account_data_by_type_for_user(
self.user_id, "test.data"
)
),
{"wombat": True},
)

# Now, as a module, request that data and then mutate it (out of negligence or otherwise).
# Now request that data and then mutate it (out of negligence or otherwise).
the_data = self.get_success(
self._account_data_mgr.get_global(self.user_id, "test.data")
)
the_data["wombat"] = False

# As Synapse, request that account data once more from the normal store; check it's as we expect.
self.assertEqual(
self.get_success(
self._store.get_global_account_data_by_type_for_user(
self.user_id, "test.data"
)
),
{"wombat": True},
)
with self.assertRaises(TypeError):
# This throws an exception because it's a frozen dict.
the_data["wombat"] = False

def test_put_global(self) -> None:
"""
Expand Down