Advertisement
Guest User

Untitled

a guest
May 22nd, 2015
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.91 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. #
  4. # Copyright (c) 2009 Doug Hellmann All rights reserved.
  5. #
  6. """
  7. """
  8. #end_pymotw_header
  9.  
  10. import contextlib
  11. import imp
  12. import os
  13. import shelve
  14. import sys
  15.  
  16.  
  17. def _mk_init_name(fullname):
  18. """Return the name of the __init__ module
  19. for a given package name.
  20. """
  21. if fullname.endswith('.__init__'):
  22. return fullname
  23. return fullname + '.__init__'
  24.  
  25.  
  26. def _get_key_name(fullname, db):
  27. """Look in an open shelf for fullname or
  28. fullname.__init__, return the name found.
  29. """
  30. if fullname in db:
  31. return fullname
  32. init_name = _mk_init_name(fullname)
  33. if init_name in db:
  34. return init_name
  35. return None
  36.  
  37.  
  38. class ShelveFinder(object):
  39. """Find modules collected in a shelve archive."""
  40.  
  41. def __init__(self, path_entry):
  42. if not os.path.isfile(path_entry):
  43. raise ImportError
  44. try:
  45. # Test the path_entry to see if it is a valid shelf
  46. with contextlib.closing(shelve.open(path_entry, 'r')):
  47. pass
  48. except Exception, e:
  49. raise ImportError(str(e))
  50. else:
  51. print 'shelf added to import path:', path_entry
  52. self.path_entry = path_entry
  53. return
  54.  
  55. def __str__(self):
  56. return '<%s for "%s">' % (self.__class__.__name__,
  57. self.path_entry)
  58.  
  59. def find_module(self, fullname, path=None):
  60. path = path or self.path_entry
  61. print '\nlooking for "%s"\n in %s' % (fullname, path)
  62. with contextlib.closing(shelve.open(self.path_entry, 'r')
  63. ) as db:
  64. key_name = _get_key_name(fullname, db)
  65. if key_name:
  66. print ' found it as %s' % key_name
  67. return ShelveLoader(path)
  68. print ' not found'
  69. return None
  70.  
  71.  
  72. class ShelveLoader(object):
  73. """Load source for modules from shelve databases."""
  74.  
  75. def __init__(self, path_entry):
  76. self.path_entry = path_entry
  77. return
  78.  
  79. def _get_filename(self, fullname):
  80. # Make up a fake filename that starts with the path entry
  81. # so pkgutil.get_data() works correctly.
  82. return os.path.join(self.path_entry, fullname)
  83.  
  84. def get_source(self, fullname):
  85. print 'loading source for "%s" from shelf' % fullname
  86. try:
  87. with contextlib.closing(shelve.open(self.path_entry, 'r')
  88. ) as db:
  89. key_name = _get_key_name(fullname, db)
  90. if key_name:
  91. return db[key_name]
  92. raise ImportError('could not find source for %s' %
  93. fullname)
  94. except Exception, e:
  95. print 'could not load source:', e
  96. raise ImportError(str(e))
  97.  
  98. def get_code(self, fullname):
  99. source = self.get_source(fullname)
  100. print 'compiling code for "%s"' % fullname
  101. return compile(source, self._get_filename(fullname),
  102. 'exec', dont_inherit=True)
  103.  
  104. def get_data(self, path):
  105. print 'looking for data\n in %s\n for "%s"' % \
  106. (self.path_entry, path)
  107. if not path.startswith(self.path_entry):
  108. raise IOError
  109. path = path[len(self.path_entry)+1:]
  110. key_name = 'data:' + path
  111. try:
  112. with contextlib.closing(shelve.open(self.path_entry, 'r')
  113. ) as db:
  114. return db[key_name]
  115. except Exception, e:
  116. # Convert all errors to IOError
  117. raise IOError
  118.  
  119. def is_package(self, fullname):
  120. init_name = _mk_init_name(fullname)
  121. with contextlib.closing(shelve.open(self.path_entry, 'r')
  122. ) as db:
  123. return init_name in db
  124.  
  125. def load_module(self, fullname):
  126. source = self.get_source(fullname)
  127.  
  128. if fullname in sys.modules:
  129. print 'reusing existing module from import of "%s"' % \
  130. fullname
  131. mod = sys.modules[fullname]
  132. else:
  133. print 'creating a new module object for "%s"' % fullname
  134. mod = sys.modules.setdefault(fullname,
  135. imp.new_module(fullname))
  136.  
  137. # Set a few properties required by PEP 302
  138. mod.__file__ = self._get_filename(fullname)
  139. mod.__name__ = fullname
  140. mod.__path__ = self.path_entry
  141. mod.__loader__ = self
  142. mod.__package__ = '.'.join(fullname.split('.')[:-1])
  143.  
  144. if self.is_package(fullname):
  145. print 'adding path for package'
  146. # Set __path__ for packages
  147. # so we can find the sub-modules.
  148. mod.__path__ = [ self.path_entry ]
  149. else:
  150. print 'imported as regular module'
  151.  
  152. print 'execing source...'
  153. exec source in mod.__dict__
  154. print 'done'
  155. return mod
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement