Skip to content

vllm.utils.import_utils

Contains helpers related to importing modules.

This is similar in concept to the importlib module.

LazyLoader

Bases: ModuleType

LazyLoader module borrowed from [Tensorflow] (https://github.com/tensorflow/tensorflow/blob/main/tensorflow/python/util/lazy_loader.py) with an addition of "module caching".

Lazily import a module, mainly to avoid pulling in large dependencies. Modules such as xgrammar might do additional side effects, so we only want to use this when it is needed, delaying all eager effects.

Source code in vllm/utils/import_utils.py
class LazyLoader(ModuleType):
    """
    `LazyLoader` module borrowed from [Tensorflow]
    (https://github.com/tensorflow/tensorflow/blob/main/tensorflow/python/util/lazy_loader.py)
    with an addition of "module caching".

    Lazily import a module, mainly to avoid pulling in large dependencies.
    Modules such as `xgrammar` might do additional side effects, so we
    only want to use this when it is needed, delaying all eager effects.
    """

    def __init__(
        self,
        local_name: str,
        parent_module_globals: dict[str, Any],
        name: str,
    ):
        self._local_name = local_name
        self._parent_module_globals = parent_module_globals
        self._module: ModuleType | None = None

        super().__init__(str(name))

    def _load(self) -> ModuleType:
        # Import the target module and insert it into the parent's namespace
        try:
            module = importlib.import_module(self.__name__)
            self._parent_module_globals[self._local_name] = module
            # The additional add to sys.modules
            # ensures library is actually loaded.
            sys.modules[self._local_name] = module
        except ModuleNotFoundError as err:
            raise err from None

        # Update this object's dict so that if someone keeps a
        # reference to the LazyLoader, lookups are efficient
        # (__getattr__ is only called on lookups that fail).
        self.__dict__.update(module.__dict__)
        return module

    def __getattr__(self, item: Any) -> Any:
        if self._module is None:
            self._module = self._load()
        return getattr(self._module, item)

    def __dir__(self) -> list[str]:
        if self._module is None:
            self._module = self._load()
        return dir(self._module)

_local_name instance-attribute

_local_name = local_name

_module instance-attribute

_module: ModuleType | None = None

_parent_module_globals instance-attribute

_parent_module_globals = parent_module_globals

__dir__

__dir__() -> list[str]
Source code in vllm/utils/import_utils.py
def __dir__(self) -> list[str]:
    if self._module is None:
        self._module = self._load()
    return dir(self._module)

__getattr__

__getattr__(item: Any) -> Any
Source code in vllm/utils/import_utils.py
def __getattr__(self, item: Any) -> Any:
    if self._module is None:
        self._module = self._load()
    return getattr(self._module, item)

__init__

__init__(
    local_name: str,
    parent_module_globals: dict[str, Any],
    name: str,
)
Source code in vllm/utils/import_utils.py
def __init__(
    self,
    local_name: str,
    parent_module_globals: dict[str, Any],
    name: str,
):
    self._local_name = local_name
    self._parent_module_globals = parent_module_globals
    self._module: ModuleType | None = None

    super().__init__(str(name))

_load

_load() -> ModuleType
Source code in vllm/utils/import_utils.py
def _load(self) -> ModuleType:
    # Import the target module and insert it into the parent's namespace
    try:
        module = importlib.import_module(self.__name__)
        self._parent_module_globals[self._local_name] = module
        # The additional add to sys.modules
        # ensures library is actually loaded.
        sys.modules[self._local_name] = module
    except ModuleNotFoundError as err:
        raise err from None

    # Update this object's dict so that if someone keeps a
    # reference to the LazyLoader, lookups are efficient
    # (__getattr__ is only called on lookups that fail).
    self.__dict__.update(module.__dict__)
    return module

PlaceholderModule

Bases: _PlaceholderBase

A placeholder object to use when a module does not exist.

This enables more informative errors when trying to access attributes of a module that does not exist.

Source code in vllm/utils/import_utils.py
class PlaceholderModule(_PlaceholderBase):
    """
    A placeholder object to use when a module does not exist.

    This enables more informative errors when trying to access attributes
    of a module that does not exist.
    """

    def __init__(self, name: str) -> None:
        super().__init__()

        # Apply name mangling to avoid conflicting with module attributes
        self.__name = name

    def placeholder_attr(self, attr_path: str):
        return _PlaceholderModuleAttr(self, attr_path)

    def __getattr__(self, key: str) -> Never:
        name = self.__name

        try:
            importlib.import_module(name)
        except ImportError as exc:
            for extra, names in get_vllm_optional_dependencies().items():
                if name in names:
                    msg = f"Please install vllm[{extra}] for {extra} support"
                    raise ImportError(msg) from exc

            raise exc

        raise AssertionError(
            "PlaceholderModule should not be used "
            "when the original module can be imported"
        )

__name instance-attribute

__name = name

__getattr__

__getattr__(key: str) -> Never
Source code in vllm/utils/import_utils.py
def __getattr__(self, key: str) -> Never:
    name = self.__name

    try:
        importlib.import_module(name)
    except ImportError as exc:
        for extra, names in get_vllm_optional_dependencies().items():
            if name in names:
                msg = f"Please install vllm[{extra}] for {extra} support"
                raise ImportError(msg) from exc

        raise exc

    raise AssertionError(
        "PlaceholderModule should not be used "
        "when the original module can be imported"
    )

__init__

__init__(name: str) -> None
Source code in vllm/utils/import_utils.py
def __init__(self, name: str) -> None:
    super().__init__()

    # Apply name mangling to avoid conflicting with module attributes
    self.__name = name

placeholder_attr

placeholder_attr(attr_path: str)
Source code in vllm/utils/import_utils.py
def placeholder_attr(self, attr_path: str):
    return _PlaceholderModuleAttr(self, attr_path)

_PlaceholderBase

Disallows downstream usage of placeholder modules.

We need to explicitly override each dunder method because __getattr__ is not called when they are accessed.

Info

Special method lookup

Source code in vllm/utils/import_utils.py
class _PlaceholderBase:
    """
    Disallows downstream usage of placeholder modules.

    We need to explicitly override each dunder method because
    [`__getattr__`][vllm.utils.import_utils._PlaceholderBase.__getattr__]
    is not called when they are accessed.

    Info:
        [Special method lookup](https://docs.python.org/3/reference/datamodel.html#special-lookup)
    """

    def __getattr__(self, key: str) -> Never:
        """
        The main class should implement this to throw an error
        for attribute accesses representing downstream usage.
        """
        raise NotImplementedError

    # [Basic customization]

    def __lt__(self, other: object):
        return self.__getattr__("__lt__")

    def __le__(self, other: object):
        return self.__getattr__("__le__")

    def __eq__(self, other: object):
        return self.__getattr__("__eq__")

    def __ne__(self, other: object):
        return self.__getattr__("__ne__")

    def __gt__(self, other: object):
        return self.__getattr__("__gt__")

    def __ge__(self, other: object):
        return self.__getattr__("__ge__")

    def __hash__(self):
        return self.__getattr__("__hash__")

    def __bool__(self):
        return self.__getattr__("__bool__")

    # [Callable objects]

    def __call__(self, *args: object, **kwargs: object):
        return self.__getattr__("__call__")

    # [Container types]

    def __len__(self):
        return self.__getattr__("__len__")

    def __getitem__(self, key: object):
        return self.__getattr__("__getitem__")

    def __setitem__(self, key: object, value: object):
        return self.__getattr__("__setitem__")

    def __delitem__(self, key: object):
        return self.__getattr__("__delitem__")

    # __missing__ is optional according to __getitem__ specification,
    # so it is skipped

    # __iter__ and __reversed__ have a default implementation
    # based on __len__ and __getitem__, so they are skipped.

    # [Numeric Types]

    def __add__(self, other: object):
        return self.__getattr__("__add__")

    def __sub__(self, other: object):
        return self.__getattr__("__sub__")

    def __mul__(self, other: object):
        return self.__getattr__("__mul__")

    def __matmul__(self, other: object):
        return self.__getattr__("__matmul__")

    def __truediv__(self, other: object):
        return self.__getattr__("__truediv__")

    def __floordiv__(self, other: object):
        return self.__getattr__("__floordiv__")

    def __mod__(self, other: object):
        return self.__getattr__("__mod__")

    def __divmod__(self, other: object):
        return self.__getattr__("__divmod__")

    def __pow__(self, other: object, modulo: object = ...):
        return self.__getattr__("__pow__")

    def __lshift__(self, other: object):
        return self.__getattr__("__lshift__")

    def __rshift__(self, other: object):
        return self.__getattr__("__rshift__")

    def __and__(self, other: object):
        return self.__getattr__("__and__")

    def __xor__(self, other: object):
        return self.__getattr__("__xor__")

    def __or__(self, other: object):
        return self.__getattr__("__or__")

    # r* and i* methods have lower priority than
    # the methods for left operand so they are skipped

    def __neg__(self):
        return self.__getattr__("__neg__")

    def __pos__(self):
        return self.__getattr__("__pos__")

    def __abs__(self):
        return self.__getattr__("__abs__")

    def __invert__(self):
        return self.__getattr__("__invert__")

    # __complex__, __int__ and __float__ have a default implementation
    # based on __index__, so they are skipped.

    def __index__(self):
        return self.__getattr__("__index__")

    def __round__(self, ndigits: object = ...):
        return self.__getattr__("__round__")

    def __trunc__(self):
        return self.__getattr__("__trunc__")

    def __floor__(self):
        return self.__getattr__("__floor__")

    def __ceil__(self):
        return self.__getattr__("__ceil__")

    # [Context managers]

    def __enter__(self):
        return self.__getattr__("__enter__")

    def __exit__(self, *args: object, **kwargs: object):
        return self.__getattr__("__exit__")

__abs__

__abs__()
Source code in vllm/utils/import_utils.py
def __abs__(self):
    return self.__getattr__("__abs__")

__add__

__add__(other: object)
Source code in vllm/utils/import_utils.py
def __add__(self, other: object):
    return self.__getattr__("__add__")

__and__

__and__(other: object)
Source code in vllm/utils/import_utils.py
def __and__(self, other: object):
    return self.__getattr__("__and__")

__bool__

__bool__()
Source code in vllm/utils/import_utils.py
def __bool__(self):
    return self.__getattr__("__bool__")

__call__

__call__(*args: object, **kwargs: object)
Source code in vllm/utils/import_utils.py
def __call__(self, *args: object, **kwargs: object):
    return self.__getattr__("__call__")

__ceil__

__ceil__()
Source code in vllm/utils/import_utils.py
def __ceil__(self):
    return self.__getattr__("__ceil__")

__delitem__

__delitem__(key: object)
Source code in vllm/utils/import_utils.py
def __delitem__(self, key: object):
    return self.__getattr__("__delitem__")

__divmod__

__divmod__(other: object)
Source code in vllm/utils/import_utils.py
def __divmod__(self, other: object):
    return self.__getattr__("__divmod__")

__enter__

__enter__()
Source code in vllm/utils/import_utils.py
def __enter__(self):
    return self.__getattr__("__enter__")

__eq__

__eq__(other: object)
Source code in vllm/utils/import_utils.py
def __eq__(self, other: object):
    return self.__getattr__("__eq__")

__exit__

__exit__(*args: object, **kwargs: object)
Source code in vllm/utils/import_utils.py
def __exit__(self, *args: object, **kwargs: object):
    return self.__getattr__("__exit__")

__floor__

__floor__()
Source code in vllm/utils/import_utils.py
def __floor__(self):
    return self.__getattr__("__floor__")

__floordiv__

__floordiv__(other: object)
Source code in vllm/utils/import_utils.py
def __floordiv__(self, other: object):
    return self.__getattr__("__floordiv__")

__ge__

__ge__(other: object)
Source code in vllm/utils/import_utils.py
def __ge__(self, other: object):
    return self.__getattr__("__ge__")

__getattr__

__getattr__(key: str) -> Never

The main class should implement this to throw an error for attribute accesses representing downstream usage.

Source code in vllm/utils/import_utils.py
def __getattr__(self, key: str) -> Never:
    """
    The main class should implement this to throw an error
    for attribute accesses representing downstream usage.
    """
    raise NotImplementedError

__getitem__

__getitem__(key: object)
Source code in vllm/utils/import_utils.py
def __getitem__(self, key: object):
    return self.__getattr__("__getitem__")

__gt__

__gt__(other: object)
Source code in vllm/utils/import_utils.py
def __gt__(self, other: object):
    return self.__getattr__("__gt__")

__hash__

__hash__()
Source code in vllm/utils/import_utils.py
def __hash__(self):
    return self.__getattr__("__hash__")

__index__

__index__()
Source code in vllm/utils/import_utils.py
def __index__(self):
    return self.__getattr__("__index__")

__invert__

__invert__()
Source code in vllm/utils/import_utils.py
def __invert__(self):
    return self.__getattr__("__invert__")

__le__

__le__(other: object)
Source code in vllm/utils/import_utils.py
def __le__(self, other: object):
    return self.__getattr__("__le__")

__len__

__len__()
Source code in vllm/utils/import_utils.py
def __len__(self):
    return self.__getattr__("__len__")

__lshift__

__lshift__(other: object)
Source code in vllm/utils/import_utils.py
def __lshift__(self, other: object):
    return self.__getattr__("__lshift__")

__lt__

__lt__(other: object)
Source code in vllm/utils/import_utils.py
def __lt__(self, other: object):
    return self.__getattr__("__lt__")

__matmul__

__matmul__(other: object)
Source code in vllm/utils/import_utils.py
def __matmul__(self, other: object):
    return self.__getattr__("__matmul__")

__mod__

__mod__(other: object)
Source code in vllm/utils/import_utils.py
def __mod__(self, other: object):
    return self.__getattr__("__mod__")

__mul__

__mul__(other: object)
Source code in vllm/utils/import_utils.py
def __mul__(self, other: object):
    return self.__getattr__("__mul__")

__ne__

__ne__(other: object)
Source code in vllm/utils/import_utils.py
def __ne__(self, other: object):
    return self.__getattr__("__ne__")

__neg__

__neg__()
Source code in vllm/utils/import_utils.py
def __neg__(self):
    return self.__getattr__("__neg__")

__or__

__or__(other: object)
Source code in vllm/utils/import_utils.py
def __or__(self, other: object):
    return self.__getattr__("__or__")

__pos__

__pos__()
Source code in vllm/utils/import_utils.py
def __pos__(self):
    return self.__getattr__("__pos__")

__pow__

__pow__(other: object, modulo: object = ...)
Source code in vllm/utils/import_utils.py
def __pow__(self, other: object, modulo: object = ...):
    return self.__getattr__("__pow__")

__round__

__round__(ndigits: object = ...)
Source code in vllm/utils/import_utils.py
def __round__(self, ndigits: object = ...):
    return self.__getattr__("__round__")

__rshift__

__rshift__(other: object)
Source code in vllm/utils/import_utils.py
def __rshift__(self, other: object):
    return self.__getattr__("__rshift__")

__setitem__

__setitem__(key: object, value: object)
Source code in vllm/utils/import_utils.py
def __setitem__(self, key: object, value: object):
    return self.__getattr__("__setitem__")

__sub__

__sub__(other: object)
Source code in vllm/utils/import_utils.py
def __sub__(self, other: object):
    return self.__getattr__("__sub__")

__truediv__

__truediv__(other: object)
Source code in vllm/utils/import_utils.py
def __truediv__(self, other: object):
    return self.__getattr__("__truediv__")

__trunc__

__trunc__()
Source code in vllm/utils/import_utils.py
def __trunc__(self):
    return self.__getattr__("__trunc__")

__xor__

__xor__(other: object)
Source code in vllm/utils/import_utils.py
def __xor__(self, other: object):
    return self.__getattr__("__xor__")

_PlaceholderModuleAttr

Bases: _PlaceholderBase

Source code in vllm/utils/import_utils.py
class _PlaceholderModuleAttr(_PlaceholderBase):
    def __init__(self, module: PlaceholderModule, attr_path: str) -> None:
        super().__init__()

        # Apply name mangling to avoid conflicting with module attributes
        self.__module = module
        self.__attr_path = attr_path

    def placeholder_attr(self, attr_path: str):
        return _PlaceholderModuleAttr(self.__module, f"{self.__attr_path}.{attr_path}")

    def __getattr__(self, key: str) -> Never:
        getattr(self.__module, f"{self.__attr_path}.{key}")

        raise AssertionError(
            "PlaceholderModule should not be used "
            "when the original module can be imported"
        )

__attr_path instance-attribute

__attr_path = attr_path

__module instance-attribute

__module = module

__getattr__

__getattr__(key: str) -> Never
Source code in vllm/utils/import_utils.py
def __getattr__(self, key: str) -> Never:
    getattr(self.__module, f"{self.__attr_path}.{key}")

    raise AssertionError(
        "PlaceholderModule should not be used "
        "when the original module can be imported"
    )

__init__

__init__(module: PlaceholderModule, attr_path: str) -> None
Source code in vllm/utils/import_utils.py
def __init__(self, module: PlaceholderModule, attr_path: str) -> None:
    super().__init__()

    # Apply name mangling to avoid conflicting with module attributes
    self.__module = module
    self.__attr_path = attr_path

placeholder_attr

placeholder_attr(attr_path: str)
Source code in vllm/utils/import_utils.py
def placeholder_attr(self, attr_path: str):
    return _PlaceholderModuleAttr(self.__module, f"{self.__attr_path}.{attr_path}")

get_vllm_optional_dependencies cached

get_vllm_optional_dependencies()
Source code in vllm/utils/import_utils.py
@cache
def get_vllm_optional_dependencies():
    metadata = importlib.metadata.metadata("vllm")
    requirements = metadata.get_all("Requires-Dist", [])
    extras = metadata.get_all("Provides-Extra", [])

    return {
        extra: [
            re.split(r";|>=|<=|==", req)[0]
            for req in requirements
            if req.endswith(f'extra == "{extra}"')
        ]
        for extra in extras
    }

import_from_path

import_from_path(
    module_name: str, file_path: str | PathLike
)

Import a Python file according to its file path.

Based on the official recipe: https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly

Source code in vllm/utils/import_utils.py
def import_from_path(module_name: str, file_path: str | os.PathLike):
    """
    Import a Python file according to its file path.

    Based on the official recipe:
    https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly
    """
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    if spec is None:
        raise ModuleNotFoundError(f"No module named {module_name!r}")

    assert spec.loader is not None

    module = importlib.util.module_from_spec(spec)
    sys.modules[module_name] = module
    spec.loader.exec_module(module)
    return module

resolve_obj_by_qualname

resolve_obj_by_qualname(qualname: str) -> Any

Resolve an object by its fully-qualified class name.

Source code in vllm/utils/import_utils.py
def resolve_obj_by_qualname(qualname: str) -> Any:
    """
    Resolve an object by its fully-qualified class name.
    """
    module_name, obj_name = qualname.rsplit(".", 1)
    module = importlib.import_module(module_name)
    return getattr(module, obj_name)