src/dubbo/extension/extension_loader.py (31 lines of code) (raw):

# # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import importlib from typing import Any from dubbo.classes import SingletonBase from dubbo.extension import registries as registries_module class ExtensionError(Exception): """ Extension error. """ def __init__(self, message: str): """ Initialize the extension error. :param message: The error message. :type message: str """ super().__init__(message) class ExtensionLoader(SingletonBase): """ Singleton class for loading extension implementations. """ def __init__(self): """ Initialize the extension loader. Load all the registries from the registries module. """ if not hasattr(self, "_initialized"): # Ensure __init__ runs only once self._registries = {} for name in registries_module.registries: registry = getattr(registries_module, name) self._registries[registry.interface] = registry.impls self._initialized = True def get_extension(self, interface: Any, impl_name: str) -> Any: """ Get the extension implementation for the interface. :param interface: Interface class. :type interface: Any :param impl_name: Implementation name. :type impl_name: str :return: Extension implementation class. :rtype: Any :raises ExtensionError: If the interface or implementation is not found. """ # Get the registry for the interface impls = self._registries.get(interface) if not impls: raise ExtensionError(f"Interface '{interface.__name__}' is not supported.") # Get the full name of the implementation full_name = impls.get(impl_name) if not full_name: raise ExtensionError(f"Implementation '{impl_name}' for interface '{interface.__name__}' is not exist.") try: # Split the full name into module and class module_name, class_name = full_name.rsplit(".", 1) # Load the module and get the class module = importlib.import_module(module_name) subclass = getattr(module, class_name) # Return the subclass return subclass except Exception as e: raise ExtensionError( f"Failed to load extension '{impl_name}' for interface '{interface.__name__}'. \nDetail: {e}" )