pgadmin4/web/pgadmin/utils/dynamic_registry/__init__.py
2024-01-01 14:13:48 +05:30

106 lines
2.9 KiB
Python

##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2024, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
#########################################################################
"""This file contains functions for creating dynamic registry meta class."""
from abc import ABCMeta
# Constructor
def __constructor(self, name, bases, kwargs):
# Register this type of auth_sources, based on the module name
# Avoid registering the BaseAuthentication itself
cls = self.__class__
entry = self._decorate_cls_name(name, kwargs)
if cls._registry is None:
cls._registry = dict()
else:
if entry in cls._registry:
raise RuntimeError((
"{} class is already been registered with {} "
"(package: {})"
).format(entry, cls._name_, cls._package_))
if cls._initialized is True:
cls._registry[entry] = self
cls._initialized = True
ABCMeta.__init__(self, name, bases, kwargs)
@classmethod
def __get(cls, name, **kwargs):
if name in cls._objects:
return cls._objects[name]
if cls._registry is not None and name in cls._registry:
cls._objects[name] = (cls._registry[name])(**kwargs)
return cls._objects[name]
raise NotImplementedError(
"{} '{}' has not been implemented.".format(cls.__name__, name)
)
@classmethod
def __load_modules(cls, app=None):
# Initialize the registry only if it has not yet been initialized
if cls._registry is None:
cls._registry = dict()
from importlib import import_module
from werkzeug.utils import find_modules
for module_name in find_modules(cls._package_, True):
module = import_module(module_name)
if "init_app" in module.__dict__.keys():
module.__dict__["init_app"](app)
def __get_module_name(self, name, kwargs):
module_name = kwargs["__module__"]
length = len(self._package_) + 1
if len(module_name) > length and module_name.startswith(self._package_):
return module_name[length:]
return module_name
def __get_class_name(self, name, kwargs):
return name
def create_registry_metaclass(name, package, load_modules=__load_modules,
decorate_as_module=True):
class_params = {
# constructor
"__init__": __constructor,
# Class members
"_registry": None,
"_objects": dict(),
"_package_": package,
# Member functions
"get": __get,
"load_modules": load_modules,
"_name_": name,
"_decorate_cls_name": __get_module_name
if decorate_as_module is True else __get_class_name,
"_initialized": False,
}
# Creating class dynamically
return type(package + "." + name, (ABCMeta, ), class_params)