From: Manuel Traut <manut@mecka.net>
Date: Fri, 10 May 2024 07:31:35 +0000
Subject: Use inject from Debian package

Signed-off-by: Manuel Traut <manut@mecka.net>
---
 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                    | 513 -------------------------
 cozy/ext/inject/py.typed                       |   0
 cozy/media/files.py                            |   2 +-
 cozy/media/importer.py                         |   2 +-
 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/power_manager.py                          |   2 +-
 cozy/report/report_to_loki.py                  |   2 +-
 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                           |   4 +-
 cozy/ui/import_failed_dialog.py                |   2 +-
 cozy/ui/library_view.py                        |   2 +-
 cozy/ui/main_view.py                           |   3 +-
 cozy/ui/media_controller.py                    |   2 +-
 cozy/ui/preferences_view.py                    |   2 +-
 cozy/ui/search_view.py                         |   2 +-
 cozy/ui/toaster.py                             |   2 +-
 cozy/ui/widgets/album_element.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      |   2 +-
 cozy/view_model/headerbar_view_model.py        |   2 +-
 cozy/view_model/library_view_model.py          |   2 +-
 cozy/view_model/playback_control_view_model.py |   2 +-
 cozy/view_model/playback_speed_view_model.py   |   2 +-
 cozy/view_model/search_view_model.py           |   2 +-
 cozy/view_model/settings_view_model.py         |   2 +-
 cozy/view_model/sleep_timer_view_model.py      |   2 +-
 cozy/view_model/storages_view_model.py         |   2 +-
 test/cozy/media/test_importer.py               |   2 +-
 test/cozy/media/test_player.py                 |   2 +-
 test/cozy/model/storage_block_list.py          |   2 +-
 test/cozy/model/test_book.py                   |   2 +-
 test/cozy/model/test_database_importer.py      |   2 +-
 test/cozy/model/test_library.py                |   2 +-
 52 files changed, 49 insertions(+), 765 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/cozy/app_controller.py b/cozy/app_controller.py
index 6d94e95..becf350 100644
--- a/cozy/app_controller.py
+++ b/cozy/app_controller.py
@@ -1,6 +1,6 @@
 from gi.repository import Gio
 
-import cozy.ext.inject as inject
+import inject
 from peewee import SqliteDatabase
 
 from cozy.control.offline_cache import OfflineCache
diff --git a/cozy/application_settings.py b/cozy/application_settings.py
index 8a4cbe6..9dc7cf0 100644
--- a/cozy/application_settings.py
+++ b/cozy/application_settings.py
@@ -1,7 +1,7 @@
 from gi.repository import Gio
 
 from cozy.architecture.event_sender import EventSender
-from cozy.ext import inject
+import inject
 
 
 class ApplicationSettings(EventSender):
diff --git a/cozy/control/artwork_cache.py b/cozy/control/artwork_cache.py
index 85b1ac1..3c4b7e3 100644
--- a/cozy/control/artwork_cache.py
+++ b/cozy/control/artwork_cache.py
@@ -7,7 +7,7 @@ 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
+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 9b21245..1fe7e2e 100644
--- a/cozy/control/filesystem_monitor.py
+++ b/cozy/control/filesystem_monitor.py
@@ -1,7 +1,7 @@
 import logging
 from typing import List
 
-import cozy.ext.inject as inject
+import inject
 from gi.repository import Gio
 
 from cozy.architecture.event_sender import EventSender
diff --git a/cozy/control/mpris.py b/cozy/control/mpris.py
index da206fa..96b7771 100644
--- a/cozy/control/mpris.py
+++ b/cozy/control/mpris.py
@@ -16,7 +16,7 @@ from gi.repository import Gio, GLib
 
 from cozy.application_settings import ApplicationSettings
 from cozy.control.artwork_cache import ArtworkCache
-from cozy.ext import inject
+import inject
 from cozy.media.player import NS_TO_SEC, US_TO_SEC, 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 2b378f3..9ce94c5 100644
--- a/cozy/control/offline_cache.py
+++ b/cozy/control/offline_cache.py
@@ -13,7 +13,7 @@ from gi.repository import Gio
 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
