pyfiles.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import sys
  2. import os
  3. import re
  4. from .compat import load_module_py, load_module_pyc
  5. from mako.template import Template
  6. from mako import exceptions
  7. import tempfile
  8. from .exc import CommandError
  9. def template_to_file(template_file, dest, output_encoding, **kw):
  10. template = Template(filename=template_file)
  11. try:
  12. output = template.render_unicode(**kw).encode(output_encoding)
  13. except:
  14. with tempfile.NamedTemporaryFile(suffix='.txt', delete=False) as ntf:
  15. ntf.write(
  16. exceptions.text_error_template().
  17. render_unicode().encode(output_encoding))
  18. fname = ntf.name
  19. raise CommandError(
  20. "Template rendering failed; see %s for a "
  21. "template-oriented traceback." % fname)
  22. else:
  23. with open(dest, 'wb') as f:
  24. f.write(output)
  25. def coerce_resource_to_filename(fname):
  26. """Interpret a filename as either a filesystem location or as a package
  27. resource.
  28. Names that are non absolute paths and contain a colon
  29. are interpreted as resources and coerced to a file location.
  30. """
  31. if not os.path.isabs(fname) and ":" in fname:
  32. import pkg_resources
  33. fname = pkg_resources.resource_filename(*fname.split(':'))
  34. return fname
  35. def simple_pyc_file_from_path(path):
  36. """Given a python source path, return the so-called
  37. "sourceless" .pyc or .pyo path.
  38. This just a .pyc or .pyo file where the .py file would be.
  39. Even with PEP-3147, which normally puts .pyc/.pyo files in __pycache__,
  40. this use case remains supported as a so-called "sourceless module import".
  41. """
  42. if sys.flags.optimize:
  43. return path + "o" # e.g. .pyo
  44. else:
  45. return path + "c" # e.g. .pyc
  46. def pyc_file_from_path(path):
  47. """Given a python source path, locate the .pyc.
  48. See http://www.python.org/dev/peps/pep-3147/
  49. #detecting-pep-3147-availability
  50. http://www.python.org/dev/peps/pep-3147/#file-extension-checks
  51. """
  52. import imp
  53. has3147 = hasattr(imp, 'get_tag')
  54. if has3147:
  55. return imp.cache_from_source(path)
  56. else:
  57. return simple_pyc_file_from_path(path)
  58. def edit(path):
  59. """Given a source path, run the EDITOR for it"""
  60. import editor
  61. try:
  62. editor.edit(path)
  63. except Exception as exc:
  64. raise CommandError('Error executing editor (%s)' % (exc,))
  65. def load_python_file(dir_, filename):
  66. """Load a file from the given path as a Python module."""
  67. module_id = re.sub(r'\W', "_", filename)
  68. path = os.path.join(dir_, filename)
  69. _, ext = os.path.splitext(filename)
  70. if ext == ".py":
  71. if os.path.exists(path):
  72. module = load_module_py(module_id, path)
  73. elif os.path.exists(simple_pyc_file_from_path(path)):
  74. # look for sourceless load
  75. module = load_module_pyc(
  76. module_id, simple_pyc_file_from_path(path))
  77. else:
  78. raise ImportError("Can't find Python file %s" % path)
  79. elif ext in (".pyc", ".pyo"):
  80. module = load_module_pyc(module_id, path)
  81. del sys.modules[module_id]
  82. return module