Skip to content

Commit

Permalink
Merge 84cfe37 into e70b5ff
Browse files Browse the repository at this point in the history
  • Loading branch information
wiredfool committed Apr 10, 2014
2 parents e70b5ff + 84cfe37 commit 76aa116
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 98 deletions.
159 changes: 94 additions & 65 deletions Tests/run.py
Expand Up @@ -3,6 +3,7 @@
# minimal test runner

import glob, os, os.path, sys, tempfile, re
from multiprocessing import Pool

try:
root = os.path.dirname(__file__)
Expand All @@ -14,42 +15,22 @@
print("***", "$ python Tests/run.py")
sys.exit(1)

print("-"*68)

python_options = []
tester_options = []

if "--installed" not in sys.argv:
os.environ["PYTHONPATH"] = "."

if "--coverage" in sys.argv:
tester_options.append("--coverage")

if "--log" in sys.argv:
tester_options.append("--log")

files = glob.glob(os.path.join(root, "test_*.py"))
files.sort()

success = failure = 0
include = [x for x in sys.argv[1:] if x[:2] != "--"]
skipped = []

python_options = " ".join(python_options)
tester_options = " ".join(tester_options)

ignore_re = re.compile('^ignore: (.*)$', re.MULTILINE)

for file in files:
test, ext = os.path.splitext(os.path.basename(file))
if include and test not in include:
continue
def test_one(f):
test, ext = os.path.splitext(os.path.basename(f))

print("running", test, "...")
# 2>&1 works on unix and on modern windowses. we might care about
# very old Python versions, but not ancient microsoft products :-)
out = os.popen("%s %s -u %s %s 2>&1" % (
sys.executable, python_options, file, tester_options
sys.executable, python_options, f, tester_options
))

result = out.read()

# Extract any ignore patterns
Expand All @@ -72,50 +53,98 @@ def fix_re(p):
for r in ignore_res:
result = r.sub('', result)

result = result.strip()

if result == "ok":
result = None
elif result == "skip":
print("---", "skipped") # FIXME: driver should include a reason
skipped.append(test)
continue
elif not result:
result = "(no output)"
result = result.strip()
status = out.close()
if status or result:
if status:
print("=== error", status)
if result:
if result[-3:] == "\nok":
# if there's an ok at the end, it's not really ok
result = result[:-3]
print(result)
failure = failure + 1
else:
success = success + 1

print("-"*68)
return (result, status)

temp_root = os.path.join(tempfile.gettempdir(), 'pillow-tests')
tempfiles = glob.glob(os.path.join(temp_root, "temp_*"))
if tempfiles:
print("===", "remaining temporary files")
for file in tempfiles:
print(file)
def filter_tests(files):
ret = []
for f in files:
test, ext = os.path.splitext(os.path.basename(f))
if include and test not in include:
continue
ret.append(f)
return ret

def main():
global python_options, tester_options

print("-"*68)

def tests(n):
if n == 1:
return "1 test"
if "--installed" not in sys.argv:
os.environ["PYTHONPATH"] = "."

if "--coverage" in sys.argv:
tester_options.append("--coverage")

if "--log" in sys.argv:
tester_options.append("--log")

files = glob.glob(os.path.join(root, "test_*.py"))
files.sort()

success = failure = 0
skipped = []

python_options = " ".join(python_options)
tester_options = " ".join(tester_options)


files = filter_tests(files)

pool = Pool()
results = pool.map(test_one, files)
pool.close()
pool.join()

for test,(result, status) in zip(files,results):
if result == "ok":
result = None
elif result == "skip":
print("---", "skipped") # FIXME: driver should include a reason
skipped.append(test)
continue
elif not result:
result = "(no output)"
if status or result:
if status:
print("=== error", status)
if result:
if result[-3:] == "\nok":
# if there's an ok at the end, it's not really ok
result = result[:-3]
print(result)
failure = failure + 1
else:
success = success + 1

print("-"*68)

temp_root = os.path.join(tempfile.gettempdir(), 'pillow-tests')
tempfiles = glob.glob(os.path.join(temp_root, "temp_*"))
if tempfiles:
print("===", "remaining temporary files")
for file in tempfiles:
print(file)
print("-"*68)

def tests(n):
if n == 1:
return "1 test"
else:
return "%d tests" % n

if skipped:
print("---", tests(len(skipped)), "skipped.")
print(skipped)
if failure:
print("***", tests(failure), "of", (success + failure), "failed.")
sys.exit(1)
else:
return "%d tests" % n
print(tests(success), "passed.")

if skipped:
print("---", tests(len(skipped)), "skipped.")
print(skipped)
if failure:
print("***", tests(failure), "of", (success + failure), "failed.")
sys.exit(1)
else:
print(tests(success), "passed.")
return 0

