From 1fd3144a8e655d8201c63be46361a0608daab996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedek=20D=C3=A9v=C3=A9nyi?= Date: Mon, 22 Jul 2024 00:39:10 +0200 Subject: [PATCH] Update python-inject and remove the bundled package (#940) --- com.github.geigi.cozy.json | 14 + cozy/app_controller.py | 2 +- cozy/application_settings.py | 2 +- cozy/control/artwork_cache.py | 2 +- cozy/control/filesystem_monitor.py | 2 +- cozy/control/mpris.py | 2 +- cozy/control/offline_cache.py | 2 +- cozy/ext/__init__.py | 0 cozy/ext/inject/LICENCE | 202 ------- cozy/ext/inject/__init__.py | 512 ------------------ cozy/ext/inject/py.typed | 0 cozy/media/files.py | 2 +- cozy/media/importer.py | 3 +- cozy/media/player.py | 2 +- cozy/model/book.py | 2 +- cozy/model/database_importer.py | 2 +- cozy/model/library.py | 2 +- cozy/model/settings.py | 2 +- cozy/model/track.py | 4 +- cozy/power_manager.py | 2 +- cozy/report/report_to_loki.py | 2 +- cozy/ui/about_window.py | 8 - cozy/ui/app_view.py | 2 +- cozy/ui/book_detail_view.py | 2 +- cozy/ui/delete_book_view.py | 2 +- cozy/ui/file_not_found_dialog.py | 2 +- cozy/ui/headerbar.py | 2 +- cozy/ui/import_failed_dialog.py | 3 +- cozy/ui/library_view.py | 2 +- cozy/ui/main_view.py | 2 +- cozy/ui/media_controller.py | 2 +- cozy/ui/preferences_window.py | 2 +- cozy/ui/search_view.py | 2 +- cozy/ui/toaster.py | 3 +- cozy/ui/widgets/book_card.py | 2 +- cozy/ui/widgets/book_row.py | 2 +- cozy/ui/widgets/error_reporting.py | 2 +- cozy/ui/widgets/playback_speed_popover.py | 2 +- cozy/ui/widgets/sleep_timer.py | 2 +- cozy/ui/widgets/storages.py | 2 +- cozy/view_model/book_detail_view_model.py | 5 +- cozy/view_model/headerbar_view_model.py | 3 +- cozy/view_model/library_view_model.py | 3 +- .../view_model/playback_control_view_model.py | 2 +- cozy/view_model/playback_speed_view_model.py | 3 +- cozy/view_model/search_view_model.py | 2 +- cozy/view_model/settings_view_model.py | 3 +- cozy/view_model/sleep_timer_view_model.py | 3 +- cozy/view_model/storages_view_model.py | 2 +- pyproject.toml | 2 - requirements.txt | 1 + test/cozy/media/test_importer.py | 2 +- test/cozy/media/test_player.py | 4 +- test/cozy/model/storage_block_list.py | 3 +- test/cozy/model/test_book.py | 5 +- test/cozy/model/test_database_importer.py | 3 +- test/cozy/model/test_library.py | 5 +- test/cozy/model/test_settings.py | 3 +- 58 files changed, 78 insertions(+), 785 deletions(-) delete mode 100644 cozy/ext/__init__.py delete mode 100644 cozy/ext/inject/LICENCE delete mode 100644 cozy/ext/inject/__init__.py delete mode 100644 cozy/ext/inject/py.typed diff --git a/com.github.geigi.cozy.json b/com.github.geigi.cozy.json index 6b324bda..d3e36711 100644 --- a/com.github.geigi.cozy.json +++ b/com.github.geigi.cozy.json @@ -107,6 +107,20 @@ } ] }, + { + "name": "python3-inject", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"inject\" --no-build-isolation" + ], + "sources": [ + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/e9/db/3250e21ff08b3466e1ce8d0b2b09edcd6af7672f709d8625e142e824eb0b/inject-5.2.1-py2.py3-none-any.whl", + "sha256": "e40a5b1bebd8a4050b6f98f3396f3de6e9e2e411ad2a2145f16f351cb6f54e51" + } + ] + }, { "name": "blueprint-compiler", "buildsystem": "meson", diff --git a/cozy/app_controller.py b/cozy/app_controller.py index 91296a06..67dfed58 100644 --- a/cozy/app_controller.py +++ b/cozy/app_controller.py @@ -1,7 +1,7 @@ +import inject from gi.repository import Gio from peewee import SqliteDatabase -import cozy.ext.inject as inject from cozy.application_settings import ApplicationSettings from cozy.architecture.singleton import Singleton from cozy.control.db import get_db diff --git a/cozy/application_settings.py b/cozy/application_settings.py index a723ba65..d98123c2 100644 --- a/cozy/application_settings.py +++ b/cozy/application_settings.py @@ -1,7 +1,7 @@ +import inject from gi.repository import Gio from cozy.architecture.event_sender import EventSender -from cozy.ext import inject class ApplicationSettings(EventSender): diff --git a/cozy/control/artwork_cache.py b/cozy/control/artwork_cache.py index 748529ad..61575bdc 100644 --- a/cozy/control/artwork_cache.py +++ b/cozy/control/artwork_cache.py @@ -4,12 +4,12 @@ from pathlib import Path from uuid import uuid4 +import inject from gi.repository import Gdk, GdkPixbuf from cozy.application_settings import ApplicationSettings from cozy.control.application_directories import get_cache_dir from cozy.db.artwork_cache import ArtworkCache as ArtworkCacheModel -from cozy.ext import inject from cozy.media.importer import Importer, ScanStatus from cozy.report import reporter diff --git a/cozy/control/filesystem_monitor.py b/cozy/control/filesystem_monitor.py index c33599ff..259333b4 100644 --- a/cozy/control/filesystem_monitor.py +++ b/cozy/control/filesystem_monitor.py @@ -1,8 +1,8 @@ import logging +import inject from gi.repository import Gio -import cozy.ext.inject as inject from cozy.architecture.event_sender import EventSender from cozy.model.book import Book from cozy.model.settings import Settings diff --git a/cozy/control/mpris.py b/cozy/control/mpris.py index 878110d4..f51836cd 100644 --- a/cozy/control/mpris.py +++ b/cozy/control/mpris.py @@ -12,11 +12,11 @@ import time from dataclasses import dataclass +import inject from gi.repository import Gio, GLib from cozy.application_settings import ApplicationSettings from cozy.control.artwork_cache import ArtworkCache -from cozy.ext import inject from cozy.media.player import Player from cozy.model.book import Book from cozy.report import reporter diff --git a/cozy/control/offline_cache.py b/cozy/control/offline_cache.py index c69e701b..3349b64f 100644 --- a/cozy/control/offline_cache.py +++ b/cozy/control/offline_cache.py @@ -2,6 +2,7 @@ import os import uuid +import inject from gi.repository import Gio import cozy.tools as tools @@ -10,7 +11,6 @@ from cozy.db.file import File from cozy.db.offline_cache import OfflineCache as OfflineCacheModel from cozy.db.track_to_file import TrackToFile -from cozy.ext import inject from cozy.model.book import Book from cozy.model.chapter import Chapter from cozy.report import reporter diff --git a/cozy/ext/__init__.py b/cozy/ext/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/cozy/ext/inject/LICENCE b/cozy/ext/inject/LICENCE deleted file mode 100644 index d6456956..00000000 --- a/cozy/ext/inject/LICENCE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - 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. diff --git a/cozy/ext/inject/__init__.py b/cozy/ext/inject/__init__.py deleted file mode 100644 index 18316e02..00000000 --- a/cozy/ext/inject/__init__.py +++ /dev/null @@ -1,512 +0,0 @@ -""" -Python dependency injection framework. - -Usage: -- Create an optional configuration:: - def my_config(binder): - binder.bind(Cache, RedisCache('localhost:1234')) - binder.bind_to_provider(CurrentUser, get_current_user) - -- Create a shared injector:: - inject.configure(my_config) - -- Use `inject.instance`, `inject.attr` or `inject.param` to inject dependencies:: - class User(object): - cache = inject.attr(Cache) - - @classmethod - def load(cls, id): - return cls.cache.load('user', id) - - def save(self): - self.cache.save(self) - - def foo(bar): - cache = inject.instance(Cache) - cache.save('bar', bar) - - @inject.params(cache=Cache) - def bar(foo, cache=None): - cache.save('foo', foo) - -Binding types: -- Instance bindings configured via `bind(cls, instance) which always return the same instance. -- Constructor bindings `bind_to_constructor(cls, callable)` which create a singleton - on first access. -- Provider bindings `bind_to_provider(cls, callable)` which call the provider - for each injection. -- Runtime bindings which automatically create class singletons. - -Thread-safety: -After configuration the injector is thread-safe and can be safely reused by multiple threads. - -Unit testing: -In tests use `inject.clear_and_configure(callable)` to create a new injector on setup, -and `inject.clear()` to clean-up on tear down. - -Runtime bindings greatly reduce the required configuration by automatically creating singletons -on first access. For example, below only the Config class requires binding configuration, -all other classes are runtime bindings:: - class Cache(object): - config = inject.attr(Config) - - def __init__(self): - self._redis = connect(self.config.redis_address) - - class Db(object): - pass - - class UserRepo(object): - cache = inject.attr(Cache) - db = inject.attr(Db) - - def load(self, user_id): - return cache.load('user', user_id) or db.load('user', user_id) - - class Config(object): - def __init__(self, redis_address): - self.redis_address = redis_address - - def my_config(binder): - binder.bind(Config, load_config_file()) - - inject.configure(my_config) - -""" -__version__ = '4.3.1' -__author__ = 'Ivan Korobkov ' -__license__ = 'Apache License 2.0' -__url__ = 'https://github.com/ivan-korobkov/python-inject' - -import inspect -import logging -import sys -import threading -from functools import wraps -from typing import (Any, Awaitable, Callable, Dict, Generic, Hashable, - Optional, Type, TypeVar, Union, cast, get_type_hints, - overload) - -_NEW_TYPING = sys.version_info[:3] >= (3, 7, 0) # PEP 560 -_RETURN = 'return' - -if _NEW_TYPING: - from typing import ForwardRef, _GenericAlias -else: - from typing import _Union - -logger = logging.getLogger('inject') - -_INJECTOR = None # Shared injector instance. -_INJECTOR_LOCK = threading.RLock() # Guards injector initialization. -_BINDING_LOCK = threading.RLock() # Guards runtime bindings. - -Injectable = Union[object, Any] -T = TypeVar('T', bound=Injectable) -Binding = Union[Type[Injectable], Hashable] -Constructor = Callable[[], Injectable] -Provider = Constructor -BinderCallable = Callable[['Binder'], None] - - -class ConstructorTypeError(TypeError): - def __init__(self, constructor: Callable, previous_error: TypeError): - super(ConstructorTypeError, self).__init__("%s raised an error: %s" % (constructor, previous_error)) - - -class Binder(object): - _bindings: Dict[Binding, Constructor] - - def __init__(self) -> None: - self._bindings = {} - - def install(self, config: BinderCallable) -> 'Binder': - """Install another callable configuration.""" - config(self) - return self - - def bind(self, cls: Binding, instance: T) -> 'Binder': - """Bind a class to an instance.""" - self._check_class(cls) - - b = lambda: instance - self._bindings[cls] = b - self._maybe_bind_forward(cls, b) - - logger.debug('Bound %s to an instance %s', cls, instance) - return self - - def bind_to_constructor(self, cls: Binding, constructor: Constructor) -> 'Binder': - """Bind a class to a callable singleton constructor.""" - self._check_class(cls) - if constructor is None: - raise InjectorException('Constructor cannot be None, key=%s' % cls) - - b = _ConstructorBinding(constructor) - self._bindings[cls] = b - self._maybe_bind_forward(cls, b) - - logger.debug('Bound %s to a constructor %s', cls, constructor) - return self - - def bind_to_provider(self, cls: Binding, provider: Provider) -> 'Binder': - """Bind a class to a callable instance provider executed for each injection.""" - self._check_class(cls) - if provider is None: - raise InjectorException('Provider cannot be None, key=%s' % cls) - - b = provider - self._bindings[cls] = b - self._maybe_bind_forward(cls, b) - - logger.debug('Bound %s to a provider %s', cls, provider) - return self - - def _check_class(self, cls: Binding) -> None: - if cls is None: - raise InjectorException('Binding key cannot be None') - - if cls in self._bindings: - raise InjectorException('Duplicate binding, key=%s' % cls) - - if self._is_forward_str(cls): - ref = ForwardRef(cls) - if ref in self._bindings: - raise InjectorException('Duplicate forward binding, i.e. "int" and int, key=%s', cls) - - def _maybe_bind_forward(self, cls: Binding, binding: Any) -> None: - """Bind a string forward reference.""" - if not _NEW_TYPING: - return - if not isinstance(cls, str): - return - - ref = ForwardRef(cls) - self._bindings[ref] = binding - logger.debug('Bound forward ref "%s"', cls) - - def _is_forward_str(self, cls: Binding) -> bool: - return _NEW_TYPING and isinstance(cls, str) - - -class Injector(object): - _bindings: Dict[Binding, Constructor] - - def __init__(self, config: Optional[BinderCallable] = None, bind_in_runtime: bool = True): - self._bind_in_runtime = bind_in_runtime - if config: - binder = Binder() - config(binder) - self._bindings = binder._bindings - else: - self._bindings = {} - - @overload - def get_instance(self, cls: Type[T]) -> T: - ... - - @overload - def get_instance(self, cls: Hashable) -> Injectable: - ... - - def get_instance(self, cls: Binding) -> Injectable: - """Return an instance for a class.""" - binding = self._bindings.get(cls) - if binding: - return binding() - - # Try to create a runtime binding. - with _BINDING_LOCK: - binding = self._bindings.get(cls) - if binding: - return binding() - - if not self._bind_in_runtime: - raise InjectorException( - 'No binding was found for key=%s' % cls) - - if not callable(cls): - raise InjectorException( - 'Cannot create a runtime binding, the key is not callable, key=%s' % cls) - - try: - instance = cls() - except TypeError as previous_error: - raise ConstructorTypeError(cls, previous_error) - - self._bindings[cls] = lambda: instance - - logger.debug( - 'Created a runtime binding for key=%s, instance=%s', cls, instance) - return instance - - -class InjectorException(Exception): - pass - - -class _ConstructorBinding(Generic[T]): - _instance: Optional[T] - - def __init__(self, constructor: Callable[[], T]) -> None: - self._constructor = constructor - self._created = False - self._instance = None - - def __call__(self) -> T: - if self._created and self._instance is not None: - return self._instance - - with _BINDING_LOCK: - if self._created and self._instance is not None: - return self._instance - self._instance = self._constructor() - self._created = True - return self._instance - - -class _AttributeInjection(object): - def __init__(self, cls: Binding) -> None: - self._cls = cls - - def __get__(self, obj: Any, owner: Any) -> Injectable: - return instance(self._cls) - - -class _ParameterInjection(Generic[T]): - __slots__ = ('_name', '_cls') - - def __init__(self, name: str, cls: Optional[Binding] = None) -> None: - self._name = name - self._cls = cls - - def __call__(self, func: Callable[..., Union[T, Awaitable[T]]]) -> Callable[..., Union[T, Awaitable[T]]]: - if inspect.iscoroutinefunction(func): - @wraps(func) - async def async_injection_wrapper(*args: Any, **kwargs: Any) -> T: - if self._name not in kwargs: - kwargs[self._name] = instance(self._cls or self._name) - async_func = cast(Callable[..., Awaitable[T]], func) - return await async_func(*args, **kwargs) - - return async_injection_wrapper - - @wraps(func) - def injection_wrapper(*args: Any, **kwargs: Any) -> T: - if self._name not in kwargs: - kwargs[self._name] = instance(self._cls or self._name) - sync_func = cast(Callable[..., T], func) - return sync_func(*args, **kwargs) - - return injection_wrapper - - -class _ParametersInjection(Generic[T]): - __slots__ = ('_params',) - - def __init__(self, **kwargs: Any) -> None: - self._params = kwargs - - def __call__(self, func: Callable[..., Union[Awaitable[T], T]]) -> Callable[..., Union[Awaitable[T], T]]: - if sys.version_info.major == 2: - arg_names = inspect.getargspec(func).args - else: - arg_names = inspect.getfullargspec(func).args - params_to_provide = self._params - - if inspect.iscoroutinefunction(func): - @wraps(func) - async def async_injection_wrapper(*args: Any, **kwargs: Any) -> T: - provided_params = frozenset( - arg_names[:len(args)]) | frozenset(kwargs.keys()) - for param, cls in params_to_provide.items(): - if param not in provided_params: - kwargs[param] = instance(cls) - async_func = cast(Callable[..., Awaitable[T]], func) - try: - return await async_func(*args, **kwargs) - except TypeError as previous_error: - raise ConstructorTypeError(func, previous_error) - - return async_injection_wrapper - - @wraps(func) - def injection_wrapper(*args: Any, **kwargs: Any) -> T: - provided_params = frozenset( - arg_names[:len(args)]) | frozenset(kwargs.keys()) - for param, cls in params_to_provide.items(): - if param not in provided_params: - kwargs[param] = instance(cls) - sync_func = cast(Callable[..., T], func) - try: - return sync_func(*args, **kwargs) - except TypeError as previous_error: - raise ConstructorTypeError(func, previous_error) - - return injection_wrapper - - -def configure(config: Optional[BinderCallable] = None, bind_in_runtime: bool = True) -> Injector: - """Create an injector with a callable config or raise an exception when already configured.""" - global _INJECTOR - - with _INJECTOR_LOCK: - if _INJECTOR: - raise InjectorException('Injector is already configured') - - _INJECTOR = Injector(config, bind_in_runtime=bind_in_runtime) - logger.debug('Created and configured an injector, config=%s', config) - return _INJECTOR - - -def configure_once(config: Optional[BinderCallable] = None, bind_in_runtime: bool = True) -> Injector: - """Create an injector with a callable config if not present, otherwise, do nothing.""" - with _INJECTOR_LOCK: - if _INJECTOR: - return _INJECTOR - - return configure(config, bind_in_runtime=bind_in_runtime) - - -def clear_and_configure(config: Optional[BinderCallable] = None, bind_in_runtime: bool = True) -> Injector: - """Clear an existing injector and create another one with a callable config.""" - with _INJECTOR_LOCK: - clear() - return configure(config, bind_in_runtime=bind_in_runtime) - - -def is_configured() -> bool: - """Return true if an injector is already configured.""" - with _INJECTOR_LOCK: - return _INJECTOR is not None - - -def clear() -> None: - """Clear an existing injector if present.""" - global _INJECTOR - - with _INJECTOR_LOCK: - if _INJECTOR is None: - return - - _INJECTOR = None - logger.debug('Cleared an injector') - - -@overload -def instance(cls: Type[T]) -> T: ... - - -@overload -def instance(cls: Hashable) -> Injectable: ... - - -def instance(cls: Binding) -> Injectable: - """Inject an instance of a class.""" - return get_injector_or_die().get_instance(cls) - - -@overload -def attr(cls: Type[T]) -> T: ... - - -@overload -def attr(cls: Hashable) -> Injectable: ... - - -def attr(cls: Binding) -> Injectable: - """Return a attribute injection (descriptor).""" - return _AttributeInjection(cls) - - -def param(name: str, cls: Optional[Binding] = None) -> Callable: - """Deprecated, use @inject.params. Return a decorator which injects an arg into a function.""" - return _ParameterInjection(name, cls) - - -def params(**args_to_classes: Binding) -> Callable: - """Return a decorator which injects args into a function. - - For example:: - - @inject.params(cache=RedisCache, db=DbInterface) - def sign_up(name, email, cache, db): - pass - """ - return _ParametersInjection(**args_to_classes) - - -def autoparams(*selected: str) -> Callable: - """Return a decorator that will inject args into a function using type annotations, Python >= 3.5 only. - - For example:: - - @inject.autoparams() - def refresh_cache(cache: RedisCache, db: DbInterface): - pass - - There is an option to specify which arguments we want to inject without attempts of injecting everything: - - For example:: - - @inject.autoparams('cache', 'db') - def sign_up(name, email, cache: RedisCache, db: DbInterface): - pass - """ - - def autoparams_decorator(fn: Callable[..., T]) -> Callable[..., T]: - if inspect.isclass(fn): - types = get_type_hints(fn.__init__) - else: - types = get_type_hints(fn) - - # Skip the return annotation. - types = {name: typ for name, typ in types.items() if name != _RETURN} - - # Convert Union types into single types, i.e. Union[A, None] => A. - types = {name: _unwrap_union_arg(typ) for name, typ in types.items()} - - # Filter types if selected args present. - if selected: - types = {name: typ for name, typ in types.items() if name in selected} - - wrapper: _ParametersInjection[T] = _ParametersInjection(**types) - return wrapper(fn) - - return autoparams_decorator - - -def get_injector() -> Optional[Injector]: - """Return the current injector or None.""" - return _INJECTOR - - -def get_injector_or_die() -> Injector: - """Return the current injector or raise an InjectorException.""" - injector = _INJECTOR - if not injector: - raise InjectorException('No injector is configured') - - return injector - - -def _unwrap_union_arg(typ): - """Return the first type A in typing.Union[A, B] or typ if not Union.""" - if not _is_union_type(typ): - return typ - return typ.__args__[0] - - -def _is_union_type(typ): - """Test if the type is a union type. Examples:: - is_union_type(int) == False - is_union_type(Union) == True - is_union_type(Union[int, int]) == False - is_union_type(Union[T, int]) == True - - Source: https://github.com/ilevkivskyi/typing_inspect/blob/master/typing_inspect.py - """ - if _NEW_TYPING: - return (typ is Union or - isinstance(typ, _GenericAlias) and typ.__origin__ is Union) - return type(typ) is _Union diff --git a/cozy/ext/inject/py.typed b/cozy/ext/inject/py.typed deleted file mode 100644 index e69de29b..00000000 diff --git a/cozy/media/files.py b/cozy/media/files.py index 0bdb97ed..72f5d125 100644 --- a/cozy/media/files.py +++ b/cozy/media/files.py @@ -2,10 +2,10 @@ import os from pathlib import Path +import inject from gi.repository import Gio from cozy.architecture.event_sender import EventSender -from cozy.ext import inject from cozy.media.importer import Importer from cozy.model.settings import Settings from cozy.report import reporter diff --git a/cozy/media/importer.py b/cozy/media/importer.py index aa20d6cc..920df318 100644 --- a/cozy/media/importer.py +++ b/cozy/media/importer.py @@ -7,10 +7,11 @@ from pathlib import Path from urllib.parse import unquote, urlparse +import inject + from cozy.architecture.event_sender import EventSender from cozy.architecture.profiler import timing from cozy.control.filesystem_monitor import FilesystemMonitor, StorageNotFound -from cozy.ext import inject from cozy.media.media_detector import AudioFileCouldNotBeDiscovered, MediaDetector, NotAnAudioFile from cozy.media.media_file import MediaFile from cozy.model.database_importer import DatabaseImporter diff --git a/cozy/media/player.py b/cozy/media/player.py index be57d7b6..5bec8fb4 100644 --- a/cozy/media/player.py +++ b/cozy/media/player.py @@ -3,12 +3,12 @@ import time from typing import Optional +import inject from gi.repository import GLib, Gst, GstController from cozy.application_settings import ApplicationSettings from cozy.architecture.event_sender import EventSender from cozy.control.offline_cache import OfflineCache -from cozy.ext import inject from cozy.media.importer import Importer, ScanStatus from cozy.model.book import Book from cozy.model.chapter import Chapter diff --git a/cozy/model/book.py b/cozy/model/book.py index 010dd712..44b6c572 100644 --- a/cozy/model/book.py +++ b/cozy/model/book.py @@ -1,6 +1,7 @@ import logging from contextlib import suppress +import inject from peewee import DoesNotExist, SqliteDatabase from cozy.application_settings import ApplicationSettings @@ -10,7 +11,6 @@ from cozy.db.collation import collate_natural from cozy.db.track import Track as TrackModel from cozy.db.track_to_file import TrackToFile -from cozy.ext import inject from cozy.model.chapter import Chapter from cozy.model.settings import Settings from cozy.model.track import Track, TrackInconsistentData diff --git a/cozy/model/database_importer.py b/cozy/model/database_importer.py index ea0edfcf..fbc9ce77 100644 --- a/cozy/model/database_importer.py +++ b/cozy/model/database_importer.py @@ -1,12 +1,12 @@ import logging +import inject from peewee import SqliteDatabase, fn from cozy.db.book import Book as BookModel from cozy.db.file import File from cozy.db.track import Track from cozy.db.track_to_file import TrackToFile -from cozy.ext import inject from cozy.extensions.is_same_book import is_same_book from cozy.media.media_file import MediaFile from cozy.model.book import Book, BookIsEmpty diff --git a/cozy/model/library.py b/cozy/model/library.py index 2abe83ec..01815d12 100644 --- a/cozy/model/library.py +++ b/cozy/model/library.py @@ -1,13 +1,13 @@ import logging from typing import Optional +import inject from peewee import SqliteDatabase from cozy.architecture.event_sender import EventSender from cozy.architecture.profiler import timing from cozy.db.book import Book as BookModel from cozy.db.file import File -from cozy.ext import inject from cozy.extensions.set import split_strings_to_set from cozy.model.book import Book, BookIsEmpty from cozy.model.chapter import Chapter diff --git a/cozy/model/settings.py b/cozy/model/settings.py index 61d50193..36066ae3 100644 --- a/cozy/model/settings.py +++ b/cozy/model/settings.py @@ -1,10 +1,10 @@ import logging from typing import NoReturn +import inject import peewee from peewee import SqliteDatabase -import cozy.ext.inject as inject from cozy.db.book import Book from cozy.db.settings import Settings as SettingsModel from cozy.db.storage import Storage as StorageModel diff --git a/cozy/model/track.py b/cozy/model/track.py index 497fd13a..993b0e4c 100644 --- a/cozy/model/track.py +++ b/cozy/model/track.py @@ -1,15 +1,13 @@ import logging -from peewee import DoesNotExist, SqliteDatabase - from gi.repository import Gst +from peewee import DoesNotExist, SqliteDatabase from cozy.db.file import File from cozy.db.track import Track as TrackModel from cozy.db.track_to_file import TrackToFile from cozy.model.chapter import Chapter - log = logging.getLogger("TrackModel") diff --git a/cozy/power_manager.py b/cozy/power_manager.py index e12b1a66..09ac40d5 100644 --- a/cozy/power_manager.py +++ b/cozy/power_manager.py @@ -1,8 +1,8 @@ import logging +import inject from gi.repository import Gtk -from cozy.ext import inject from cozy.media.player import Player log = logging.getLogger("power_mgr") diff --git a/cozy/report/report_to_loki.py b/cozy/report/report_to_loki.py index 7b57a766..43fdeabd 100644 --- a/cozy/report/report_to_loki.py +++ b/cozy/report/report_to_loki.py @@ -4,6 +4,7 @@ from contextlib import suppress import distro +import inject import pytz import requests from gi.repository import Gtk @@ -12,7 +13,6 @@ from cozy import __version__ as CozyVersion from cozy.application_settings import ApplicationSettings -from cozy.ext import inject from cozy.report.log_level import LogLevel URL = 'https://errors.cozy.sh:3100/api/prom/push' diff --git a/cozy/ui/about_window.py b/cozy/ui/about_window.py index 3d28f804..09da27d9 100644 --- a/cozy/ui/about_window.py +++ b/cozy/ui/about_window.py @@ -43,14 +43,6 @@ def set_extra_credits(self) -> None: ["Fred Warren", "Gabriel", "Hu Mann", "Josiah", "Oleksii Kriukov"], ) self._window.add_acknowledgement_section(_("m4b chapter support in mutagen"), ("mweinelt",)) - self._window.add_acknowledgement_section( - _("Open Source Projects"), - ("Lollypop music player https://gitlab.gnome.org/World/lollypop",), - ) - - self._window.add_legal_section( - "python-inject", "© 2010 Ivan Korobkov", Gtk.License.APACHE_2_0 - ) def present(self, parent: Adw.ApplicationWindow) -> None: self._window.present(parent) diff --git a/cozy/ui/app_view.py b/cozy/ui/app_view.py index 342c7c72..8faac506 100644 --- a/cozy/ui/app_view.py +++ b/cozy/ui/app_view.py @@ -1,6 +1,6 @@ +import inject from gi.repository import Adw, Gtk -from cozy.ext import inject from cozy.view import View from cozy.view_model.app_view_model import AppViewModel diff --git a/cozy/ui/book_detail_view.py b/cozy/ui/book_detail_view.py index 6ef8e0be..627cde68 100644 --- a/cozy/ui/book_detail_view.py +++ b/cozy/ui/book_detail_view.py @@ -5,10 +5,10 @@ from typing import Callable, Final import cairo +import inject from gi.repository import Adw, Gio, GLib, GObject, Graphene, Gtk from cozy.control.artwork_cache import ArtworkCache -from cozy.ext import inject from cozy.model.book import Book from cozy.model.chapter import Chapter from cozy.report import reporter diff --git a/cozy/ui/delete_book_view.py b/cozy/ui/delete_book_view.py index 151e7091..3c340520 100644 --- a/cozy/ui/delete_book_view.py +++ b/cozy/ui/delete_book_view.py @@ -1,6 +1,6 @@ +import inject from gi.repository import Adw, Gtk -from cozy.ext import inject from cozy.model.book import Book from cozy.ui.widgets.book_row import BookRow diff --git a/cozy/ui/file_not_found_dialog.py b/cozy/ui/file_not_found_dialog.py index f11ec2ee..bd746217 100644 --- a/cozy/ui/file_not_found_dialog.py +++ b/cozy/ui/file_not_found_dialog.py @@ -1,8 +1,8 @@ from pathlib import Path +import inject from gi.repository import Adw, Gio, GLib, Gtk -from cozy.ext import inject from cozy.media.importer import Importer from cozy.model.chapter import Chapter diff --git a/cozy/ui/headerbar.py b/cozy/ui/headerbar.py index d7263ecf..38ecff45 100644 --- a/cozy/ui/headerbar.py +++ b/cozy/ui/headerbar.py @@ -1,8 +1,8 @@ import logging +import inject from gi.repository import Adw, GObject, Gtk -from cozy.ext import inject from cozy.ui.widgets.progress_popover import ProgressPopover from cozy.view_model.headerbar_view_model import HeaderBarState, HeaderbarViewModel diff --git a/cozy/ui/import_failed_dialog.py b/cozy/ui/import_failed_dialog.py index 1cbefca5..58a0647f 100644 --- a/cozy/ui/import_failed_dialog.py +++ b/cozy/ui/import_failed_dialog.py @@ -1,9 +1,8 @@ from gettext import gettext as _ +import inject from gi.repository import Adw, Gtk -from cozy.ext import inject - HEADER = _("This can have multiple reasons:") POSSIBILITIES = "\n • ".join(( # yes, it is a hack, because \t would be too wide "", diff --git a/cozy/ui/library_view.py b/cozy/ui/library_view.py index 363c7d90..095c1393 100644 --- a/cozy/ui/library_view.py +++ b/cozy/ui/library_view.py @@ -1,8 +1,8 @@ from typing import Optional +import inject from gi.repository import Adw, Gtk -from cozy.ext import inject from cozy.ui.delete_book_view import DeleteBookView from cozy.ui.widgets.book_card import BookCard from cozy.ui.widgets.filter_list_box import FilterListBox diff --git a/cozy/ui/main_view.py b/cozy/ui/main_view.py index 8229c8d7..7807eaaf 100644 --- a/cozy/ui/main_view.py +++ b/cozy/ui/main_view.py @@ -2,10 +2,10 @@ from threading import Thread from typing import Callable +import inject from gi.repository import Adw, Gdk, Gio, GLib, Gtk import cozy.control.filesystem_monitor as fs_monitor -import cozy.ext.inject as inject import cozy.report.reporter as report from cozy.application_settings import ApplicationSettings from cozy.architecture.event_sender import EventSender diff --git a/cozy/ui/media_controller.py b/cozy/ui/media_controller.py index 5007ba68..b609d60d 100644 --- a/cozy/ui/media_controller.py +++ b/cozy/ui/media_controller.py @@ -1,10 +1,10 @@ import logging +import inject from gi.repository import Adw, Gdk, Gtk from cozy.control.artwork_cache import ArtworkCache from cozy.db.book import Book -from cozy.ext import inject from cozy.ui.widgets.playback_speed_popover import PlaybackSpeedPopover from cozy.ui.widgets.seek_bar import SeekBar from cozy.ui.widgets.sleep_timer import SleepTimer diff --git a/cozy/ui/preferences_window.py b/cozy/ui/preferences_window.py index 3798e39f..6c9bc157 100644 --- a/cozy/ui/preferences_window.py +++ b/cozy/ui/preferences_window.py @@ -1,6 +1,6 @@ +import inject from gi.repository import Adw, Gio, Gtk -from cozy.ext import inject from cozy.ui.widgets.error_reporting import ErrorReporting from cozy.ui.widgets.storages import StorageLocations from cozy.view_model.settings_view_model import SettingsViewModel diff --git a/cozy/ui/search_view.py b/cozy/ui/search_view.py index bfc22b8b..eba2d72d 100644 --- a/cozy/ui/search_view.py +++ b/cozy/ui/search_view.py @@ -2,9 +2,9 @@ from collections.abc import Sequence from typing import Callable +import inject from gi.repository import Adw, Gtk -from cozy.ext import inject from cozy.model.book import Book from cozy.ui.headerbar import Headerbar from cozy.ui.widgets.book_row import BookRow diff --git a/cozy/ui/toaster.py b/cozy/ui/toaster.py index e3c20065..6fb5b00d 100644 --- a/cozy/ui/toaster.py +++ b/cozy/ui/toaster.py @@ -1,7 +1,6 @@ +import inject from gi.repository import Adw, Gtk -from cozy.ext import inject - class ToastNotifier: _builder: Gtk.Builder = inject.attr("MainWindowBuilder") diff --git a/cozy/ui/widgets/book_card.py b/cozy/ui/widgets/book_card.py index d33cf893..9dd47bbd 100644 --- a/cozy/ui/widgets/book_card.py +++ b/cozy/ui/widgets/book_card.py @@ -1,10 +1,10 @@ from math import pi as PI import cairo +import inject from gi.repository import Gdk, Gio, GObject, Graphene, Gtk from cozy.control.artwork_cache import ArtworkCache -from cozy.ext import inject from cozy.model.book import Book ALBUM_ART_SIZE = 200 diff --git a/cozy/ui/widgets/book_row.py b/cozy/ui/widgets/book_row.py index 9b88b338..4b089090 100644 --- a/cozy/ui/widgets/book_row.py +++ b/cozy/ui/widgets/book_row.py @@ -1,9 +1,9 @@ from typing import Callable +import inject from gi.repository import Adw, Gtk from cozy.control.artwork_cache import ArtworkCache -from cozy.ext import inject from cozy.model.book import Book BOOK_ICON_SIZE = 52 diff --git a/cozy/ui/widgets/error_reporting.py b/cozy/ui/widgets/error_reporting.py index 28e37eac..8d48ba63 100644 --- a/cozy/ui/widgets/error_reporting.py +++ b/cozy/ui/widgets/error_reporting.py @@ -1,9 +1,9 @@ from gettext import gettext as _ +import inject from gi.repository import Gtk from cozy.application_settings import ApplicationSettings -from cozy.ext import inject LEVELS = [ _("Disabled"), diff --git a/cozy/ui/widgets/playback_speed_popover.py b/cozy/ui/widgets/playback_speed_popover.py index 2ffa2413..ba7d83ca 100644 --- a/cozy/ui/widgets/playback_speed_popover.py +++ b/cozy/ui/widgets/playback_speed_popover.py @@ -1,6 +1,6 @@ +import inject from gi.repository import Gtk -from cozy.ext import inject from cozy.view_model.playback_speed_view_model import PlaybackSpeedViewModel diff --git a/cozy/ui/widgets/sleep_timer.py b/cozy/ui/widgets/sleep_timer.py index 20f650da..a87e6f79 100644 --- a/cozy/ui/widgets/sleep_timer.py +++ b/cozy/ui/widgets/sleep_timer.py @@ -1,6 +1,6 @@ +import inject from gi.repository import Gtk -from cozy.ext import inject from cozy.view_model.sleep_timer_view_model import SleepTimerViewModel, SystemPowerControl diff --git a/cozy/ui/widgets/storages.py b/cozy/ui/widgets/storages.py index c75aaa15..a5dfd6e4 100644 --- a/cozy/ui/widgets/storages.py +++ b/cozy/ui/widgets/storages.py @@ -1,8 +1,8 @@ from typing import Callable +import inject from gi.repository import Adw, Gio, GLib, GObject, Gtk -from cozy.ext import inject from cozy.model.storage import Storage from cozy.view_model.storages_view_model import StoragesViewModel diff --git a/cozy/view_model/book_detail_view_model.py b/cozy/view_model/book_detail_view_model.py index 81d229dd..0555126b 100644 --- a/cozy/view_model/book_detail_view_model.py +++ b/cozy/view_model/book_detail_view_model.py @@ -1,10 +1,11 @@ -from cozy.control import time_format +import inject + from cozy.application_settings import ApplicationSettings from cozy.architecture.event_sender import EventSender from cozy.architecture.observable import Observable +from cozy.control import time_format from cozy.control.filesystem_monitor import FilesystemMonitor from cozy.control.offline_cache import OfflineCache -from cozy.ext import inject from cozy.media.player import Player from cozy.model.book import Book from cozy.model.chapter import Chapter diff --git a/cozy/view_model/headerbar_view_model.py b/cozy/view_model/headerbar_view_model.py index d40d3789..31efbafc 100644 --- a/cozy/view_model/headerbar_view_model.py +++ b/cozy/view_model/headerbar_view_model.py @@ -1,9 +1,10 @@ from enum import Enum, auto +import inject + from cozy.architecture.event_sender import EventSender from cozy.architecture.observable import Observable from cozy.control.offline_cache import OfflineCache -from cozy.ext import inject from cozy.media.files import Files from cozy.media.importer import Importer, ScanStatus from cozy.model.library import Library diff --git a/cozy/view_model/library_view_model.py b/cozy/view_model/library_view_model.py index 029b8a40..1c7e487e 100644 --- a/cozy/view_model/library_view_model.py +++ b/cozy/view_model/library_view_model.py @@ -3,7 +3,8 @@ from enum import Enum, auto from typing import Optional -import cozy.ext.inject as inject +import inject + from cozy.application_settings import ApplicationSettings from cozy.architecture.event_sender import EventSender from cozy.architecture.observable import Observable diff --git a/cozy/view_model/playback_control_view_model.py b/cozy/view_model/playback_control_view_model.py index c6836f18..fcb76a6e 100644 --- a/cozy/view_model/playback_control_view_model.py +++ b/cozy/view_model/playback_control_view_model.py @@ -1,8 +1,8 @@ +import inject from gi.repository import Gst from cozy.architecture.event_sender import EventSender from cozy.architecture.observable import Observable -from cozy.ext import inject from cozy.media.player import Player from cozy.model.book import Book from cozy.open_view import OpenView diff --git a/cozy/view_model/playback_speed_view_model.py b/cozy/view_model/playback_speed_view_model.py index 0de22a83..adf4b3dd 100644 --- a/cozy/view_model/playback_speed_view_model.py +++ b/cozy/view_model/playback_speed_view_model.py @@ -1,7 +1,8 @@ +import inject + from cozy.architecture.event_sender import EventSender from cozy.architecture.observable import Observable from cozy.db.book import Book -from cozy.ext import inject from cozy.media.player import Player diff --git a/cozy/view_model/search_view_model.py b/cozy/view_model/search_view_model.py index cd8ee70a..f0294e61 100644 --- a/cozy/view_model/search_view_model.py +++ b/cozy/view_model/search_view_model.py @@ -1,8 +1,8 @@ from typing import Callable +import inject from gi.repository import GLib -import cozy.ext.inject as inject from cozy.application_settings import ApplicationSettings from cozy.architecture.event_sender import EventSender from cozy.architecture.observable import Observable diff --git a/cozy/view_model/settings_view_model.py b/cozy/view_model/settings_view_model.py index 0c9ba931..f7cb94f8 100644 --- a/cozy/view_model/settings_view_model.py +++ b/cozy/view_model/settings_view_model.py @@ -1,9 +1,10 @@ import logging +import inject + from cozy.application_settings import ApplicationSettings from cozy.architecture.event_sender import EventSender from cozy.architecture.observable import Observable -from cozy.ext import inject from cozy.media.importer import Importer from cozy.model.settings import Settings diff --git a/cozy/view_model/sleep_timer_view_model.py b/cozy/view_model/sleep_timer_view_model.py index c7f4f87a..787e71f9 100644 --- a/cozy/view_model/sleep_timer_view_model.py +++ b/cozy/view_model/sleep_timer_view_model.py @@ -4,9 +4,10 @@ from enum import Enum, auto from typing import Optional +import inject + from cozy.application_settings import ApplicationSettings from cozy.architecture.observable import Observable -from cozy.ext import inject from cozy.media.player import Player from cozy.tools import IntervalTimer diff --git a/cozy/view_model/storages_view_model.py b/cozy/view_model/storages_view_model.py index ac735bbb..9d297e66 100644 --- a/cozy/view_model/storages_view_model.py +++ b/cozy/view_model/storages_view_model.py @@ -1,13 +1,13 @@ import logging from threading import Thread +import inject from peewee import SqliteDatabase from cozy.application_settings import ApplicationSettings from cozy.architecture.event_sender import EventSender from cozy.architecture.observable import Observable from cozy.control.filesystem_monitor import FilesystemMonitor -from cozy.ext import inject from cozy.media.importer import Importer from cozy.model.library import Library from cozy.model.settings import Settings diff --git a/pyproject.toml b/pyproject.toml index e705a7eb..d305150a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,6 @@ skip-magic-trailing-comma = true line_length = 100 profile = "black" multi_line_output = 3 -skip = ["cozy/ext/inject/"] [tool.ruff] line-length = 100 @@ -16,4 +15,3 @@ output-format = "grouped" [tool.ruff.lint] extend-select = ["B", "SIM", "PIE", "C4", "INT", "LOG"] extend-ignore = ["E402", "E731"] -exclude = ["cozy/ext/inject/*"] diff --git a/requirements.txt b/requirements.txt index 23408ea8..6e360d3f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ mutagen peewee>=3.9.6 pytz requests +inject \ No newline at end of file diff --git a/test/cozy/media/test_importer.py b/test/cozy/media/test_importer.py index dbc2025d..054cc583 100644 --- a/test/cozy/media/test_importer.py +++ b/test/cozy/media/test_importer.py @@ -1,9 +1,9 @@ from unittest.mock import MagicMock, call +import inject import pytest from peewee import SqliteDatabase -from cozy.ext import inject from cozy.media.media_file import MediaFile from cozy.model.library import Library diff --git a/test/cozy/media/test_player.py b/test/cozy/media/test_player.py index 7904f896..49bb2de6 100644 --- a/test/cozy/media/test_player.py +++ b/test/cozy/media/test_player.py @@ -1,10 +1,10 @@ -from unittest.mock import MagicMock, call, PropertyMock +from unittest.mock import MagicMock, PropertyMock, call +import inject import pytest from peewee import SqliteDatabase from cozy.application_settings import ApplicationSettings -from cozy.ext import inject from cozy.media.player import GstPlayer from cozy.model.library import Library from cozy.model.settings import Settings diff --git a/test/cozy/model/storage_block_list.py b/test/cozy/model/storage_block_list.py index 7bbee042..0ccf3f60 100644 --- a/test/cozy/model/storage_block_list.py +++ b/test/cozy/model/storage_block_list.py @@ -1,8 +1,7 @@ +import inject import pytest from peewee import SqliteDatabase -from cozy.ext import inject - @pytest.fixture(autouse=True) def setup_inject(peewee_database_storage): diff --git a/test/cozy/model/test_book.py b/test/cozy/model/test_book.py index b61bd8f9..30a01394 100644 --- a/test/cozy/model/test_book.py +++ b/test/cozy/model/test_book.py @@ -1,9 +1,10 @@ +from test.cozy.mocks import ApplicationSettingsMock + +import inject import pytest from peewee import SqliteDatabase from cozy.application_settings import ApplicationSettings -from cozy.ext import inject -from test.cozy.mocks import ApplicationSettingsMock @pytest.fixture(autouse=True) diff --git a/test/cozy/model/test_database_importer.py b/test/cozy/model/test_database_importer.py index 529c5557..266e38fd 100644 --- a/test/cozy/model/test_database_importer.py +++ b/test/cozy/model/test_database_importer.py @@ -1,8 +1,7 @@ +import inject import pytest from peewee import SqliteDatabase -from cozy.ext import inject - @pytest.fixture(autouse=True) def setup_inject(peewee_database): diff --git a/test/cozy/model/test_library.py b/test/cozy/model/test_library.py index 2fcc0d03..ac22b247 100644 --- a/test/cozy/model/test_library.py +++ b/test/cozy/model/test_library.py @@ -1,11 +1,12 @@ +from test.cozy.mocks import ApplicationSettingsMock + +import inject import pytest from peewee import SqliteDatabase from cozy.application_settings import ApplicationSettings -from cozy.ext import inject from cozy.extensions.set import split_strings_to_set from cozy.model.settings import Settings -from test.cozy.mocks import ApplicationSettingsMock @pytest.fixture(autouse=True) diff --git a/test/cozy/model/test_settings.py b/test/cozy/model/test_settings.py index 7d467973..7f12f065 100644 --- a/test/cozy/model/test_settings.py +++ b/test/cozy/model/test_settings.py @@ -1,6 +1,5 @@ +import inject import pytest - -import cozy.ext.inject as inject from peewee import SqliteDatabase