+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 e69de29..0000000
diff --git a/cozy/ext/inject/LICENCE b/cozy/ext/inject/LICENCE
deleted file mode 100644
index d645695..0000000
--- 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 f3a77da..0000000
--- a/cozy/ext/inject/__init__.py
+++ /dev/null
@@ -1,513 +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 <ivan.korobkov@gmail.com>'
-__license__ = 'Apache License 2.0'
-__url__ = 'https://github.com/ivan-korobkov/python-inject'
-
-import inspect
-import logging
-import sys
-import threading
-import types
-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 e69de29..0000000
diff --git a/cozy/media/files.py b/cozy/media/files.py
index c4d9092..6b0fae8 100644
--- a/cozy/media/files.py
+++ b/cozy/media/files.py
@@ -6,7 +6,7 @@ from pathlib import Path
 from gi.repository import Gio
 
 from cozy.architecture.event_sender import EventSender
-from cozy.ext import inject
+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 0009d8c..1ff308d 100644
--- a/cozy/media/importer.py
+++ b/cozy/media/importer.py
@@ -10,7 +10,7 @@ from urllib.parse import urlparse, unquote
 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
+import inject
 from cozy.media.media_detector import MediaDetector, NotAnAudioFile, AudioFileCouldNotBeDiscovered
 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 795ce38..cb7a19f 100644
--- a/cozy/media/player.py
+++ b/cozy/media/player.py
@@ -10,7 +10,7 @@ from gi.repository import GLib, Gst
 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
+import inject
 from cozy.media.gst_player import GstPlayer, GstPlayerState
 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 a5b6277..e964258 100644
--- a/cozy/model/book.py
+++ b/cozy/model/book.py
@@ -11,7 +11,7 @@ from cozy.db.collation import collate_natural
 from cozy.db.book import Book as BookModel
 from cozy.db.track import Track as TrackModel
 from cozy.db.track_to_file import TrackToFile
-from cozy.ext import inject
+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 29aa10d..57a3249 100644
--- a/cozy/model/database_importer.py
+++ b/cozy/model/database_importer.py
@@ -7,7 +7,7 @@ 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
+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 d377dec..8971b48 100644
--- a/cozy/model/library.py
+++ b/cozy/model/library.py
@@ -7,7 +7,7 @@ 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
+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 61d5019..d85f2e6 100644
--- a/cozy/model/settings.py
+++ b/cozy/model/settings.py
@@ -4,7 +4,7 @@ from typing import NoReturn
 import peewee
 from peewee import SqliteDatabase
 
-import cozy.ext.inject as inject
+import 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/power_manager.py b/cozy/power_manager.py
index e12b1a6..eeb36dd 100644
--- a/cozy/power_manager.py
+++ b/cozy/power_manager.py
@@ -2,7 +2,7 @@ import logging
 
 from gi.repository import Gtk
 
-from cozy.ext import inject
+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 6720a10..f9ec514 100644
--- a/cozy/report/report_to_loki.py
+++ b/cozy/report/report_to_loki.py
@@ -7,7 +7,7 @@ import distro
 import platform
 
 from cozy.application_settings import ApplicationSettings
-from cozy.ext import inject
+import inject
 from cozy.report.log_level import LogLevel
 from cozy.version import __version__ as CozyVersion
 from peewee import __version__ as PeeweeVersion
diff --git a/cozy/ui/app_view.py b/cozy/ui/app_view.py
index 09d5ca8..3a8f627 100644
--- a/cozy/ui/app_view.py
+++ b/cozy/ui/app_view.py
@@ -1,6 +1,6 @@
 from gi.repository import Gtk, Adw
 
-from cozy.ext import inject
+import inject
 from cozy.view_model.app_view_model import AppViewModel
 from cozy.view import View
 
diff --git a/cozy/ui/book_detail_view.py b/cozy/ui/book_detail_view.py
index 3a25271..e75311c 100644
--- a/cozy/ui/book_detail_view.py
+++ b/cozy/ui/book_detail_view.py
@@ -6,7 +6,7 @@ from typing import Optional, Callable
 import gi
 
 from cozy.control.artwork_cache import ArtworkCache
-from cozy.ext import inject
+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 7271cc3..7bc5cb0 100644
--- a/cozy/ui/delete_book_view.py
+++ b/cozy/ui/delete_book_view.py
@@ -1,6 +1,6 @@
 from gi.repository import Adw, Gtk
 
