diff --git a/src/ahriman/core/__init__.py b/src/ahriman/core/__init__.py index 53d4d036..5e72ecec 100644 --- a/src/ahriman/core/__init__.py +++ b/src/ahriman/core/__init__.py @@ -38,12 +38,12 @@ class _Context: """ self._content: dict[str, Any] = {} - def get(self, key: ContextKey[T]) -> T: + def get(self, key: ContextKey[T] | type[T]) -> T: """ get value for the specified key Args: - key(ContextKey[T]): context key name + key(ContextKey[T] | type[T]): context key name Returns: T: value associated with the key @@ -52,29 +52,37 @@ class _Context: KeyError: in case if the specified context variable was not found ValueError: in case if type of value is not an instance of specified return type """ + if not isinstance(key, ContextKey): + key = ContextKey.from_type(key) + if key.key not in self._content: raise KeyError(key.key) value = self._content[key.key] if not isinstance(value, key.return_type): raise ValueError(f"Value {value} is not an instance of {key.return_type}") + return value - def set(self, key: ContextKey[T], value: T) -> None: + def set(self, key: ContextKey[T] | type[T], value: T) -> None: """ set value for the specified key Args: - key(ContextKey[T]): context key name + key(ContextKey[T] | type[T]): context key name value(T): context value associated with the specified key Raises: KeyError: in case if the specified context variable already exists ValueError: in case if type of value is not an instance of specified return type """ + if not isinstance(key, ContextKey): + key = ContextKey.from_type(key) + if key.key in self._content: raise KeyError(key.key) if not isinstance(value, key.return_type): raise ValueError(f"Value {value} is not an instance of {key.return_type}") + self._content[key.key] = value def __iter__(self) -> Iterator[str]: diff --git a/src/ahriman/core/gitremote/remote_push_trigger.py b/src/ahriman/core/gitremote/remote_push_trigger.py index 5114ea4a..44aa9166 100644 --- a/src/ahriman/core/gitremote/remote_push_trigger.py +++ b/src/ahriman/core/gitremote/remote_push_trigger.py @@ -22,7 +22,6 @@ from ahriman.core.configuration import Configuration from ahriman.core.database import SQLite from ahriman.core.gitremote.remote_push import RemotePush from ahriman.core.triggers import Trigger -from ahriman.models.context_key import ContextKey from ahriman.models.package import Package from ahriman.models.repository_id import RepositoryId from ahriman.models.result import Result @@ -111,7 +110,7 @@ class RemotePushTrigger(Trigger): GitRemoteError: if database is not set in context """ ctx = context.get() - database = ctx.get(ContextKey("database", SQLite)) + database = ctx.get(SQLite) for target in self.targets: section, _ = self.configuration.gettype( diff --git a/src/ahriman/core/repository/repository.py b/src/ahriman/core/repository/repository.py index 9fe6936b..f9c97907 100644 --- a/src/ahriman/core/repository/repository.py +++ b/src/ahriman/core/repository/repository.py @@ -26,7 +26,6 @@ from ahriman.core.database import SQLite from ahriman.core.repository.executor import Executor from ahriman.core.repository.update_handler import UpdateHandler from ahriman.core.sign.gpg import GPG -from ahriman.models.context_key import ContextKey from ahriman.models.pacman_synchronization import PacmanSynchronization from ahriman.models.repository_id import RepositoryId @@ -89,11 +88,11 @@ class Repository(Executor, UpdateHandler): # directly without loader ctx = _Context() - ctx.set(ContextKey("database", SQLite), self.database) - ctx.set(ContextKey("configuration", Configuration), self.configuration) - ctx.set(ContextKey("pacman", Pacman), self.pacman) - ctx.set(ContextKey("sign", GPG), self.sign) + ctx.set(SQLite, self.database) + ctx.set(Configuration, self.configuration) + ctx.set(Pacman, self.pacman) + ctx.set(GPG, self.sign) - ctx.set(ContextKey("repository", type(self)), self) + ctx.set(type(self), self) context.set(ctx) diff --git a/src/ahriman/core/support/keyring_trigger.py b/src/ahriman/core/support/keyring_trigger.py index 5fad5b2a..cbe24694 100644 --- a/src/ahriman/core/support/keyring_trigger.py +++ b/src/ahriman/core/support/keyring_trigger.py @@ -24,7 +24,6 @@ from ahriman.core.sign.gpg import GPG from ahriman.core.support.package_creator import PackageCreator from ahriman.core.support.pkgbuild.keyring_generator import KeyringGenerator from ahriman.core.triggers import Trigger -from ahriman.models.context_key import ContextKey from ahriman.models.repository_id import RepositoryId @@ -134,8 +133,8 @@ class KeyringTrigger(Trigger): trigger action which will be called at the start of the application """ ctx = context.get() - sign = ctx.get(ContextKey("sign", GPG)) - database = ctx.get(ContextKey("database", SQLite)) + sign = ctx.get(GPG) + database = ctx.get(SQLite) for target in self.targets: generator = KeyringGenerator(database, sign, self.repository_id, self.configuration, target) diff --git a/src/ahriman/core/support/package_creator.py b/src/ahriman/core/support/package_creator.py index a95cbcba..d33248ca 100644 --- a/src/ahriman/core/support/package_creator.py +++ b/src/ahriman/core/support/package_creator.py @@ -25,7 +25,6 @@ from ahriman.core.configuration import Configuration from ahriman.core.database import SQLite from ahriman.core.support.pkgbuild.pkgbuild_generator import PkgbuildGenerator from ahriman.models.build_status import BuildStatus -from ahriman.models.context_key import ContextKey from ahriman.models.package import Package @@ -65,7 +64,7 @@ class PackageCreator: # register package ctx = context.get() - database: SQLite = ctx.get(ContextKey("database", SQLite)) + database = ctx.get(SQLite) _, repository_id = self.configuration.check_loaded() package = Package.from_build(local_path, repository_id.architecture, None) database.package_update(package, BuildStatus()) diff --git a/src/ahriman/models/context_key.py b/src/ahriman/models/context_key.py index 4e1af459..ec46c67f 100644 --- a/src/ahriman/models/context_key.py +++ b/src/ahriman/models/context_key.py @@ -18,7 +18,7 @@ # along with this program. If not, see . # from dataclasses import dataclass -from typing import Generic, TypeVar +from typing import Generic, Self, TypeVar T = TypeVar("T") @@ -35,3 +35,16 @@ class ContextKey(Generic[T]): """ key: str return_type: type[T] + + @classmethod + def from_type(cls, return_type: type[T]) -> Self: + """ + construct key from type + + Args: + return_type(type[T]): return type used for the specified context key + + Returns: + Self: context key with autogenerated + """ + return cls(return_type.__name__, return_type) diff --git a/tests/ahriman/core/gitremote/test_remote_push_trigger.py b/tests/ahriman/core/gitremote/test_remote_push_trigger.py index bfe35173..d0458397 100644 --- a/tests/ahriman/core/gitremote/test_remote_push_trigger.py +++ b/tests/ahriman/core/gitremote/test_remote_push_trigger.py @@ -3,7 +3,6 @@ from pytest_mock import MockerFixture from ahriman.core.configuration import Configuration from ahriman.core.database import SQLite from ahriman.core.gitremote import RemotePushTrigger -from ahriman.models.context_key import ContextKey from ahriman.models.package import Package from ahriman.models.result import Result @@ -30,5 +29,5 @@ def test_on_result(configuration: Configuration, result: Result, package_ahriman trigger = RemotePushTrigger(repository_id, configuration) trigger.on_result(result, [package_ahriman]) - database_mock.assert_called_once_with(ContextKey("database", SQLite)) + database_mock.assert_called_once_with(SQLite) run_mock.assert_called_once_with(result) diff --git a/tests/ahriman/core/repository/test_repository.py b/tests/ahriman/core/repository/test_repository.py index 654f89d9..0983c1fd 100644 --- a/tests/ahriman/core/repository/test_repository.py +++ b/tests/ahriman/core/repository/test_repository.py @@ -6,7 +6,6 @@ from ahriman.core.configuration import Configuration from ahriman.core.database import SQLite from ahriman.core.repository import Repository from ahriman.core.sign.gpg import GPG -from ahriman.models.context_key import ContextKey def test_load(configuration: Configuration, database: SQLite, mocker: MockerFixture) -> None: @@ -29,9 +28,9 @@ def test_set_context(configuration: Configuration, database: SQLite, mocker: Moc instance = Repository.load(repository_id, configuration, database, report=False) set_mock.assert_has_calls([ - MockCall(ContextKey("database", SQLite), instance.database), - MockCall(ContextKey("configuration", Configuration), instance.configuration), - MockCall(ContextKey("pacman", Pacman), instance.pacman), - MockCall(ContextKey("sign", GPG), instance.sign), - MockCall(ContextKey("repository", Repository), instance), + MockCall(SQLite, instance.database), + MockCall(Configuration, instance.configuration), + MockCall(Pacman, instance.pacman), + MockCall(GPG, instance.sign), + MockCall(Repository, instance), ]) diff --git a/tests/ahriman/core/support/test_keyring_trigger.py b/tests/ahriman/core/support/test_keyring_trigger.py index bcc2fbfa..13631858 100644 --- a/tests/ahriman/core/support/test_keyring_trigger.py +++ b/tests/ahriman/core/support/test_keyring_trigger.py @@ -5,7 +5,6 @@ from ahriman.core.configuration import Configuration from ahriman.core.database import SQLite from ahriman.core.sign.gpg import GPG from ahriman.core.support import KeyringTrigger -from ahriman.models.context_key import ContextKey def test_configuration_sections(configuration: Configuration) -> None: @@ -29,5 +28,5 @@ def test_on_start(configuration: Configuration, mocker: MockerFixture) -> None: trigger = KeyringTrigger(repository_id, configuration) trigger.on_start() - context_mock.assert_has_calls([MockCall(ContextKey("sign", GPG)), MockCall(ContextKey("database", SQLite))]) + context_mock.assert_has_calls([MockCall(GPG), MockCall(SQLite)]) run_mock.assert_called_once_with() diff --git a/tests/ahriman/core/support/test_package_creator.py b/tests/ahriman/core/support/test_package_creator.py index 61ae71d5..acb32316 100644 --- a/tests/ahriman/core/support/test_package_creator.py +++ b/tests/ahriman/core/support/test_package_creator.py @@ -4,7 +4,6 @@ from pytest_mock import MockerFixture from ahriman.core.database import SQLite from ahriman.core.support.package_creator import PackageCreator -from ahriman.models.context_key import ContextKey from ahriman.models.package import Package from ahriman.models.package_description import PackageDescription from ahriman.models.package_source import PackageSource @@ -38,5 +37,5 @@ def test_run(package_creator: PackageCreator, database: SQLite, mocker: MockerFi init_mock.assert_called_once_with(local_path) package_mock.assert_called_once_with(local_path, "x86_64", None) - database_mock.assert_called_once_with(ContextKey("database", SQLite)) + database_mock.assert_called_once_with(SQLite) insert_mock.assert_called_once_with(package, pytest.helpers.anyvar(int)) diff --git a/tests/ahriman/core/test_context_init.py b/tests/ahriman/core/test_context_init.py index ba4425f2..e7791d91 100644 --- a/tests/ahriman/core/test_context_init.py +++ b/tests/ahriman/core/test_context_init.py @@ -15,6 +15,18 @@ def test_get_set() -> None: assert ctx.get(key) == value +def test_get_set_type() -> None: + """ + must set and get variable by type + """ + key, value = int, 42 + ctx = _Context() + + ctx.set(key, value) + assert ctx.get(key) == value + assert ctx.get(ContextKey.from_type(int)) == value + + def test_get_key_exception() -> None: """ must raise KeyError in case if key was not found diff --git a/tests/ahriman/models/test_context_key.py b/tests/ahriman/models/test_context_key.py index e69de29b..555928c4 100644 --- a/tests/ahriman/models/test_context_key.py +++ b/tests/ahriman/models/test_context_key.py @@ -0,0 +1,9 @@ +from ahriman.models.context_key import ContextKey + + +def test_from_type() -> None: + """ + must construct key from type + """ + assert ContextKey.from_type(int) == ContextKey("int", int) + assert ContextKey.from_type(ContextKey) == ContextKey("ContextKey", ContextKey)