importers.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import importlib.abc, importlib.util
  2. import os.path
  3. import zipimport
  4. class MetaPathFinder(importlib.abc.MetaPathFinder):
  5. def add_file(self, filename, modulename=None):
  6. if not hasattr(self, "_registered_files"):
  7. self._registered_files = {}
  8. if not os.path.exists(filename):
  9. raise RuntimeError("'%s' must be exist!" % filename)
  10. if modulename is None:
  11. modulename = os.path.splitext(os.path.basename(filename))[0]
  12. unique_modulename = modulename
  13. uniqifier = 1
  14. while unique_modulename in self._registered_files:
  15. unique_modulename = "%s%d" % (modulename, uniqifier)
  16. uniqifier += 1
  17. self._registered_files[unique_modulename] = filename
  18. return unique_modulename
  19. def find_spec(self, fullname, path, target=None):
  20. if not hasattr(self, "_registered_files"):
  21. return None
  22. if fullname in self._registered_files:
  23. modulename = fullname
  24. filename = self._registered_files[fullname]
  25. if os.path.splitext(os.path.basename(filename))[1].lower() == ".zip":
  26. loader = zipimport.zipimporter(filename)
  27. spec = importlib.util.spec_from_loader(modulename, loader)
  28. else:
  29. spec = importlib.util.spec_from_file_location(modulename, filename)
  30. return spec
  31. return None
  32. _path_finder_instance = MetaPathFinder()
  33. def add_file(filename, modulename=None):
  34. global _path_finder_instance
  35. return _path_finder_instance.add_file(filename, modulename)
  36. def _run_once(f):
  37. def func(*args, **kwargs):
  38. if not f.has_run:
  39. f.has_run = True
  40. return f(*args, **kwargs)
  41. f.has_run = False
  42. return func
  43. @_run_once
  44. def install_pathfinder():
  45. global _path_finder_instance
  46. import sys
  47. sys.meta_path.insert(0, _path_finder_instance)