if __name__=='__main__':
sys.exit(main())
2 changes: 1 addition & 1 deletion Tests/tester.py
Expand Up @@ -241,7 +241,7 @@ def tempfile(template, *extra):
assert temp[:5] in ("temp.", "temp_")
name = os.path.basename(sys.argv[0])
name = temp[:4] + os.path.splitext(name)[0][4:]
name = name + "_%d" % len(_tempfiles) + temp[4:]
name = name + "_%d_%d" % (os.getpid(), len(_tempfiles)) + temp[4:]
name = os.path.join(root, name)
files.append(name)
_tempfiles.extend(files)
Expand Down
44 changes: 44 additions & 0 deletions mp_compile.py
@@ -0,0 +1,44 @@
# A monkey patch of the base distutils.ccompiler to use parallel builds
# Tested on 2.7, looks to be identical to 3.3.

from multiprocessing import Pool, cpu_count
from distutils.ccompiler import CCompiler

# hideous monkeypatching. but. but. but.
def _mp_compile_one(tp):
(self, obj, build, cc_args, extra_postargs, pp_opts) = tp
try:
src, ext = build[obj]
except KeyError:
return
self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)
return

def _mp_compile(self, sources, output_dir=None, macros=None,
include_dirs=None, debug=0, extra_preargs=None,
extra_postargs=None, depends=None):
"""Compile one or more source files.
see distutils.ccompiler.CCompiler.compile for comments.
"""
# A concrete compiler class can either override this method
# entirely or implement _compile().

macros, objects, extra_postargs, pp_opts, build = \
self._setup_compile(output_dir, macros, include_dirs, sources,
depends, extra_postargs)
cc_args = self._get_cc_args(pp_opts, debug, extra_preargs)

pool = Pool()
try:
print ("Building using %d processes" % pool._processes)
except: pass
arr = [(self, obj, build, cc_args, extra_postargs, pp_opts) for obj in objects]
results = pool.map_async(_mp_compile_one,arr)

pool.close()
pool.join()
# Return *all* object filenames, not just the ones we just built.
return objects

CCompiler.compile = _mp_compile
69 changes: 37 additions & 32 deletions setup.py
Expand Up @@ -14,6 +14,8 @@
import struct
import sys

import mp_compile

from distutils.command.build_ext import build_ext
from distutils import sysconfig
from setuptools import Extension, setup, find_packages
Expand Down Expand Up @@ -645,38 +647,41 @@ def add_multiarch_paths(self):
finally:
os.unlink(tmpfile)

setup(
name=NAME,
version=VERSION,
description='Python Imaging Library (Fork)',
long_description=(
# monkeypatch the compiler

if __name__=='__main__':
setup(
name=NAME,
version=VERSION,
description='Python Imaging Library (Fork)',
long_description=(
_read('README.rst') + b'\n' +
_read('CHANGES.rst')).decode('utf-8'),
author='Alex Clark (fork author)',
author_email='aclark@aclark.net',
url='http://python-imaging.github.io/',
classifiers=[
"Development Status :: 6 - Mature",
"Topic :: Multimedia :: Graphics",
"Topic :: Multimedia :: Graphics :: Capture :: Digital Camera",
"Topic :: Multimedia :: Graphics :: Capture :: Scanners",
"Topic :: Multimedia :: Graphics :: Capture :: Screen Capture",
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
"Topic :: Multimedia :: Graphics :: Viewers",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3", ],
cmdclass={"build_ext": pil_build_ext},
ext_modules=[Extension("PIL._imaging", ["_imaging.c"])],
include_package_data=True,
packages=find_packages(),
scripts=glob.glob("Scripts/pil*.py"),
test_suite='PIL.tests',
keywords=["Imaging",],
license='Standard PIL License',
zip_safe=True,
)
author='Alex Clark (fork author)',
author_email='aclark@aclark.net',
url='http://python-imaging.github.io/',
classifiers=[
"Development Status :: 6 - Mature",
"Topic :: Multimedia :: Graphics",
"Topic :: Multimedia :: Graphics :: Capture :: Digital Camera",
"Topic :: Multimedia :: Graphics :: Capture :: Scanners",
"Topic :: Multimedia :: Graphics :: Capture :: Screen Capture",
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
"Topic :: Multimedia :: Graphics :: Viewers",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3", ],
cmdclass={"build_ext": pil_build_ext},
ext_modules=[Extension("PIL._imaging", ["_imaging.c"])],
include_package_data=True,
packages=find_packages(),
scripts=glob.glob("Scripts/pil*.py"),
test_suite='PIL.tests',
keywords=["Imaging",],
license='Standard PIL License',
zip_safe=True,
)

0 comments on commit 76aa116

Please sign in to comment.