exporters.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. """Ways of dealing with macro-expanded code, e.g. caching or re-serializing it."""
  2. import os
  3. import shutil
  4. from macropy.core import unparse
  5. from py_compile import wr_long
  6. import marshal
  7. import imp
  8. class NullExporter(object):
  9. def export_transformed(self, code, tree, module_name, file_name):
  10. pass
  11. def find(self, file, pathname, description, module_name, package_path):
  12. pass
  13. class SaveExporter(object):
  14. def __init__(self, directory="exported", root=os.getcwd()):
  15. self.root = root
  16. self.directory = directory
  17. shutil.rmtree(directory, ignore_errors=True)
  18. shutil.copytree(root, directory)
  19. def export_transformed(self, code, tree, module_name, file_name):
  20. new_path = os.path.join(
  21. self.root,
  22. self.directory,
  23. os.path.relpath(file_name, self.root)
  24. )
  25. with open(new_path, "w") as f:
  26. f.write(unparse(tree))
  27. def find(self, file, pathname, description, module_name, package_path):
  28. pass
  29. suffix = __debug__ and 'c' or 'o'
  30. class PycExporter(object):
  31. def __init__(self, root=os.getcwd()):
  32. self.root = root
  33. def export_transformed(self, code, tree, module_name, file_name):
  34. f = open(file_name + suffix , 'wb')
  35. f.write('\0\0\0\0')
  36. timestamp = long(os.fstat(f.fileno()).st_mtime)
  37. wr_long(f, timestamp)
  38. marshal.dump(code, f)
  39. f.flush()
  40. f.seek(0, 0)
  41. f.write(imp.get_magic())
  42. def find(self, file, pathname, description, module_name, package_path):
  43. try:
  44. f = open(file.name + suffix, 'rb')
  45. py_time = os.fstat(file.fileno()).st_mtime
  46. pyc_time = os.fstat(f.fileno()).st_mtime
  47. if py_time > pyc_time:
  48. return None
  49. x = imp.load_compiled(module_name, pathname + suffix, f)
  50. return x
  51. except Exception, e:
  52. print e