Skip to content

Commit

Permalink
Refactor ConfigStore to avoid needing to pass config_dir (#114827)
Browse files Browse the repository at this point in the history
Co-authored-by: Erik <[email protected]>
  • Loading branch information
bdraco and emontnemery authored Apr 4, 2024
1 parent 56ef950 commit cceea6d
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 13 deletions.
16 changes: 11 additions & 5 deletions homeassistant/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ def __init__(self, config_dir: str) -> None:
self.services = ServiceRegistry(self)
self.states = StateMachine(self.bus, self.loop)
self.config = Config(self, config_dir)
self.config.async_initialize()
self.components = loader.Components(self)
self.helpers = loader.Helpers(self)
self.state: CoreState = CoreState.not_running
Expand Down Expand Up @@ -2600,12 +2601,12 @@ async def _execute_service(
class Config:
"""Configuration settings for Home Assistant."""

_store: Config._ConfigStore

def __init__(self, hass: HomeAssistant, config_dir: str) -> None:
"""Initialize a new config object."""
self.hass = hass

self._store = self._ConfigStore(self.hass, config_dir)

self.latitude: float = 0
self.longitude: float = 0

Expand Down Expand Up @@ -2656,6 +2657,13 @@ def __init__(self, hass: HomeAssistant, config_dir: str) -> None:
# If Home Assistant is running in safe mode
self.safe_mode: bool = False

def async_initialize(self) -> None:
"""Finish initializing a config object.
This must be called before the config object is used.
"""
self._store = self._ConfigStore(self.hass)

def distance(self, lat: float, lon: float) -> float | None:
"""Calculate distance from Home Assistant.
Expand Down Expand Up @@ -2862,7 +2870,6 @@ async def _async_store(self) -> None:
"country": self.country,
"language": self.language,
}

await self._store.async_save(data)

# Circular dependency prevents us from generating the class at top level
Expand All @@ -2872,7 +2879,7 @@ async def _async_store(self) -> None:
class _ConfigStore(Store[dict[str, Any]]):
"""Class to help storing Config data."""

def __init__(self, hass: HomeAssistant, config_dir: str) -> None:
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize storage class."""
super().__init__(
hass,
Expand All @@ -2881,7 +2888,6 @@ def __init__(self, hass: HomeAssistant, config_dir: str) -> None:
private=True,
atomic_writes=True,
minor_version=CORE_STORAGE_MINOR_VERSION,
config_dir=config_dir,
)
self._original_unit_system: str | None = None # from old store 1.1

Expand Down
13 changes: 5 additions & 8 deletions homeassistant/helpers/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,15 @@ def load_old_config():
return config


def get_internal_store_manager(
hass: HomeAssistant, config_dir: str | None = None
) -> _StoreManager:
def get_internal_store_manager(hass: HomeAssistant) -> _StoreManager:
"""Get the store manager.
This function is not part of the API and should only be
used in the Home Assistant core internals. It is not
guaranteed to be stable.
"""
if STORAGE_MANAGER not in hass.data:
manager = _StoreManager(hass, config_dir or hass.config.config_dir)
manager = _StoreManager(hass)
hass.data[STORAGE_MANAGER] = manager
return hass.data[STORAGE_MANAGER]

Expand All @@ -111,13 +109,13 @@ class _StoreManager:
The store manager is used to cache and manage storage files.
"""

def __init__(self, hass: HomeAssistant, config_dir: str) -> None:
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize storage manager class."""
self._hass = hass
self._invalidated: set[str] = set()
self._files: set[str] | None = None
self._data_preload: dict[str, json_util.JsonValueType] = {}
self._storage_path: Path = Path(config_dir).joinpath(STORAGE_DIR)
self._storage_path: Path = Path(hass.config.config_dir).joinpath(STORAGE_DIR)
self._cancel_cleanup: asyncio.TimerHandle | None = None

async def async_initialize(self) -> None:
Expand Down Expand Up @@ -246,7 +244,6 @@ def __init__(
encoder: type[JSONEncoder] | None = None,
minor_version: int = 1,
read_only: bool = False,
config_dir: str | None = None,
) -> None:
"""Initialize storage class."""
self.version = version
Expand All @@ -263,7 +260,7 @@ def __init__(
self._atomic_writes = atomic_writes
self._read_only = read_only
self._next_write_time = 0.0
self._manager = get_internal_store_manager(hass, config_dir)
self._manager = get_internal_store_manager(hass)

@cached_property
def path(self):
Expand Down
3 changes: 3 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2288,6 +2288,7 @@ async def test_additional_data_in_core_config(
) -> None:
"""Test that we can handle additional data in core configuration."""
config = ha.Config(hass, "/test/ha-config")
config.async_initialize()
hass_storage[ha.CORE_STORAGE_KEY] = {
"version": 1,
"data": {"location_name": "Test Name", "additional_valid_key": "value"},
Expand All @@ -2301,6 +2302,7 @@ async def test_incorrect_internal_external_url(
) -> None:
"""Test that we warn when detecting invalid internal/external url."""
config = ha.Config(hass, "/test/ha-config")
config.async_initialize()

hass_storage[ha.CORE_STORAGE_KEY] = {
"version": 1,
Expand All @@ -2314,6 +2316,7 @@ async def test_incorrect_internal_external_url(
assert "Invalid internal_url set" not in caplog.text

config = ha.Config(hass, "/test/ha-config")
config.async_initialize()

hass_storage[ha.CORE_STORAGE_KEY] = {
"version": 1,
Expand Down

0 comments on commit cceea6d

Please sign in to comment.