-from cozy.ext import inject
+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 4beba83..cdd437a 100644
--- a/cozy/ui/file_not_found_dialog.py
+++ b/cozy/ui/file_not_found_dialog.py
@@ -2,7 +2,7 @@ from pathlib import Path
 
 from gi.repository import Adw, Gio, GLib, Gtk
 
-from cozy.ext import inject
+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 48c8efa..4f99ad4 100644
--- a/cozy/ui/headerbar.py
+++ b/cozy/ui/headerbar.py
@@ -2,13 +2,13 @@ import logging
 
 import gi
 
-from cozy.ext import inject
+import inject
 from cozy.ui.widgets.progress_popover import ProgressPopover
 from cozy.view_model.headerbar_view_model import HeaderbarViewModel, HeaderBarState
 
 from gi.repository import Adw, Gtk, GObject
 
-from cozy.ext import inject
+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 7b98fa8..b3da136 100644
--- a/cozy/ui/import_failed_dialog.py
+++ b/cozy/ui/import_failed_dialog.py
@@ -2,7 +2,7 @@ from gettext import gettext as _
 
 from gi.repository import Adw, Gtk
 
-from cozy.ext import inject
+import inject
 
 
 HEADER = _("This can have multiple reasons:")
diff --git a/cozy/ui/library_view.py b/cozy/ui/library_view.py
index 59eb2ea..ce6b1f7 100644
--- a/cozy/ui/library_view.py
+++ b/cozy/ui/library_view.py
@@ -3,7 +3,7 @@ from typing import Optional
 
 from gi.repository import Adw, Gtk
 
-from cozy.ext import inject
+import inject
 from cozy.ui.widgets.book_element import BookElement
 from cozy.ui.delete_book_view import DeleteBookView
 from cozy.ui.widgets.filter_list_box import FilterListBox
diff --git a/cozy/ui/main_view.py b/cozy/ui/main_view.py
index a7f6780..0e5bae1 100644
--- a/cozy/ui/main_view.py
+++ b/cozy/ui/main_view.py
@@ -7,7 +7,7 @@ from typing import Callable
 from gi.repository import Adw, Gdk, Gio, GLib, Gtk
 
 import cozy.control.filesystem_monitor as fs_monitor
-import cozy.ext.inject as inject
+import inject
 import cozy.report.reporter as report
 from cozy.application_settings import ApplicationSettings
 from cozy.architecture.event_sender import EventSender
@@ -209,7 +209,6 @@ class CozyUI(EventSender, metaclass=Singleton):
 
         # Translators: Replace "translator-credits" with your names, one name per line
         about.set_translator_credits(_("translator-credits"))
-        about.add_legal_section("python-inject", "© 2010 Ivan Korobkov", Gtk.License.APACHE_2_0)
 
         about.set_transient_for(self.window)
         about.present()
diff --git a/cozy/ui/media_controller.py b/cozy/ui/media_controller.py
index ae0c64b..c6bbd7d 100644
--- a/cozy/ui/media_controller.py
+++ b/cozy/ui/media_controller.py
@@ -4,7 +4,7 @@ import gi
 
 from cozy.control.artwork_cache import ArtworkCache
 from cozy.db.book import Book
-from cozy.ext import inject
+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_view.py b/cozy/ui/preferences_view.py
index decca8f..34c7577 100644
--- a/cozy/ui/preferences_view.py
+++ b/cozy/ui/preferences_view.py
@@ -1,7 +1,7 @@
 from typing import Any
 from gi.repository import Adw, Gio, Gtk
 
-from cozy.ext import inject
+import inject
 from cozy.ui.widgets.error_reporting import ErrorReporting
 
 from cozy.ui.widgets.storages import StorageLocations
diff --git a/cozy/ui/search_view.py b/cozy/ui/search_view.py
index c83d2b4..6c22fe7 100644
--- a/cozy/ui/search_view.py
+++ b/cozy/ui/search_view.py
@@ -3,7 +3,7 @@ from typing import Callable, Sequence
 
 from gi.repository import Adw, Gtk
 
-from cozy.ext import inject
+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 e3c2006..b871c91 100644
--- a/cozy/ui/toaster.py
+++ b/cozy/ui/toaster.py
@@ -1,6 +1,6 @@
 from gi.repository import Adw, Gtk
 
