Skip to content

Commit

Permalink
test: Add missing module_loader tests (#3073)
Browse files Browse the repository at this point in the history
Fix module loader coverage
  • Loading branch information
provinzkraut committed Feb 6, 2024
1 parent e6eb9f2 commit 1e037d3
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 15 deletions.
25 changes: 10 additions & 15 deletions litestar/utils/module_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

import platform
import os.path
import sys
from importlib import import_module
from importlib.util import find_spec
Expand All @@ -17,8 +17,6 @@
"module_to_os_path",
)

PYTHON_38 = sys.version_info < (3, 9, 0)


def module_to_os_path(dotted_path: str = "app") -> Path:
"""Find Module to OS Path.
Expand All @@ -27,7 +25,7 @@ def module_to_os_path(dotted_path: str = "app") -> Path:
specified by `dotted_path`.
Args:
dotted_path (str, optional): The path to the module. Defaults to "app".
dotted_path: The path to the module. Defaults to "app".
Raises:
TypeError: The module could not be found.
Expand All @@ -36,15 +34,12 @@ def module_to_os_path(dotted_path: str = "app") -> Path:
Path: The path to the module.
"""
try:
src = find_spec(dotted_path)
if (src := find_spec(dotted_path)) is None: # pragma: no cover
raise TypeError(f"Couldn't find the path for {dotted_path}")
except ModuleNotFoundError as e:
msg = "Couldn't find the path for %s"
raise TypeError(msg, dotted_path) from e
path_separator = "\\" if platform.system() == "Windows" else "/"
if PYTHON_38:
suffix = f"{path_separator}__init__.py"
return Path(str(src.origin)[: (-1 * len(suffix))] if src.origin.endswith(suffix) else src.origin) # type: ignore[arg-type, union-attr]
return Path(str(src.origin).removesuffix(f"{path_separator}__init__.py")) # type: ignore
raise TypeError(f"Couldn't find the path for {dotted_path}") from e

return Path(str(src.origin).rsplit(os.path.sep + "__init__.py", maxsplit=1)[0])


def import_string(dotted_path: str) -> Any:
Expand All @@ -54,7 +49,7 @@ def import_string(dotted_path: str) -> Any:
last name in the path. Raise ImportError if the import failed.
Args:
dotted_path (str): The path of the module to import.
dotted_path: The path of the module to import.
Raises:
ImportError: Could not import the module.
Expand All @@ -72,8 +67,8 @@ def _cached_import(module_path: str, class_name: str) -> Any:
"""Import and cache a class from a module.
Args:
module_path (str): dotted path to module.
class_name (str): Class or function name.
module_path: dotted path to module.
class_name: Class or function name.
Returns:
object: The imported class or function
Expand Down
16 changes: 16 additions & 0 deletions tests/unit/test_utils/test_module_loader.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from pathlib import Path

import pytest
from _pytest.monkeypatch import MonkeyPatch

from litestar.config.compression import CompressionConfig
from litestar.utils.module_loader import import_string, module_to_os_path
Expand All @@ -21,3 +24,16 @@ def test_module_path() -> None:
with pytest.raises(TypeError):
_ = module_to_os_path("litestar.config.compression.Config")
_ = module_to_os_path("litestar.config.compression.extra.module")


def test_import_non_existing_attribute_raises() -> None:
with pytest.raises(ImportError):
import_string("litestar.app.some_random_string")


def test_import_string_cached(tmp_path: Path, monkeypatch: MonkeyPatch) -> None:
tmp_path.joinpath("testmodule.py").write_text("x = 'foo'")
monkeypatch.chdir(tmp_path)
monkeypatch.syspath_prepend(tmp_path)

assert import_string("testmodule.x") == "foo"

0 comments on commit 1e037d3

Please sign in to comment.