Repository: home-assistant/core
File: homeassistant/loader.py (Python)

Code before:
        helper = importlib.import_module(f"homeassistant.helpers.{helper_name}")
        wrapped = ModuleWrapper(self._hass, helper)
        setattr(self, helper_name, wrapped)
        return wrapped


def bind_hass(func: _CallableT) -> _CallableT:
    """Decorate function to indicate that first argument is hass.

    The use of this decorator is discouraged, and it should not be used
    for new functions.
    """
    setattr(func, "__bind_hass", True)
    return func


async def _async_component_dependencies(
    hass: HomeAssistant,
    integration: Integration,
) -> set[str]:
    """Async function to get component dependencies."""
    loading = set()
    loaded = set()

    async def helper(integration: Integration) -> None:
        """Recursive async helper to get component dependencies."""
        domain = integration.domain
        loading.add(domain)

        for dependency_domain in integration.dependencies:
            dep_integration = await async_get_integration(hass, dependency_domain)

            # If we are already loading it, we have a circular dependency.
            # We have to check it here, because we need to cover all possible dependants.
            if conflict := loading.intersection(dep_integration.after_dependencies):
                raise CircularDependency(conflict.pop(), dependency_domain)

            # If we have already loaded it, no point doing it again.
            if dependency_domain in loaded:
                continue

            # If we are already loading it, we have a circular dependency.
            if dependency_domain in loading:
                raise CircularDependency(dependency_domain, domain)

            await helper(dep_integration)

        loading.remove(domain)
        loaded.add(domain)

    await helper(integration)

Review comment (refactor):
`helper` is not a good name.

Maybe call it `component_dependencies_impl` since this is the actual implementation and `_async_component_dependencies` is just a wrapper?

Code after:
        helper = importlib.import_module(f"homeassistant.helpers.{helper_name}")
        wrapped = ModuleWrapper(self._hass, helper)
        setattr(self, helper_name, wrapped)
        return wrapped


def bind_hass(func: _CallableT) -> _CallableT:
    """Decorate function to indicate that first argument is hass.

    The use of this decorator is discouraged, and it should not be used
    for new functions.
    """
    setattr(func, "__bind_hass", True)
    return func


async def _async_component_dependencies(
    hass: HomeAssistant,
    integration: Integration,
) -> set[str]:
    """Get component dependencies."""
    loading = set()
    loaded = set()

    async def component_dependencies_impl(integration: Integration) -> None:
        """Recursively get component dependencies."""
        domain = integration.domain
        loading.add(domain)

        for dependency_domain in integration.dependencies:
            dep_integration = await async_get_integration(hass, dependency_domain)

            # If we are already loading it, we have a circular dependency.
            # We have to check it here to make sure that every integration that
            # depends on us, does not appear in our own after_dependencies.
            if conflict := loading.intersection(dep_integration.after_dependencies):
                raise CircularDependency(conflict, dependency_domain)

            # If we have already loaded it, no point doing it again.
            if dependency_domain in loaded:
                continue

            # If we are already loading it, we have a circular dependency.
            if dependency_domain in loading:
                raise CircularDependency(dependency_domain, domain)

            await component_dependencies_impl(dep_integration)

        loading.remove(domain)
        loaded.add(domain)