Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/sqlalchemy/util/_preloaded.py: 95%
20 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:35 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:35 +0000
1# util/_preloaded.py
2# Copyright (C) 2005-2023 the SQLAlchemy authors and contributors
3# <see AUTHORS file>
4#
5# This module is part of SQLAlchemy and is released under
6# the MIT License: https://www.opensource.org/licenses/mit-license.php
8"""supplies the "preloaded" registry to resolve circular module imports at
9runtime.
11"""
13import sys
15from . import compat
18class _ModuleRegistry:
19 """Registry of modules to load in a package init file.
21 To avoid potential thread safety issues for imports that are deferred
22 in a function, like https://bugs.python.org/issue38884, these modules
23 are added to the system module cache by importing them after the packages
24 has finished initialization.
26 A global instance is provided under the name :attr:`.preloaded`. Use
27 the function :func:`.preload_module` to register modules to load and
28 :meth:`.import_prefix` to load all the modules that start with the
29 given path.
31 While the modules are loaded in the global module cache, it's advisable
32 to access them using :attr:`.preloaded` to ensure that it was actually
33 registered. Each registered module is added to the instance ``__dict__``
34 in the form `<package>_<module>`, omitting ``sqlalchemy`` from the package
35 name. Example: ``sqlalchemy.sql.util`` becomes ``preloaded.sql_util``.
36 """
38 def __init__(self, prefix="sqlalchemy."):
39 self.module_registry = set()
40 self.prefix = prefix
42 def preload_module(self, *deps):
43 """Adds the specified modules to the list to load.
45 This method can be used both as a normal function and as a decorator.
46 No change is performed to the decorated object.
47 """
48 self.module_registry.update(deps)
49 return lambda fn: fn
51 def import_prefix(self, path):
52 """Resolve all the modules in the registry that start with the
53 specified path.
54 """
55 for module in self.module_registry:
56 if self.prefix:
57 key = module.split(self.prefix)[-1].replace(".", "_")
58 else:
59 key = module
60 if (
61 not path or module.startswith(path)
62 ) and key not in self.__dict__:
63 compat.import_(module, globals(), locals())
64 self.__dict__[key] = sys.modules[module]
67preloaded = _ModuleRegistry()
68preload_module = preloaded.preload_module