Files
wehub-resource-sync dc6079821b
CI Github Actions / Run Tests (push) Waiting to run
Automatic PR Merger / mergepal (push) Waiting to run
Semgrep / Semgrep Workflow Security Scan (push) Waiting to run
Docs Tests / Check for file changes (push) Has been cancelled
Docs Tests / Test Documentation (push) Has been cancelled
Docs Tests / Documentation Linting Checks (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.10, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.8, test-policies) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-performance) (push) Has been cancelled
Continuous Integration / Run Tests (windows-2022, 3.9, test-policies) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.9) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.10) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.8) (push) Has been cancelled
Continuous Integration / Run Flaky Tests (windows-2022, 3.9) (push) Has been cancelled
Continuous Integration / Check for file changes (push) Has been cancelled
Continuous Integration / Wait for docs tests (push) Has been cancelled
Continuous Integration / Code Quality (push) Has been cancelled
Continuous Integration / Check for changelog (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-cli) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-core-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-full-model-training) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-featurizers) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-predictors) (push) Has been cancelled
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-other-unit-tests) (push) Has been cancelled
Continuous Integration / Upload coverage reports to codeclimate (push) Has been cancelled
Continuous Integration / Run Non-Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Run Broker Integration Tests (push) Has been cancelled
Continuous Integration / Run Sequential Integration Tests (push) Has been cancelled
Continuous Integration / Build Docker base images and setup environment (push) Has been cancelled
Continuous Integration / Build Docker (default) (push) Has been cancelled
Continuous Integration / Build Docker (full) (push) Has been cancelled
Continuous Integration / Build Docker (mitie-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-de) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-en) (push) Has been cancelled
Continuous Integration / Build Docker (spacy-it) (push) Has been cancelled
Continuous Integration / Deploy to PyPI (push) Has been cancelled
Continuous Integration / Notify Slack & Publish Release Notes (push) Has been cancelled
Publish Documentation / Evaluate release tag (push) Has been cancelled
Publish Documentation / Prebuild Docs (push) Has been cancelled
Publish Documentation / Preview Docs (push) Has been cancelled
Publish Documentation / Check for file changes (push) Has been cancelled
Publish Documentation / Publish Docs (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:24:47 +08:00

273 lines
8.5 KiB
Python

import asyncio
import functools
import importlib
import inspect
import logging
from typing import Text, Dict, Optional, Any, List, Callable, Collection, Type
from rasa.shared.exceptions import RasaException
logger = logging.getLogger(__name__)
def class_from_module_path(
module_path: Text, lookup_path: Optional[Text] = None
) -> Type:
"""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.
Returns:
a Python class
Raises:
ImportError, in case the Python class cannot be found.
RasaException, in case the imported result is something other than a class
"""
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)
elif lookup_path:
# 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 not inspect.isclass(klass):
raise RasaException(
f"`class_from_module_path()` is expected to return a class, "
f"but for {module_path} we got a {type(klass)}."
)
return klass
def all_subclasses(cls: Any) -> List[Any]:
"""Returns all known (imported) subclasses of a class."""
classes = cls.__subclasses__() + [
g for s in cls.__subclasses__() for g in all_subclasses(s)
]
return [subclass for subclass in classes if not inspect.isabstract(subclass)]
def module_path_from_instance(inst: Any) -> Text:
"""Return the module path of an instance's class."""
return inst.__module__ + "." + inst.__class__.__name__
def sort_list_of_dicts_by_first_key(dicts: List[Dict]) -> List[Dict]:
"""Sorts a list of dictionaries by their first key."""
return sorted(dicts, key=lambda d: list(d.keys())[0])
def lazy_property(function: Callable) -> Any:
"""Allows to avoid recomputing a property over and over.
The result gets stored in a local var. Computation of the property
will happen once, on the first call of the property. All
succeeding calls will use the value stored in the private property.
"""
attr_name = "_lazy_" + function.__name__
def _lazyprop(self: Any) -> Any:
if not hasattr(self, attr_name):
setattr(self, attr_name, function(self))
return getattr(self, attr_name)
return property(_lazyprop)
def cached_method(f: Callable[..., Any]) -> Callable[..., Any]:
"""Caches method calls based on the call's `args` and `kwargs`.
Works for `async` and `sync` methods. Don't apply this to functions.
Args:
f: The decorated method whose return value should be cached.
Returns:
The return value which the method gives for the first call with the given
arguments.
"""
assert "self" in arguments_of(f), "This decorator can only be used with methods."
class Cache:
"""Helper class to abstract the caching details."""
def __init__(self, caching_object: object, args: Any, kwargs: Any) -> None:
self.caching_object = caching_object
self.cache = getattr(caching_object, self._cache_name(), {})
# noinspection PyUnresolvedReferences
self.cache_key = functools._make_key(args, kwargs, typed=False)
def _cache_name(self) -> Text:
return f"_cached_{self.caching_object.__class__.__name__}_{f.__name__}"
def is_cached(self) -> bool:
return self.cache_key in self.cache
def cache_result(self, result: Any) -> None:
self.cache[self.cache_key] = result
setattr(self.caching_object, self._cache_name(), self.cache)
def cached_result(self) -> Any:
return self.cache[self.cache_key]
if asyncio.iscoroutinefunction(f):
@functools.wraps(f)
async def decorated(self: object, *args: Any, **kwargs: Any) -> Any:
cache = Cache(self, args, kwargs)
if not cache.is_cached():
# Store the task immediately so that other concurrent calls of the
# method can re-use the same task and don't schedule a second execution.
to_cache = asyncio.ensure_future(f(self, *args, **kwargs))
cache.cache_result(to_cache)
return await cache.cached_result()
return decorated
else:
@functools.wraps(f)
def decorated(self: object, *args: Any, **kwargs: Any) -> Any:
cache = Cache(self, args, kwargs)
if not cache.is_cached():
to_cache = f(self, *args, **kwargs)
cache.cache_result(to_cache)
return cache.cached_result()
return decorated
def transform_collection_to_sentence(collection: Collection[Text]) -> Text:
"""Transforms e.g. a list like ['A', 'B', 'C'] into a sentence 'A, B and C'."""
x = list(collection)
if len(x) >= 2:
return ", ".join(map(str, x[:-1])) + " and " + x[-1]
return "".join(collection)
def minimal_kwargs(
kwargs: Dict[Text, Any], func: Callable, excluded_keys: Optional[List] = None
) -> Dict[Text, Any]:
"""Returns only the kwargs which are required by a function. Keys, contained in
the exception list, are not included.
Args:
kwargs: All available kwargs.
func: The function which should be called.
excluded_keys: Keys to exclude from the result.
Returns:
Subset of kwargs which are accepted by `func`.
"""
excluded_keys = excluded_keys or []
possible_arguments = arguments_of(func)
return {
k: v
for k, v in kwargs.items()
if k in possible_arguments and k not in excluded_keys
}
def mark_as_experimental_feature(feature_name: Text) -> None:
"""Warns users that they are using an experimental feature."""
logger.warning(
f"The {feature_name} is currently experimental and might change or be "
"removed in the future 🔬 Please share your feedback on it in the "
"forum (https://forum.rasa.com) to help us make this feature "
"ready for production."
)
def arguments_of(func: Callable) -> List[Text]:
"""Return the parameters of the function `func` as a list of names."""
import inspect
return list(inspect.signature(func).parameters.keys())
def extract_duplicates(list1: List[Any], list2: List[Any]) -> List[Any]:
"""Extracts duplicates from two lists."""
if list1:
dict1 = {
(sorted(list(i.keys()))[0] if isinstance(i, dict) else i): i for i in list1
}
else:
dict1 = {}
if list2:
dict2 = {
(sorted(list(i.keys()))[0] if isinstance(i, dict) else i): i for i in list2
}
else:
dict2 = {}
set1 = set(dict1.keys())
set2 = set(dict2.keys())
dupes = set1.intersection(set2)
return sorted(list(dupes))
def clean_duplicates(dupes: Dict[Text, Any]) -> Dict[Text, Any]:
"""Removes keys for empty values."""
duplicates = dupes.copy()
for k in dupes:
if not dupes[k]:
duplicates.pop(k)
return duplicates
def merge_dicts(
tempDict1: Dict[Text, Any],
tempDict2: Dict[Text, Any],
override_existing_values: bool = False,
) -> Dict[Text, Any]:
"""Merges two dicts."""
if override_existing_values:
merged_dicts, b = tempDict1.copy(), tempDict2.copy()
else:
merged_dicts, b = tempDict2.copy(), tempDict1.copy()
merged_dicts.update(b)
return merged_dicts
def merge_lists(
list1: List[Any], list2: List[Any], override: bool = False
) -> List[Any]:
"""Merges two lists."""
return sorted(list(set(list1 + list2)))
def merge_lists_of_dicts(
dict_list1: List[Dict],
dict_list2: List[Dict],
override_existing_values: bool = False,
) -> List[Dict]:
"""Merges two dict lists."""
dict1 = {
(sorted(list(i.keys()))[0] if isinstance(i, dict) else i): i for i in dict_list1
}
dict2 = {
(sorted(list(i.keys()))[0] if isinstance(i, dict) else i): i for i in dict_list2
}
merged_dicts = merge_dicts(dict1, dict2, override_existing_values)
return list(merged_dicts.values())