2019-06-19 22:50:40 +00:00
|
|
|
import sys
|
|
|
|
from collections import defaultdict
|
|
|
|
import six
|
|
|
|
|
|
|
|
if six.PY2:
|
|
|
|
# python2.x
|
|
|
|
import __builtin__ as builtins
|
|
|
|
else:
|
|
|
|
# python3.x
|
|
|
|
import builtins
|
|
|
|
|
|
|
|
|
|
|
|
class PostImportHookPatching(object):
|
|
|
|
_patched = False
|
|
|
|
_post_import_hooks = defaultdict(list)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def _init_hook():
|
|
|
|
if PostImportHookPatching._patched:
|
|
|
|
return
|
|
|
|
PostImportHookPatching._patched = True
|
|
|
|
|
|
|
|
if six.PY2:
|
|
|
|
# python2.x
|
|
|
|
builtins.__org_import__ = builtins.__import__
|
2020-04-09 10:12:50 +00:00
|
|
|
builtins.__import__ = PostImportHookPatching.__patched_import2
|
2019-06-19 22:50:40 +00:00
|
|
|
else:
|
|
|
|
# python3.x
|
|
|
|
builtins.__org_import__ = builtins.__import__
|
2020-04-09 10:12:50 +00:00
|
|
|
builtins.__import__ = PostImportHookPatching.__patched_import3
|
2019-06-19 22:50:40 +00:00
|
|
|
|
|
|
|
@staticmethod
|
2020-04-09 10:12:50 +00:00
|
|
|
def __patched_import2(name, globals={}, locals={}, fromlist=[], level=-1):
|
2019-06-19 22:50:40 +00:00
|
|
|
already_imported = name in sys.modules
|
|
|
|
mod = builtins.__org_import__(
|
|
|
|
name,
|
|
|
|
globals=globals,
|
|
|
|
locals=locals,
|
|
|
|
fromlist=fromlist,
|
|
|
|
level=level)
|
|
|
|
|
|
|
|
if not already_imported and name in PostImportHookPatching._post_import_hooks:
|
|
|
|
for hook in PostImportHookPatching._post_import_hooks[name]:
|
|
|
|
hook()
|
|
|
|
return mod
|
|
|
|
|
|
|
|
@staticmethod
|
2020-04-09 10:12:50 +00:00
|
|
|
def __patched_import3(name, globals=None, locals=None, fromlist=(), level=0):
|
2020-01-10 11:35:07 +00:00
|
|
|
name_parts = name.split('.')
|
|
|
|
base_name = name_parts[0]
|
|
|
|
second_name = '.'.join(name_parts[:2]) if len(name_parts) > 1 else None
|
|
|
|
base_already_imported = (not base_name) or (base_name in sys.modules)
|
|
|
|
second_already_imported = (not second_name) or (second_name in sys.modules)
|
2019-06-19 22:50:40 +00:00
|
|
|
mod = builtins.__org_import__(
|
|
|
|
name,
|
|
|
|
globals=globals,
|
|
|
|
locals=locals,
|
|
|
|
fromlist=fromlist,
|
|
|
|
level=level)
|
2020-01-10 11:35:07 +00:00
|
|
|
if not base_already_imported and base_name in PostImportHookPatching._post_import_hooks:
|
2019-10-05 22:43:37 +00:00
|
|
|
for hook in PostImportHookPatching._post_import_hooks[base_name]:
|
2019-06-19 22:50:40 +00:00
|
|
|
hook()
|
2020-01-10 11:35:07 +00:00
|
|
|
if not second_already_imported and second_name in PostImportHookPatching._post_import_hooks:
|
|
|
|
for hook in PostImportHookPatching._post_import_hooks[second_name]:
|
|
|
|
hook()
|
2019-06-19 22:50:40 +00:00
|
|
|
return mod
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def add_on_import(name, func):
|
|
|
|
PostImportHookPatching._init_hook()
|
2019-09-03 09:58:01 +00:00
|
|
|
if name not in PostImportHookPatching._post_import_hooks or \
|
2019-06-19 22:50:40 +00:00
|
|
|
func not in PostImportHookPatching._post_import_hooks[name]:
|
|
|
|
PostImportHookPatching._post_import_hooks[name].append(func)
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def remove_on_import(name, func):
|
2020-07-30 12:07:25 +00:00
|
|
|
if name in PostImportHookPatching._post_import_hooks and \
|
|
|
|
func in PostImportHookPatching._post_import_hooks[name]:
|
2019-06-19 22:50:40 +00:00
|
|
|
PostImportHookPatching._post_import_hooks[name].remove(func)
|