<commit_before>import asyncio
import functools
import importlib
import inspect
import logging
from typing import Text, Dict, Optional, Any, List, Callable, Collection

import rasa.shared.utils.io as io_utils
from rasa.shared.constants import NEXT_MAJOR_VERSION_FOR_DEPRECATIONS


logger = logging.getLogger(__name__)


def class_from_module_path(
    module_path: Text, lookup_path: Optional[Text] = None, ensure_class: bool = True
) -> Any:
    """Given the module name and path of a class, tries to retrieve the class.

    The loaded class can be used to instantiate new objects."""
    # load the module, will raise ImportError if module cannot be loaded
    klass = None
    if "." in module_path:
        module_name, _, class_name = module_path.rpartition(".")
        m = importlib.import_module(module_name)
        # get the class, will raise AttributeError if class cannot be found
        klass = getattr(m, class_name)
    else:
        klass = globals().get(module_path, locals().get(module_path))
        if module is not None:
            klass = module

        if klass is None and lookup_path:
            # last resort: try to import the class from the lookup path
            m = importlib.import_module(lookup_path)
            klass = getattr(m, module_path)

    if klass is None:
        raise ImportError(f"Cannot retrieve class from path {module_path}.")

    if ensure_class and not inspect.isclass(klass):
        io_utils.raise_deprecation_warning(
            f"`class_from_module_path()` is expected to return a class, "
            f"but {module_path} is not one. "
            f"This warning will be converted "
            f"into an exception in {NEXT_MAJOR_VERSION_FOR_DEPRECATIONS}."
        )
        raise TypeError(f"Object at {module_path} is not a valid class.")<commit_msg>fix class_from_module_path() + add docstring<commit_after>import asyncio
import functools
import importlib
import inspect
import logging
from typing import Text, Dict, Optional, Any, List, Callable, Collection

import rasa.shared.utils.io as io_utils
from rasa.shared.constants import NEXT_MAJOR_VERSION_FOR_DEPRECATIONS


logger = logging.getLogger(__name__)


def class_from_module_path(
    module_path: Text, lookup_path: Optional[Text] = None, ensure_class: bool = True
) -> Any:
    """Given the module name and path of a class, tries to retrieve the class.

    The loaded class can be used to instantiate new objects.

    Args:
        module_path: either an absolute path to a Python class,
                     or the name of the class in the local / global scope.
        lookup_path: a path where to load the class from, if it cannot
                     be found in the local / global scope.
        ensure_class: a boolean that will ensure that the loaded Python class
                      is actually class if True (by default).
    Returns:
        a Python class
    Raises:
        ImportError, in case the Python class cannot be found.
    """
    klass = None
    if "." in module_path:
        module_name, _, class_name = module_path.rpartition(".")
        m = importlib.import_module(module_name)
        klass = getattr(m, class_name, None)
    else:
        klass = globals().get(module_path, locals().get(module_path))

        if klass is None and lookup_path:
            # last resort: try to import the class from the lookup path
            m = importlib.import_module(lookup_path)
            klass = getattr(m, module_path, None)

    if klass is None:
        raise ImportError(f"Cannot retrieve class from path {module_path}.")

    if ensure_class and not inspect.isclass(klass):
        io_utils.raise_deprecation_warning(
            f"`class_from_module_path()` is expected to return a class, "
            f"but {module_path} is not one. "
            f"This warning will be converted "
            f"into an exception in {NEXT_MAJOR_VERSION_FOR_DEPRECATIONS}."
        )
        raise TypeError(f"Object at {module_path} is not a valid class.")
{'fraction_non_alphanumeric': 0.07092907092907093, 'fraction_numerical': 0.0, 'mean_word_length': 2.8106565176022835, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '940200', 'n_tokens_mistral': 1129, 'n_tokens_neox': 1117, 'n_words': 413}