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

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 

7 

8"""supplies the "preloaded" registry to resolve circular module imports at 

9runtime. 

10 

11""" 

12 

13import sys 

14 

15from . import compat 

16 

17 

18class _ModuleRegistry: 

19 """Registry of modules to load in a package init file. 

20 

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. 

25 

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. 

30 

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 """ 

37 

38 def __init__(self, prefix="sqlalchemy."): 

39 self.module_registry = set() 

40 self.prefix = prefix 

41 

42 def preload_module(self, *deps): 

43 """Adds the specified modules to the list to load. 

44 

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 

50 

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] 

65 

66 

67preloaded = _ModuleRegistry() 

68preload_module = preloaded.preload_module