def test__load_dependencies_from__with_already_loaded_files(
            self, patch_injection_container, patch_open):
        # given
        root = "/" if os.name != "nt" else "C:\\"
        search_path = os.path.join(root, "fake", "path")
        namespace = DEFAULT_NAMESPACE
        mocked_file_1 = MagicMock(spec=os.DirEntry)
        mocked_file_1.path = os.path.join("fake", "path", "file_1.py")
        mocked_file_2 = MagicMock(spec=os.DirEntry)
        mocked_file_2.path = os.path.join("fake", "path", "file_2.py")
        file_collector = MagicMock()
        file_collector.collect.return_value = {mocked_file_1, mocked_file_2}
        patch_injection_container(
            "PythonFileCollector",
            return_value=file_collector,
        )
        patch_open(
            read_data=
            "from injectable import injectable\n@injectable\nclass A: ...")
        run_path = patch_injection_container("run_path")
        InjectionContainer.load_dependencies_from(search_path, namespace)

        # when
        InjectionContainer.load_dependencies_from(search_path, namespace)

        # then
        assert file_collector.collect.call_count == 2
        assert run_path.call_count == 2
        assert len(InjectionContainer.LOADED_FILEPATHS) == 2
    def test__load_dependencies_from__with_files_with_injectables(
            self, patch_injection_container, patch_open):
        # given
        root = "/" if os.name != "nt" else "C:\\"
        search_path = os.path.join(root, "fake", "path")
        namespace = DEFAULT_NAMESPACE
        file_collector = MagicMock()
        file_collector.collect.return_value = {
            MagicMock(spec=os.DirEntry),
            MagicMock(spec=os.DirEntry),
        }
        patch_injection_container(
            "PythonFileCollector",
            return_value=file_collector,
        )
        patch_open(
            read_data=
            "from injectable import injectable\n@injectable\nclass A: ...")
        run_path = patch_injection_container("run_path")

        # when
        InjectionContainer.load_dependencies_from(search_path, namespace)

        # then
        assert file_collector.collect.called is True
        assert run_path.call_count == 2
    def test__load_dependencies_from__with_files_without_injectables(
            self, patch_injection_container, patch_open):
        # given
        root = "/" if os.name != "nt" else "C:\\"
        search_path = os.path.join(root, "fake", "path")
        namespace = DEFAULT_NAMESPACE
        file_collector = MagicMock()
        file_collector.collect.return_value = {
            MagicMock(spec=os.DirEntry),
            MagicMock(spec=os.DirEntry),
        }
        patch_injection_container(
            "PythonFileCollector",
            return_value=file_collector,
        )
        patch_open(read_data='"""not injectable"""')
        patch_injection_container("find_module_name")
        spec = MagicMock()
        patch_injection_container("spec_from_file_location", return_value=spec)
        patch_injection_container("module_from_spec")

        # when
        InjectionContainer.load_dependencies_from(search_path, namespace)

        # then
        assert file_collector.collect.called is True
        assert spec.loader.exec_module.called is False
    def test__load_dependencies_from__leaves_loading_vars_clean(
            self, patch_injection_container):
        # given
        root = "/" if os.name != "nt" else "C:\\"
        search_path = os.path.join(root, "fake", "path")
        namespace = DEFAULT_NAMESPACE
        patch_injection_container("PythonFileCollector")

        # when
        InjectionContainer.load_dependencies_from(search_path, namespace)

        # then
        assert InjectionContainer.LOADING_FILEPATH is None
        assert InjectionContainer.LOADING_DEFAULT_NAMESPACE is None
    def test__load_dependencies_from__regular_call(self,
                                                   patch_injection_container):
        # given
        root = "/" if os.name != "nt" else "C:\\"
        search_path = os.path.join(root, "fake", "path")
        namespace = DEFAULT_NAMESPACE
        file_collector = MagicMock()
        patch_injection_container("PythonFileCollector",
                                  return_value=file_collector)

        # when
        InjectionContainer.load_dependencies_from(search_path, namespace)

        # then
        assert file_collector.collect.called is True
Exemple #6
0
def load_injection_container(
    search_path: str = None,
    *,
    default_namespace: str = DEFAULT_NAMESPACE,
    encoding: str = "utf-8",
):
    """
    Loads injectables under the search path to a shared injection container under the
    designated namespaces.

    :param search_path: (optional) path under which to search for injectables. Can
            be either a relative or absolute path. Defaults to the caller's file
            directory.
    :param default_namespace: (optional) designated namespace for registering
            injectables which does not explicitly request to be addressed in a
            specific namespace. Defaults to
            :const:`injectable.constants.DEFAULT_NAMESPACE`.
    :param encoding: (optional) defines which encoding to use when reading project files
            to discover and register injectables. Defaults to ``utf-8``.

    Usage::

      >>> from injectable import load_injection_container
      >>> load_injection_container()

    .. note::

        This method will not scan any file already scanned by previous calls to it.
        Multiple invocations to different search paths will add found injectables into
        the injection container without clearing previously loaded ones but never
        loading a same injectable more than once.

    .. versionadded:: 3.4.0
    """
    if search_path is None:
        search_path = os.path.dirname(get_caller_filepath())
    elif not os.path.isabs(search_path):
        caller_path = os.path.dirname(get_caller_filepath())
        search_path = os.path.abspath(os.path.join(caller_path, search_path))
    InjectionContainer.load_dependencies_from(search_path, default_namespace,
                                              encoding)