_build_tlz.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import sys
  2. import types
  3. import toolz
  4. from toolz.compatibility import import_module
  5. class TlzLoader(object):
  6. """ Finds and loads ``tlz`` modules when added to sys.meta_path"""
  7. def __init__(self):
  8. self.always_from_toolz = set([
  9. toolz.pipe,
  10. ])
  11. def _load_toolz(self, fullname):
  12. rv = {}
  13. package, dot, submodules = fullname.partition('.')
  14. try:
  15. module_name = ''.join(['cytoolz', dot, submodules])
  16. rv['cytoolz'] = import_module(module_name)
  17. except ImportError:
  18. pass
  19. try:
  20. module_name = ''.join(['toolz', dot, submodules])
  21. rv['toolz'] = import_module(module_name)
  22. except ImportError:
  23. pass
  24. if not rv:
  25. raise ImportError(fullname)
  26. return rv
  27. def find_module(self, fullname, path=None): # pragma: py3 no cover
  28. package, dot, submodules = fullname.partition('.')
  29. if package == 'tlz':
  30. return self
  31. def load_module(self, fullname): # pragma: py3 no cover
  32. if fullname in sys.modules: # pragma: no cover
  33. return sys.modules[fullname]
  34. spec = TlzSpec(fullname, self)
  35. module = self.create_module(spec)
  36. sys.modules[fullname] = module
  37. self.exec_module(module)
  38. return module
  39. def find_spec(self, fullname, path, target=None): # pragma: no cover
  40. package, dot, submodules = fullname.partition('.')
  41. if package == 'tlz':
  42. return TlzSpec(fullname, self)
  43. def create_module(self, spec):
  44. return types.ModuleType(spec.name)
  45. def exec_module(self, module):
  46. toolz_mods = self._load_toolz(module.__name__)
  47. fast_mod = toolz_mods.get('cytoolz') or toolz_mods['toolz']
  48. slow_mod = toolz_mods.get('toolz') or toolz_mods['cytoolz']
  49. module.__dict__.update(toolz.merge(fast_mod.__dict__, module.__dict__))
  50. package = fast_mod.__package__
  51. if package is not None:
  52. package, dot, submodules = package.partition('.')
  53. module.__package__ = ''.join(['tlz', dot, submodules])
  54. if not module.__doc__:
  55. module.__doc__ = fast_mod.__doc__
  56. # show file from toolz during introspection
  57. module.__file__ = slow_mod.__file__
  58. for k, v in fast_mod.__dict__.items():
  59. tv = slow_mod.__dict__.get(k)
  60. try:
  61. hash(tv)
  62. except TypeError:
  63. tv = None
  64. if tv in self.always_from_toolz:
  65. module.__dict__[k] = tv
  66. elif (
  67. isinstance(v, types.ModuleType)
  68. and v.__package__ == fast_mod.__name__
  69. ):
  70. package, dot, submodules = v.__name__.partition('.')
  71. module_name = ''.join(['tlz', dot, submodules])
  72. submodule = import_module(module_name)
  73. module.__dict__[k] = submodule
  74. class TlzSpec(object):
  75. def __init__(self, name, loader):
  76. self.name = name
  77. self.loader = loader
  78. self.origin = None
  79. self.submodule_search_locations = []
  80. self.loader_state = None
  81. self.cached = None
  82. self.parent = None
  83. self.has_location = False
  84. tlz_loader = TlzLoader()
  85. sys.meta_path.append(tlz_loader)
  86. tlz_loader.exec_module(sys.modules['tlz'])