deploy-ng: Fix to handle utf-8 Python source files on all systems

NOTE: This only works for Python 3
This commit is contained in:
Mitchell Stokes 2018-02-12 17:47:55 -08:00
parent 73fd10281b
commit 8f919b7e40

View File

@ -8,7 +8,7 @@ import marshal
import imp import imp
import platform import platform
import struct import struct
from io import StringIO, BytesIO, TextIOWrapper import io
import distutils.sysconfig as sysconf import distutils.sysconfig as sysconf
import zipfile import zipfile
@ -1143,11 +1143,14 @@ class Freezer:
stuff = ("", "rb", imp.PY_COMPILED) stuff = ("", "rb", imp.PY_COMPILED)
self.mf.load_module(mdef.moduleName, fp, pathname, stuff) self.mf.load_module(mdef.moduleName, fp, pathname, stuff)
else: else:
if mdef.text:
fp = StringIO(mdef.text)
else:
fp = open(pathname, 'U')
stuff = ("", "r", imp.PY_SOURCE) stuff = ("", "r", imp.PY_SOURCE)
if mdef.text:
fp = io.StringIO(mdef.text)
elif sys.version_info >= (3, 0):
fp = open(pathname, 'rb')
stuff = ("", "rb", imp.PY_SOURCE)
else:
fp = open(pathname, 'r')
self.mf.load_module(mdef.moduleName, fp, pathname, stuff) self.mf.load_module(mdef.moduleName, fp, pathname, stuff)
if tempPath: if tempPath:
@ -1910,7 +1913,7 @@ class Freezer:
if data.startswith(b'MZ'): if data.startswith(b'MZ'):
# A Windows PE file. # A Windows PE file.
pe = pefile.PEFile() pe = pefile.PEFile()
pe.read(BytesIO(data)) pe.read(io.BytesIO(data))
addr = pe.get_export_address(symbol_name) addr = pe.get_export_address(symbol_name)
if addr is not None: if addr is not None:
# We found it, return its offset in the file. # We found it, return its offset in the file.
@ -2162,8 +2165,8 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
Returns None if the module could not be found. """ Returns None if the module could not be found. """
if os.path.isfile(path): if os.path.isfile(path):
if sys.version_info >= (3, 0) and 'b' not in mode: if 'b' not in mode:
return open(path, mode, encoding='utf8') return io.open(path, mode, encoding='utf8')
else: else:
return open(path, mode) return open(path, mode)
@ -2189,7 +2192,7 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
return None return None
if sys.version_info >= (3, 0) and 'b' not in mode: if sys.version_info >= (3, 0) and 'b' not in mode:
return TextIOWrapper(fp, encoding='utf8') return io.TextIOWrapper(fp, encoding='utf8')
return fp return fp
# Look at the parent directory. # Look at the parent directory.
@ -2198,6 +2201,43 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
return None return None
def load_module(self, fqname, fp, pathname, file_info):
"""Copied from ModuleFinder.load_module with fixes to handle sending bytes
to compile() for PY_SOURCE types. Sending bytes to compile allows it to
handle file encodings."""
if sys.version_info < (3, 0):
# fallback to original version for Python 2
return super.load_module(fqname, fp, pathname, file_info)
suffix, mode, type = file_info
self.msgin(2, "load_module", fqname, fp and "fp", pathname)
if type == imp.PKG_DIRECTORY:
m = self.load_package(fqname, pathname)
self.msgout(2, "load_module ->", m)
return m
if type == imp.PY_SOURCE:
newline = b'\n' if 'b' in mode else '\n'
co = compile(fp.read()+newline, pathname, 'exec')
elif type == imp.PY_COMPILED:
try:
marshal_data = importlib._bootstrap_external._validate_bytecode_header(fp.read())
except ImportError as exc:
self.msgout(2, "raise ImportError: " + str(exc), pathname)
raise
co = marshal.loads(marshal_data)
else:
co = None
m = self.add_module(fqname)
m.__file__ = pathname
if co:
if self.replace_paths:
co = self.replace_paths_in_code(co)
m.__code__ = co
self.scan_code(co, m)
self.msgout(2, "load_module ->", m)
return m
def find_module(self, name, path=None, parent=None): def find_module(self, name, path=None, parent=None):
""" Finds a module with the indicated name on the given search path """ Finds a module with the indicated name on the given search path
(or self.path if None). Returns a tuple like (fp, path, stuff), where (or self.path if None). Returns a tuple like (fp, path, stuff), where