Commit c920def2 authored by Michael Droettboom's avatar Michael Droettboom Committed by GitHub

Merge pull request #101 from mdboom/use-pathlib

Use pathlib for path manipulations
parents ef8da067 fa23049e
import json import json
import os from pathlib import Path
import re import re
import subprocess import subprocess
import sys import sys
sys.path.insert(0, os.path.abspath( sys.path.insert(
os.path.join(os.path.dirname(__file__), '..', 'test'))) 0, str((Path(__file__).resolve().parents[1] / 'test')))
import conftest import conftest
...@@ -14,11 +15,12 @@ SKIP = set(['fft', 'hyantes']) ...@@ -14,11 +15,12 @@ SKIP = set(['fft', 'hyantes'])
def run_native(hostpython, code): def run_native(hostpython, code):
output = subprocess.check_output( output = subprocess.check_output(
[os.path.abspath(hostpython), '-c', code], [hostpython.resolve(), '-c', code],
cwd=os.path.dirname(__file__), cwd=Path(__file__).resolve().parent,
env={ env={
'PYTHONPATH': 'PYTHONPATH':
os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'src'))} str(Path(__file__).resolve().parents[1] / 'src')
}
) )
return float(output.strip().split()[-1]) return float(output.strip().split()[-1])
...@@ -72,12 +74,12 @@ def parse_numpy_benchmark(filename): ...@@ -72,12 +74,12 @@ def parse_numpy_benchmark(filename):
def get_numpy_benchmarks(): def get_numpy_benchmarks():
root = '../numpy-benchmarks/benchmarks' root = Path('../numpy-benchmarks/benchmarks')
for filename in os.listdir(root): for filename in root.iterdir():
name = os.path.splitext(filename)[0] name = filename.name
if name in SKIP: if name in SKIP:
continue continue
content = parse_numpy_benchmark(os.path.join(root, filename)) content = parse_numpy_benchmark(filename)
content += ( content += (
"import numpy as np\n" "import numpy as np\n"
"_ = np.empty(())\n" "_ = np.empty(())\n"
...@@ -103,6 +105,6 @@ def main(hostpython): ...@@ -103,6 +105,6 @@ def main(hostpython):
if __name__ == '__main__': if __name__ == '__main__':
results = main(sys.argv[-2]) results = main(Path(sys.argv[-2]).resolve())
with open(sys.argv[-1], 'w') as fp: with open(sys.argv[-1], 'w') as fp:
json.dump(results, fp) json.dump(results, fp)
...@@ -3,21 +3,24 @@ Generate a list of test modules in the CPython distribution. ...@@ -3,21 +3,24 @@ Generate a list of test modules in the CPython distribution.
""" """
import os import os
from pathlib import Path
tests = [] tests = []
TEST_DIR = "../cpython/build/3.6.4/host/lib/python3.6/test" TEST_DIR = Path("../cpython/build/3.6.4/host/lib/python3.6/test")
for root, dirs, files in os.walk( for root, dirs, files in os.walk(
"../cpython/build/3.6.4/host/lib/python3.6/test"): "../cpython/build/3.6.4/host/lib/python3.6/test"):
root = os.path.relpath(root, TEST_DIR) root = Path(root).relative_to(TEST_DIR)
if root == '.': if root == '.':
root = '' root = ''
else: else:
root = '.'.join(root.split('/')) + '.' root = '.'.join(root.split('/')) + '.'
for filename in files: for filename in files:
if filename.startswith("test_") and filename.endswith(".py"): filename = Path(filename)
tests.append(root + os.path.splitext(filename)[0]) if str(filename).startswith("test_") and filename.suffix == ".py":
tests.append(str(root / filename.stem))
tests.sort() tests.sort()
with open("python_tests.txt", "w") as fp: with open("python_tests.txt", "w") as fp:
......
import os import os
import pathlib from pathlib import Path
import time import time
...@@ -295,8 +295,7 @@ def pytest_generate_tests(metafunc): ...@@ -295,8 +295,7 @@ def pytest_generate_tests(metafunc):
test_modules = [] test_modules = []
if 'CIRCLECI' not in os.environ or True: if 'CIRCLECI' not in os.environ or True:
with open( with open(
str(pathlib.Path(__file__).parents[0] / Path(__file__).parent / "python_tests.txt") as fp:
"python_tests.txt")) as fp:
for line in fp: for line in fp:
line = line.strip() line = line.strip()
if line.startswith('#'): if line.startswith('#'):
......
...@@ -6,7 +6,7 @@ Build all of the packages in a given directory. ...@@ -6,7 +6,7 @@ Build all of the packages in a given directory.
import argparse import argparse
import json import json
import os from pathlib import Path
import shutil import shutil
...@@ -14,42 +14,39 @@ import common ...@@ -14,42 +14,39 @@ import common
import buildpkg import buildpkg
def build_package(pkgname, dependencies, packagesdir, args): def build_package(pkgname, dependencies, packagesdir, outputdir, args):
reqs = dependencies[pkgname] reqs = dependencies[pkgname]
# Make sure all of the package's requirements are built first # Make sure all of the package's requirements are built first
for req in reqs: for req in reqs:
build_package(req, dependencies, packagesdir, args) build_package(req, dependencies, packagesdir, outputdir, args)
if not os.path.isfile( if not (packagesdir / pkgname / 'build' / '.packaged').is_file():
os.path.join(packagesdir, pkgname, 'build', '.packaged')):
print("BUILDING PACKAGE: " + pkgname) print("BUILDING PACKAGE: " + pkgname)
buildpkg.build_package( buildpkg.build_package(packagesdir / pkgname / 'meta.yaml', args)
os.path.join(packagesdir, pkgname, 'meta.yaml'), args)
shutil.copyfile( shutil.copyfile(
os.path.join(packagesdir, pkgname, 'build', pkgname + '.data'), packagesdir / pkgname / 'build' / (pkgname + '.data'),
os.path.join(args.output[0], pkgname + '.data')) outputdir / (pkgname + '.data'))
shutil.copyfile( shutil.copyfile(
os.path.join(packagesdir, pkgname, 'build', pkgname + '.js'), packagesdir / pkgname / 'build' / (pkgname + '.js'),
os.path.join(args.output[0], pkgname + '.js')) outputdir / (pkgname + '.js'))
def build_packages(packagesdir, args): def build_packages(packagesdir, outputdir, args):
# We have to build the packages in the correct order (dependencies first), # We have to build the packages in the correct order (dependencies first),
# so first load in all of the package metadata and build a dependency map. # so first load in all of the package metadata and build a dependency map.
dependencies = {} dependencies = {}
for pkgdir in os.listdir(packagesdir): for pkgdir in packagesdir.iterdir():
pkgdir = os.path.join(packagesdir, pkgdir) pkgpath = pkgdir / 'meta.yaml'
pkgpath = os.path.join(pkgdir, 'meta.yaml') if pkgdir.is_dir() and pkgpath.is_file():
if os.path.isdir(pkgdir) and os.path.isfile(pkgpath):
pkg = common.parse_package(pkgpath) pkg = common.parse_package(pkgpath)
name = pkg['package']['name'] name = pkg['package']['name']
reqs = pkg.get('requirements', {}).get('run', []) reqs = pkg.get('requirements', {}).get('run', [])
dependencies[name] = reqs dependencies[name] = reqs
for pkgname in dependencies.keys(): for pkgname in dependencies.keys():
build_package(pkgname, dependencies, packagesdir, args) build_package(pkgname, dependencies, packagesdir, outputdir, args)
# This is done last so the main Makefile can use it as a completion token # This is done last so the main Makefile can use it as a completion token
with open(os.path.join(args.output[0], 'packages.json'), 'w') as fd: with open(outputdir / 'packages.json', 'w') as fd:
json.dump({'dependencies': dependencies}, fd) json.dump({'dependencies': dependencies}, fd)
...@@ -78,8 +75,9 @@ def parse_args(): ...@@ -78,8 +75,9 @@ def parse_args():
def main(args): def main(args):
packagesdir = os.path.abspath(args.dir[0]) packagesdir = Path(args.dir[0]).resolve()
build_packages(packagesdir, args) outputdir = Path(args.output[0]).resolve()
build_packages(packagesdir, outputdir, args)
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -7,6 +7,7 @@ Builds a Pyodide package. ...@@ -7,6 +7,7 @@ Builds a Pyodide package.
import argparse import argparse
import hashlib import hashlib
import os import os
from pathlib import Path
import shutil import shutil
import subprocess import subprocess
...@@ -14,7 +15,7 @@ import subprocess ...@@ -14,7 +15,7 @@ import subprocess
import common import common
ROOTDIR = os.path.abspath(os.path.dirname(__file__)) ROOTDIR = Path(__file__).parent.resolve()
def check_checksum(path, pkg): def check_checksum(path, pkg):
...@@ -37,40 +38,39 @@ def check_checksum(path, pkg): ...@@ -37,40 +38,39 @@ def check_checksum(path, pkg):
def download_and_extract(buildpath, packagedir, pkg, args): def download_and_extract(buildpath, packagedir, pkg, args):
tarballpath = os.path.join( tarballpath = buildpath / Path(pkg['source']['url']).name
buildpath, os.path.basename(pkg['source']['url'])) if not tarballpath.is_file():
if not os.path.isfile(tarballpath):
subprocess.run([ subprocess.run([
'wget', '-q', '-O', tarballpath, pkg['source']['url'] 'wget', '-q', '-O', str(tarballpath), pkg['source']['url']
], check=True) ], check=True)
check_checksum(tarballpath, pkg) check_checksum(tarballpath, pkg)
srcpath = os.path.join(buildpath, packagedir) srcpath = buildpath / packagedir
if not os.path.isdir(srcpath): if not srcpath.is_dir():
shutil.unpack_archive(tarballpath, buildpath) shutil.unpack_archive(str(tarballpath), str(buildpath))
return srcpath return srcpath
def patch(path, srcpath, pkg, args): def patch(path, srcpath, pkg, args):
if os.path.isfile(os.path.join(srcpath, '.patched')): if (srcpath / '.patched').is_file():
return return
# Apply all of the patches # Apply all of the patches
orig_dir = os.getcwd() orig_dir = Path.cwd()
pkgdir = os.path.abspath(os.path.dirname(path)) pkgdir = path.parent.resolve()
os.chdir(srcpath) os.chdir(srcpath)
try: try:
for patch in pkg['source'].get('patches', []): for patch in pkg['source'].get('patches', []):
subprocess.run([ subprocess.run([
'patch', '-p1', '--binary', '-i', os.path.join(pkgdir, patch) 'patch', '-p1', '--binary', '-i', pkgdir / patch
], check=True) ], check=True)
finally: finally:
os.chdir(orig_dir) os.chdir(orig_dir)
# Add any extra files # Add any extra files
for src, dst in pkg['source'].get('extras', []): for src, dst in pkg['source'].get('extras', []):
shutil.copyfile(os.path.join(pkgdir, src), os.path.join(srcpath, dst)) shutil.copyfile(pkgdir / src, srcpath / dst)
with open(os.path.join(srcpath, '.patched'), 'wb') as fd: with open(srcpath / '.patched', 'wb') as fd:
fd.write(b'\n') fd.write(b'\n')
...@@ -78,31 +78,31 @@ def get_libdir(srcpath, args): ...@@ -78,31 +78,31 @@ def get_libdir(srcpath, args):
# Get the name of the build/lib.XXX directory that distutils wrote its # Get the name of the build/lib.XXX directory that distutils wrote its
# output to # output to
slug = subprocess.check_output([ slug = subprocess.check_output([
os.path.join(args.host, 'bin', 'python3'), str(Path(args.host) / 'bin' / 'python3'),
'-c', '-c',
'import sysconfig, sys; ' 'import sysconfig, sys; '
'print("{}-{}.{}".format(' 'print("{}-{}.{}".format('
'sysconfig.get_platform(), ' 'sysconfig.get_platform(), '
'sys.version_info[0], ' 'sys.version_info[0], '
'sys.version_info[1]))']).decode('ascii').strip() 'sys.version_info[1]))']).decode('ascii').strip()
purelib = os.path.join(srcpath, 'build', 'lib') purelib = srcpath / 'build' / 'lib'
if os.path.isdir(purelib): if purelib.is_dir():
libdir = purelib libdir = purelib
else: else:
libdir = os.path.join(srcpath, 'build', 'lib.' + slug) libdir = srcpath / 'build' / ('lib.' + slug)
return libdir return libdir
def compile(path, srcpath, pkg, args): def compile(path, srcpath, pkg, args):
if os.path.isfile(os.path.join(srcpath, '.built')): if (srcpath / '.built').is_file():
return return
orig_dir = os.getcwd() orig_dir = Path.cwd()
os.chdir(srcpath) os.chdir(srcpath)
try: try:
subprocess.run([ subprocess.run([
os.path.join(args.host, 'bin', 'python3'), str(Path(args.host) / 'bin' / 'python3'),
os.path.join(ROOTDIR, 'pywasmcross'), str(ROOTDIR / 'pywasmcross'),
'--cflags', '--cflags',
args.cflags + ' ' + args.cflags + ' ' +
pkg.get('build', {}).get('cflags', ''), pkg.get('build', {}).get('cflags', ''),
...@@ -117,7 +117,7 @@ def compile(path, srcpath, pkg, args): ...@@ -117,7 +117,7 @@ def compile(path, srcpath, pkg, args):
post = pkg.get('build', {}).get('post') post = pkg.get('build', {}).get('post')
if post is not None: if post is not None:
libdir = get_libdir(srcpath, args) libdir = get_libdir(srcpath, args)
pkgdir = os.path.abspath(os.path.dirname(path)) pkgdir = path.parent.resolve()
env = { env = {
'BUILD': libdir, 'BUILD': libdir,
'PKGDIR': pkgdir 'PKGDIR': pkgdir
...@@ -125,46 +125,46 @@ def compile(path, srcpath, pkg, args): ...@@ -125,46 +125,46 @@ def compile(path, srcpath, pkg, args):
subprocess.run([ subprocess.run([
'bash', '-c', post], env=env, check=True) 'bash', '-c', post], env=env, check=True)
with open(os.path.join(srcpath, '.built'), 'wb') as fd: with open(srcpath / '.built', 'wb') as fd:
fd.write(b'\n') fd.write(b'\n')
def package_files(buildpath, srcpath, pkg, args): def package_files(buildpath, srcpath, pkg, args):
if os.path.isfile(os.path.join(buildpath, '.packaged')): if (buildpath / '.pacakaged').is_file():
return return
name = pkg['package']['name'] name = pkg['package']['name']
libdir = get_libdir(srcpath, args) libdir = get_libdir(srcpath, args)
subprocess.run([ subprocess.run([
'python2', 'python2',
os.path.join(os.environ['EMSCRIPTEN'], 'tools', 'file_packager.py'), Path(os.environ['EMSCRIPTEN']) / 'tools' / 'file_packager.py',
os.path.join(buildpath, name + '.data'), buildpath / (name + '.data'),
'--preload', '--preload',
'{}@/lib/python3.6/site-packages'.format(libdir), '{}@/lib/python3.6/site-packages'.format(libdir),
'--js-output={}'.format(os.path.join(buildpath, name + '.js')), '--js-output={}'.format(buildpath / (name + '.js')),
'--export-name=pyodide', '--export-name=pyodide',
'--exclude', '*.wasm.pre', '--exclude', '*.wasm.pre',
'--exclude', '__pycache__', '--exclude', '__pycache__',
'--use-preload-plugins'], check=True) '--use-preload-plugins'], check=True)
subprocess.run([ subprocess.run([
'uglifyjs', 'uglifyjs',
os.path.join(buildpath, name + '.js'), buildpath / (name + '.js'),
'-o', '-o',
os.path.join(buildpath, name + '.js')], check=True) buildpath / (name + '.js')], check=True)
with open(os.path.join(buildpath, '.packaged'), 'wb') as fd: with open(buildpath / '.packaged', 'wb') as fd:
fd.write(b'\n') fd.write(b'\n')
def build_package(path, args): def build_package(path, args):
pkg = common.parse_package(path) pkg = common.parse_package(path)
packagedir = pkg['package']['name'] + '-' + pkg['package']['version'] packagedir = pkg['package']['name'] + '-' + pkg['package']['version']
dirpath = os.path.dirname(path) dirpath = path.parent
orig_path = os.getcwd() orig_path = Path.cwd()
os.chdir(dirpath) os.chdir(dirpath)
try: try:
buildpath = os.path.join(dirpath, 'build') buildpath = dirpath / 'build'
if not os.path.exists(buildpath): if not buildpath.is_dir():
os.makedirs(buildpath) os.makedirs(buildpath)
srcpath = download_and_extract(buildpath, packagedir, pkg, args) srcpath = download_and_extract(buildpath, packagedir, pkg, args)
patch(path, srcpath, pkg, args) patch(path, srcpath, pkg, args)
...@@ -195,7 +195,7 @@ def parse_args(): ...@@ -195,7 +195,7 @@ def parse_args():
def main(args): def main(args):
path = os.path.abspath(args.package[0]) path = Path(args.package[0]).resolve()
build_package(path, args) build_package(path, args)
......
import os from pathlib import Path
ROOTDIR = os.path.abspath(os.path.dirname(__file__)) ROOTDIR = Path(__file__).parent.resolve()
HOSTPYTHON = os.path.abspath( HOSTPYTHON = ROOTDIR / '..' / 'cpython' / 'build' / '3.6.4' / 'host'
os.path.join(ROOTDIR, '..', 'cpython', 'build', '3.6.4', 'host')) TARGETPYTHON = ROOTDIR / '..' / 'cpython' / 'installs' / 'python-3.6.4'
TARGETPYTHON = os.path.abspath(
os.path.join(ROOTDIR, '..', 'cpython', 'installs', 'python-3.6.4'))
DEFAULTCFLAGS = '' DEFAULTCFLAGS = ''
DEFAULTLDFLAGS = ' '.join([ DEFAULTLDFLAGS = ' '.join([
'-O3', '-O3',
......
...@@ -28,6 +28,7 @@ import argparse ...@@ -28,6 +28,7 @@ import argparse
import importlib.machinery import importlib.machinery
import json import json
import os import os
from pathlib import Path
import re import re
import subprocess import subprocess
import sys import sys
...@@ -36,7 +37,7 @@ import sys ...@@ -36,7 +37,7 @@ import sys
import common import common
ROOTDIR = os.path.abspath(os.path.dirname(__file__)) ROOTDIR = Path(__file__).parent.resolve()
symlinks = set(['cc', 'c++', 'ld', 'ar', 'gcc']) symlinks = set(['cc', 'c++', 'ld', 'ar', 'gcc'])
...@@ -52,8 +53,8 @@ def collect_args(basename): ...@@ -52,8 +53,8 @@ def collect_args(basename):
# native compiler # native compiler
env = dict(os.environ) env = dict(os.environ)
path = env['PATH'] path = env['PATH']
while ROOTDIR + ':' in path: while str(ROOTDIR) + ':' in path:
path = path.replace(ROOTDIR + ':', '') path = path.replace(str(ROOTDIR) + ':', '')
env['PATH'] = path env['PATH'] = path
with open('build.log', 'a') as fd: with open('build.log', 'a') as fd:
...@@ -71,11 +72,11 @@ def make_symlinks(env): ...@@ -71,11 +72,11 @@ def make_symlinks(env):
Makes sure all of the symlinks that make this script look like a compiler Makes sure all of the symlinks that make this script look like a compiler
exist. exist.
""" """
exec_path = os.path.abspath(__file__) exec_path = Path(__file__).resolve()
for symlink in symlinks: for symlink in symlinks:
symlink_path = os.path.join(ROOTDIR, symlink) symlink_path = ROOTDIR / symlink
if not os.path.exists(symlink_path): if not symlink_path.exists():
os.symlink(exec_path, symlink_path) symlink_path.symlink_to(exec_path)
if symlink == 'c++': if symlink == 'c++':
var = 'CXX' var = 'CXX'
else: else:
...@@ -86,15 +87,16 @@ def make_symlinks(env): ...@@ -86,15 +87,16 @@ def make_symlinks(env):
def capture_compile(args): def capture_compile(args):
env = dict(os.environ) env = dict(os.environ)
make_symlinks(env) make_symlinks(env)
env['PATH'] = ROOTDIR + ':' + os.environ['PATH'] env['PATH'] = str(ROOTDIR) + ':' + os.environ['PATH']
result = subprocess.run( result = subprocess.run(
[os.path.join(args.host, 'bin', 'python3'), [Path(args.host) / 'bin' / 'python3',
'setup.py', 'setup.py',
'install'], env=env) 'install'], env=env)
if result.returncode != 0: if result.returncode != 0:
if os.path.exists('build.log'): build_log_path = Path('build.log')
os.remove('build.log') if build_log_path.exists():
build_log_path.unlink()
sys.exit(result.returncode) sys.exit(result.returncode)
...@@ -131,7 +133,7 @@ def handle_command(line, args): ...@@ -131,7 +133,7 @@ def handle_command(line, args):
# Don't include any system directories # Don't include any system directories
if arg[2:].startswith('/usr'): if arg[2:].startswith('/usr'):
continue continue
if (os.path.abspath(arg[2:]).startswith(args.host) and if (str(Path(arg[2:]).resolve()).startswith(args.host) and
'site-packages' not in arg): 'site-packages' not in arg):
arg = arg.replace('-I' + args.host, '-I' + args.target) arg = arg.replace('-I' + args.host, '-I' + args.target)
# Don't include any system directories # Don't include any system directories
...@@ -168,8 +170,9 @@ def handle_command(line, args): ...@@ -168,8 +170,9 @@ def handle_command(line, args):
def replay_compile(args): def replay_compile(args):
# If pure Python, there will be no build.log file, which is fine -- just do # If pure Python, there will be no build.log file, which is fine -- just do
# nothing # nothing
if os.path.isfile('build.log'): build_log_path = Path('build.log')
with open('build.log', 'r') as fd: if build_log_path.is_file():
with open(build_log_path, 'r') as fd:
for line in fd: for line in fd:
line = json.loads(line) line = json.loads(line)
handle_command(line, args) handle_command(line, args)
...@@ -178,14 +181,14 @@ def replay_compile(args): ...@@ -178,14 +181,14 @@ def replay_compile(args):
def clean_out_native_artifacts(): def clean_out_native_artifacts():
for root, dirs, files in os.walk('.'): for root, dirs, files in os.walk('.'):
for file in files: for file in files:
path = os.path.join(root, file) path = Path(root) / file
basename, ext = os.path.splitext(file) if path.suffix in ('.o', '.so', '.a'):
if ext in ('.o', '.so', '.a'): path.unlink()
os.remove(path)
def build_wrap(args): def build_wrap(args):
if not os.path.isfile('build.log'): build_log_path = Path('build.log')
if not build_log_path.is_file():
capture_compile(args) capture_compile(args)
clean_out_native_artifacts() clean_out_native_artifacts()
replay_compile(args) replay_compile(args)
...@@ -212,7 +215,7 @@ def parse_args(): ...@@ -212,7 +215,7 @@ def parse_args():
if __name__ == '__main__': if __name__ == '__main__':
basename = os.path.basename(sys.argv[0]) basename = Path(sys.argv[0]).name
if basename in symlinks: if basename in symlinks:
collect_args(basename) collect_args(basename)
else: else:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment