__init__.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import sys
  2. class VendorImporter:
  3. """
  4. A PEP 302 meta path importer for finding optionally-vendored
  5. or otherwise naturally-installed packages from root_name.
  6. """
  7. def __init__(self, root_name, vendored_names=(), vendor_pkg=None):
  8. self.root_name = root_name
  9. self.vendored_names = set(vendored_names)
  10. self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor')
  11. @property
  12. def search_path(self):
  13. """
  14. Search first the vendor package then as a natural package.
  15. """
  16. yield self.vendor_pkg + '.'
  17. yield ''
  18. def find_module(self, fullname, path=None):
  19. """
  20. Return self when fullname starts with root_name and the
  21. target module is one vendored through this importer.
  22. """
  23. root, base, target = fullname.partition(self.root_name + '.')
  24. if root:
  25. return
  26. if not any(map(target.startswith, self.vendored_names)):
  27. return
  28. return self
  29. def load_module(self, fullname):
  30. """
  31. Iterate over the search path to locate and load fullname.
  32. """
  33. root, base, target = fullname.partition(self.root_name + '.')
  34. for prefix in self.search_path:
  35. try:
  36. extant = prefix + target
  37. __import__(extant)
  38. mod = sys.modules[extant]
  39. sys.modules[fullname] = mod
  40. return mod
  41. except ImportError:
  42. pass
  43. else:
  44. raise ImportError(
  45. "The '{target}' package is required; "
  46. "normally this is bundled with this package so if you get "
  47. "this warning, consult the packager of your "
  48. "distribution.".format(**locals())
  49. )
  50. def install(self):
  51. """
  52. Install this importer into sys.meta_path if not already present.
  53. """
  54. if self not in sys.meta_path:
  55. sys.meta_path.append(self)
  56. names = 'packaging', 'pyparsing', 'six', 'appdirs'
  57. VendorImporter(__name__, names).install()