Fix python3 errors from string and byte concatenation (#13141)

This commit is contained in:
Patrick Gartung 2019-10-11 03:21:45 -05:00 committed by GitHub
parent fd97f5c491
commit d248b0e9d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 32 deletions

View file

@ -461,10 +461,11 @@ def relocate_package(workdir, spec, allow_root):
Relocate the given package Relocate the given package
""" """
buildinfo = read_buildinfo_file(workdir) buildinfo = read_buildinfo_file(workdir)
new_path = spack.store.layout.root new_path = str(spack.store.layout.root)
new_prefix = spack.paths.prefix new_prefix = str(spack.paths.prefix)
old_path = buildinfo['buildpath'] old_path = str(buildinfo['buildpath'])
old_prefix = buildinfo.get('spackprefix', '/not/in/buildinfo/dictionary') old_prefix = str(buildinfo.get('spackprefix',
'/not/in/buildinfo/dictionary'))
rel = buildinfo.get('relative_rpaths', False) rel = buildinfo.get('relative_rpaths', False)
if rel: if rel:
return return

View file

@ -10,7 +10,6 @@
import spack.repo import spack.repo
import spack.cmd import spack.cmd
import llnl.util.lang import llnl.util.lang
import llnl.util.filesystem as fs
from spack.util.executable import Executable, ProcessError from spack.util.executable import Executable, ProcessError
import llnl.util.tty as tty import llnl.util.tty as tty
@ -290,23 +289,15 @@ def modify_object_macholib(cur_path, old_dir, new_dir):
return return
try: try:
from macholib.MachO import MachO from macholib.MachO import MachO
from macholib.mach_o import LC_RPATH
except ImportError as e: except ImportError as e:
raise MissingMacholibException(e) raise MissingMacholibException(e)
def match_func(cpath): def match_func(cpath):
return str(cpath).replace(old_dir, new_dir) rpath = cpath.replace(old_dir, new_dir)
return rpath
dll = MachO(cur_path) dll = MachO(cur_path)
dll.rewriteLoadCommands(match_func) dll.rewriteLoadCommands(match_func)
for header in dll.headers:
for (idx, (lc, cmd, data)) in enumerate(header.commands):
if lc.cmd == LC_RPATH:
rpath = data
rpath = rpath.strip('\x00')
new_rpath = match_func(rpath)
header.rewriteDataForCommand(idx, new_rpath)
try: try:
f = open(dll.filename, 'rb+') f = open(dll.filename, 'rb+')
for header in dll.headers: for header in dll.headers:
@ -364,6 +355,26 @@ def needs_text_relocation(m_type, m_subtype):
return (m_type == "text") return (m_type == "text")
def replace_prefix_text(path_name, old_dir, new_dir):
"""
Replace old install prefix with new install prefix
in text files using utf-8 encoded strings.
"""
def replace(match):
return match.group().replace(old_dir.encode('utf-8'),
new_dir.encode('utf-8'))
with open(path_name, 'rb+') as f:
data = f.read()
f.seek(0)
pat = re.compile(old_dir.encode('utf-8'))
if not pat.search(data):
return
ndata = pat.sub(replace, data)
f.write(ndata)
f.truncate()
def replace_prefix_bin(path_name, old_dir, new_dir): def replace_prefix_bin(path_name, old_dir, new_dir):
""" """
Attempt to replace old install prefix with new install prefix Attempt to replace old install prefix with new install prefix
@ -372,23 +383,27 @@ def replace_prefix_bin(path_name, old_dir, new_dir):
""" """
def replace(match): def replace(match):
occurances = match.group().count(old_dir) occurances = match.group().count(old_dir.encode('utf-8'))
padding = (len(old_dir) - len(new_dir)) * occurances olen = len(old_dir.encode('utf-8'))
nlen = len(new_dir.encode('utf-8'))
padding = (olen - nlen) * occurances
if padding < 0: if padding < 0:
return data return data
return match.group().replace(old_dir, new_dir) + b'\0' * padding return match.group().replace(old_dir.encode('utf-8'),
new_dir.encode('utf-8')) + b'\0' * padding
with open(path_name, 'rb+') as f: with open(path_name, 'rb+') as f:
data = f.read() data = f.read()
f.seek(0) f.seek(0)
original_data_len = len(data) original_data_len = len(data)
pat = re.compile(re.escape(old_dir) + b'([^\0]*?)\0') pat = re.compile(old_dir.encode('utf-8') + b'([^\0]*?)\0')
if not pat.search(data):
return
ndata = pat.sub(replace, data) ndata = pat.sub(replace, data)
new_data_len = len(ndata) if not len(ndata) == original_data_len:
if not new_data_len == original_data_len:
raise BinaryStringReplacementException( raise BinaryStringReplacementException(
path_name, original_data_len, new_data_len) path_name, original_data_len, len(ndata))
f.write(data) f.write(ndata)
f.truncate() f.truncate()
@ -429,8 +444,8 @@ def relocate_macho_binaries(path_names, old_dir, new_dir, allow_root):
modify_object_macholib(path_name, placeholder, new_dir) modify_object_macholib(path_name, placeholder, new_dir)
modify_object_macholib(path_name, old_dir, new_dir) modify_object_macholib(path_name, old_dir, new_dir)
if len(new_dir) <= len(old_dir): if len(new_dir) <= len(old_dir):
replace_prefix_bin(path_name, old_dir.encode('utf-8'), replace_prefix_bin(path_name, old_dir,
new_dir.encode('utf-8')) new_dir)
else: else:
tty.warn('Cannot do a binary string replacement' tty.warn('Cannot do a binary string replacement'
' with padding for %s' ' with padding for %s'
@ -563,16 +578,15 @@ def relocate_links(path_names, old_dir, new_dir):
def relocate_text(path_names, oldpath, newpath, oldprefix, newprefix): def relocate_text(path_names, oldpath, newpath, oldprefix, newprefix):
""" """
Replace old path with new path in text file path_name Replace old path with new path in text files
including the path the the spack sbang script.
""" """
fs.filter_file('%s' % oldpath, '%s' % newpath, *path_names,
backup=False, string=True)
sbangre = '#!/bin/bash %s/bin/sbang' % oldprefix sbangre = '#!/bin/bash %s/bin/sbang' % oldprefix
sbangnew = '#!/bin/bash %s/bin/sbang' % newprefix sbangnew = '#!/bin/bash %s/bin/sbang' % newprefix
fs.filter_file(sbangre, sbangnew, *path_names, for path_name in path_names:
backup=False, string=True) replace_prefix_text(path_name, oldpath, newpath)
fs.filter_file(oldprefix, newprefix, *path_names, replace_prefix_text(path_name, sbangre, sbangnew)
backup=False, string=True) replace_prefix_text(path_name, oldprefix, newprefix)
def substitute_rpath(orig_rpath, topdir, new_root_path): def substitute_rpath(orig_rpath, topdir, new_root_path):