Skip to content

Commit f4041bb

Browse files
committed
Remove Thing.application_config and move deepcopy to ThingServerInterface.
This keeps the application config as a server property, which I think is clearer. Also, we now deep copy it every time it's needed, rather than in `Thing.__init__`. It may be nice in the future to swap deepcopy for some kind of freezing method, but that's for a future PR, and probably not worth an issue.
1 parent ce87e19 commit f4041bb

3 files changed

Lines changed: 7 additions & 10 deletions

File tree

src/labthings_fastapi/thing.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from typing import TYPE_CHECKING, Any, Optional
1010
from typing_extensions import Self
1111
from collections.abc import Mapping
12-
from copy import deepcopy
1312
import logging
1413
import os
1514
import json
@@ -83,8 +82,6 @@ class Thing:
8382
_thing_server_interface: ThingServerInterface
8483
"""Provide access to features of the server that this `.Thing` is attached to."""
8584

86-
application_config: Mapping[str, Any] | None
87-
8885
def __init__(self, thing_server_interface: ThingServerInterface) -> None:
8986
"""Initialise a Thing.
9087
@@ -101,9 +98,6 @@ def __init__(self, thing_server_interface: ThingServerInterface) -> None:
10198
`.create_thing_without_server` which generates a mock interface.
10299
"""
103100
self._thing_server_interface = thing_server_interface
104-
# Create a deepcopy of the configuration so if one Thing mutates the config
105-
# it cannot propagate.
106-
self.application_config = deepcopy(thing_server_interface.application_config)
107101
self._disable_saving_settings: bool = False
108102

109103
@property

src/labthings_fastapi/thing_server_interface.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44
from concurrent.futures import Future
5+
from copy import deepcopy
56
import os
67
from typing import (
78
TYPE_CHECKING,
@@ -159,7 +160,7 @@ def path(self) -> str:
159160
@property
160161
def application_config(self) -> Mapping[str, Any] | None:
161162
"""The custom application configuration options from configuration."""
162-
return self._get_server().application_config
163+
return deepcopy(self._get_server().application_config)
163164

164165
def get_thing_states(self) -> Mapping[str, Any]:
165166
"""Retrieve metadata from all Things on the server.

tests/test_thing.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ def test_thing_can_access_application_config():
2727
thing2 = server.things["thing2"]
2828

2929
# Check both Things can access the application config
30-
assert thing1.application_config == {"foo": "bar", "mock": True}
31-
assert thing1.application_config == thing2.application_config
30+
thing1_config = thing1._thing_server_interface.application_config
31+
thing2_config = thing2._thing_server_interface.application_config
32+
assert thing1_config == {"foo": "bar", "mock": True}
33+
assert thing1_config == thing2_config
3234
# But that they are not the same dictionary, preventing mutations affecting
3335
# behaviour of another thing.
34-
assert thing1.application_config is not thing2.application_config
36+
assert thing1_config is not thing2_config

0 commit comments

Comments
 (0)