-from cozy.ext import inject
+import inject
 
 
 class ToastNotifier:
diff --git a/cozy/ui/widgets/album_element.py b/cozy/ui/widgets/album_element.py
index 11a84a1..6588a57 100644
--- a/cozy/ui/widgets/album_element.py
+++ b/cozy/ui/widgets/album_element.py
@@ -5,7 +5,7 @@ import cairo
 
 from cozy.control.artwork_cache import ArtworkCache
 from cozy.model.book import Book
-from cozy.ext import inject
+import inject
 
 from gi.repository import Gtk, GObject, Gdk
 
diff --git a/cozy/ui/widgets/book_row.py b/cozy/ui/widgets/book_row.py
index 9b88b33..b44206c 100644
--- a/cozy/ui/widgets/book_row.py
+++ b/cozy/ui/widgets/book_row.py
@@ -3,7 +3,7 @@ from typing import Callable
 from gi.repository import Adw, Gtk
 
 from cozy.control.artwork_cache import ArtworkCache
-from cozy.ext import inject
+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 3610327..0de9b56 100644
--- a/cozy/ui/widgets/error_reporting.py
+++ b/cozy/ui/widgets/error_reporting.py
@@ -3,7 +3,7 @@ from gettext import gettext as _
 import gi
 
 from cozy.application_settings import ApplicationSettings
-from cozy.ext import inject
+import inject
 
 from gi.repository import Gtk
 
diff --git a/cozy/ui/widgets/playback_speed_popover.py b/cozy/ui/widgets/playback_speed_popover.py
index 18c9266..a554652 100644
--- a/cozy/ui/widgets/playback_speed_popover.py
+++ b/cozy/ui/widgets/playback_speed_popover.py
@@ -1,4 +1,4 @@
-from cozy.ext import inject
+import inject
 from cozy.view_model.playback_speed_view_model import PlaybackSpeedViewModel
 
 from gi.repository import Gtk
diff --git a/cozy/ui/widgets/sleep_timer.py b/cozy/ui/widgets/sleep_timer.py
index 6d396db..e0e10cf 100644
--- a/cozy/ui/widgets/sleep_timer.py
+++ b/cozy/ui/widgets/sleep_timer.py
@@ -1,4 +1,4 @@
-from cozy.ext import inject
+import inject
 from cozy.view_model.sleep_timer_view_model import SleepTimerViewModel, SystemPowerControl
 
 from gi.repository import Gtk
diff --git a/cozy/ui/widgets/storages.py b/cozy/ui/widgets/storages.py
index f20726d..855f5a1 100644
--- a/cozy/ui/widgets/storages.py
+++ b/cozy/ui/widgets/storages.py
@@ -2,7 +2,7 @@ from typing import Callable
 
 from gi.repository import Adw, Gio, GLib, GObject, Gtk
 
-from cozy.ext import inject
+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 4eb7e9c..764b2b2 100644
--- a/cozy/view_model/book_detail_view_model.py
+++ b/cozy/view_model/book_detail_view_model.py
@@ -4,7 +4,7 @@ from cozy.architecture.event_sender import EventSender
 from cozy.architecture.observable import Observable
 from cozy.control.filesystem_monitor import FilesystemMonitor
 from cozy.control.offline_cache import OfflineCache
-from cozy.ext import inject
+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 d160220..1786994 100644
--- a/cozy/view_model/headerbar_view_model.py
+++ b/cozy/view_model/headerbar_view_model.py
@@ -3,7 +3,7 @@ from enum import Enum, auto
 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
+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 2639ca8..8b7203e 100644
--- a/cozy/view_model/library_view_model.py
+++ b/cozy/view_model/library_view_model.py
@@ -3,7 +3,7 @@ import os
 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 8255a49..4e0bfeb 100644
--- a/cozy/view_model/playback_control_view_model.py
+++ b/cozy/view_model/playback_control_view_model.py
@@ -1,6 +1,6 @@
 from cozy.architecture.event_sender import EventSender
 from cozy.architecture.observable import Observable
