You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							69 lines
						
					
					
						
							2.3 KiB
						
					
					
				
			
		
		
	
	
							69 lines
						
					
					
						
							2.3 KiB
						
					
					
				# util/_preloaded.py
 | 
						|
# Copyright (C) 2005-2022 the SQLAlchemy authors and contributors
 | 
						|
# <see AUTHORS file>
 | 
						|
#
 | 
						|
# This module is part of SQLAlchemy and is released under
 | 
						|
# the MIT License: https://www.opensource.org/licenses/mit-license.php
 | 
						|
 | 
						|
"""supplies the "preloaded" registry to resolve circular module imports at
 | 
						|
runtime.
 | 
						|
 | 
						|
"""
 | 
						|
 | 
						|
import sys
 | 
						|
 | 
						|
from . import compat
 | 
						|
 | 
						|
 | 
						|
class _ModuleRegistry:
 | 
						|
    """Registry of modules to load in a package init file.
 | 
						|
 | 
						|
    To avoid potential thread safety issues for imports that are deferred
 | 
						|
    in a function, like https://bugs.python.org/issue38884, these modules
 | 
						|
    are added to the system module cache by importing them after the packages
 | 
						|
    has finished initialization.
 | 
						|
 | 
						|
    A global instance is provided under the name :attr:`.preloaded`. Use
 | 
						|
    the function :func:`.preload_module` to register modules to load and
 | 
						|
    :meth:`.import_prefix` to load all the modules that start with the
 | 
						|
    given path.
 | 
						|
 | 
						|
    While the modules are loaded in the global module cache, it's advisable
 | 
						|
    to access them using :attr:`.preloaded` to ensure that it was actually
 | 
						|
    registered. Each registered module is added to the instance ``__dict__``
 | 
						|
    in the form `<package>_<module>`, omitting ``sqlalchemy`` from the package
 | 
						|
    name. Example: ``sqlalchemy.sql.util`` becomes ``preloaded.sql_util``.
 | 
						|
    """
 | 
						|
 | 
						|
    def __init__(self, prefix="sqlalchemy."):
 | 
						|
        self.module_registry = set()
 | 
						|
        self.prefix = prefix
 | 
						|
 | 
						|
    def preload_module(self, *deps):
 | 
						|
        """Adds the specified modules to the list to load.
 | 
						|
 | 
						|
        This method can be used both as a normal function and as a decorator.
 | 
						|
        No change is performed to the decorated object.
 | 
						|
        """
 | 
						|
        self.module_registry.update(deps)
 | 
						|
        return lambda fn: fn
 | 
						|
 | 
						|
    def import_prefix(self, path):
 | 
						|
        """Resolve all the modules in the registry that start with the
 | 
						|
        specified path.
 | 
						|
        """
 | 
						|
        for module in self.module_registry:
 | 
						|
            if self.prefix:
 | 
						|
                key = module.split(self.prefix)[-1].replace(".", "_")
 | 
						|
            else:
 | 
						|
                key = module
 | 
						|
            if (
 | 
						|
                not path or module.startswith(path)
 | 
						|
            ) and key not in self.__dict__:
 | 
						|
                compat.import_(module, globals(), locals())
 | 
						|
                self.__dict__[key] = sys.modules[module]
 | 
						|
 | 
						|
 | 
						|
preloaded = _ModuleRegistry()
 | 
						|
preload_module = preloaded.preload_module
 |