-from cozy.ext import inject
+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 0de22a8..73e0f21 100644
--- a/cozy/view_model/playback_speed_view_model.py
+++ b/cozy/view_model/playback_speed_view_model.py
@@ -1,7 +1,7 @@
 from cozy.architecture.event_sender import EventSender
 from cozy.architecture.observable import Observable
 from cozy.db.book import Book
-from cozy.ext import inject
+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 cd8ee70..e363871 100644
--- a/cozy/view_model/search_view_model.py
+++ b/cozy/view_model/search_view_model.py
@@ -2,7 +2,7 @@ from typing import Callable
 
 from gi.repository import GLib
 
-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/settings_view_model.py b/cozy/view_model/settings_view_model.py
index f533352..678c574 100644
--- a/cozy/view_model/settings_view_model.py
+++ b/cozy/view_model/settings_view_model.py
@@ -5,7 +5,7 @@ from gi.repository import Adw, Gtk
 from cozy.application_settings import ApplicationSettings
 from cozy.architecture.event_sender import EventSender
 from cozy.architecture.observable import Observable
-from cozy.ext import inject
+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 296ef8c..3acb9d6 100644
--- a/cozy/view_model/sleep_timer_view_model.py
+++ b/cozy/view_model/sleep_timer_view_model.py
@@ -6,7 +6,7 @@ from typing import Optional
 from cozy import tools
 from cozy.application_settings import ApplicationSettings
 from cozy.architecture.observable import Observable
-from cozy.ext import inject
+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 c238e40..b085aac 100644
--- a/cozy/view_model/storages_view_model.py
+++ b/cozy/view_model/storages_view_model.py
@@ -7,7 +7,7 @@ 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
+import inject
 from cozy.media.importer import Importer
 from cozy.model.library import Library
 from cozy.model.settings import Settings
diff --git a/test/cozy/media/test_importer.py b/test/cozy/media/test_importer.py
index fe599f6..2b20552 100644
--- a/test/cozy/media/test_importer.py
+++ b/test/cozy/media/test_importer.py
@@ -3,7 +3,7 @@ from unittest.mock import MagicMock, call
 import pytest
 from peewee import SqliteDatabase
 
-from cozy.ext import inject
+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 bce0522..f8d64bb 100644
--- a/test/cozy/media/test_player.py
+++ b/test/cozy/media/test_player.py
@@ -4,7 +4,7 @@ import pytest
 from peewee import SqliteDatabase
 
 from cozy.application_settings import ApplicationSettings
-from cozy.ext import inject
+import inject
 from cozy.media.gst_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 7bbee04..18e9bb3 100644
--- a/test/cozy/model/storage_block_list.py
+++ b/test/cozy/model/storage_block_list.py
@@ -1,7 +1,7 @@
 import pytest
 from peewee import SqliteDatabase
 
-from cozy.ext import inject
+import inject
 
 
 @pytest.fixture(autouse=True)
diff --git a/test/cozy/model/test_book.py b/test/cozy/model/test_book.py
index 5c89451..7dc0dec 100644
--- a/test/cozy/model/test_book.py
+++ b/test/cozy/model/test_book.py
@@ -2,7 +2,7 @@ import pytest
 from peewee import SqliteDatabase
 
 from cozy.application_settings import ApplicationSettings
-from cozy.ext import inject
+import inject
 from test.cozy.mocks import ApplicationSettingsMock
 
 
diff --git a/test/cozy/model/test_database_importer.py b/test/cozy/model/test_database_importer.py
index d5c2827..c44a58a 100644
--- a/test/cozy/model/test_database_importer.py
+++ b/test/cozy/model/test_database_importer.py
@@ -1,7 +1,7 @@
 import pytest
 from peewee import SqliteDatabase
 
-from cozy.ext import inject
+import inject
 
 
 @pytest.fixture(autouse=True)
diff --git a/test/cozy/model/test_library.py b/test/cozy/model/test_library.py
index 34556bf..6e3b337 100644
--- a/test/cozy/model/test_library.py
+++ b/test/cozy/model/test_library.py
@@ -2,7 +2,7 @@ import pytest
 from peewee import SqliteDatabase
 
 from cozy.application_settings import ApplicationSettings
-from cozy.ext import inject
+import inject
 from cozy.extensions.set import split_strings_to_set
 from cozy.model.settings import Settings
 from test.cozy.mocks import ApplicationSettingsMock
